下面是一些经常遇到的断言(注意,其中提到的行号都是VC++5.0中的)
FreeMemoryDedug()
在AFXMEM.CPP的第67行。这个断言的起因可能是用错误的操作符释放内存--例如:用delete释放由malloc()分配的内存。也可能是没有用
CObject类的delete方法而用全局的释放操作符。还有其他的原因,包括视图释放一个在框架(栈)上创建的对象或是先前的内存故障。
CWnd::Attach()
这个断言在WINCORE.CPP的第314行
ASSERT(m_hWnd==NULL) //only attach ance,detach on destroy
这个断言通常可能是由于试图把一个已经捆绑(attach)过的窗口捆绑在其他的对象上,只能有一个MFC对象能够捆绑到一个窗口上--不然,消
息映射就会不正常
CWnd::Create()
这个断言在WINCORE.CPP的708行
ASSERT((dwStyle&WS_POPUP)==0)
起因是由于使用Create()函数时试图赋予WS_POPUP风格没,但是不支持的,想要这种风格应该用CreateEx()函数
CWnd::DestroyWindow()
ASSERT(pMap!=NULL)
这个断言在WINCORE.CPP的930行,起因时在消息映射还没有激活的时候就关闭或是析构窗口,要窒息检查InitInstance()函数
CWnd::PreCreateWindow()
ASSERT(cd.style&WS_CHILD)
这个断言在WINCORE.CPP的第694行,原因时使用了WS_CHILD风格,对于没有子窗口,最好用CFrameWnd而不要用CWnd
CBitmap::DrawItem()
ASSERT(m_bitmap.m_nObject!=NULL)
这个断言在WINBTN.CPP的117行,原因时在位图未加载前试图画一个位图按钮而引起程出问题。对于对话框,这种情况子OnInitDialog()函数中
就能轻易解决,如下面例子:
BOOL CSomeDlg::OnInitDialog()
{
m_Ok.AutoLoad(IDOK,this);
m_Cancel.AutoLoad(IDCANCEL,this);
m_Help.AutoLoad(IDHELPBUTTON,this);
.................
}
ClistBox::DrawItem(),ClistBox::MeasureItem(),和ClistBox::CompareItem()
这三个断言在同一个地方出现,而且几乎是由于相同的原因,他们在WINCRTL1.CPP的105行,是关于owner-draw风格列表框的,当这些断言出现的时候,你要记住重载这些消息处理函数
Cobject::IsKindof()
ASSERT(this!=NULL)
这个断言在OBJCORE.CPP的第43行,一旦IsKindof()被为一个无效的由CWnd派生的对象而调用,就会产生这个断言。它说明对象没有初始化过(比如NULL指针),或是内存先前出了故障。
void AFXAPI DDX_Control()
ASSERT(!pDX->m_bSaveAndValidate)
这个断言在DLGDATA.CPP的第575行。调用UpdateData()或是UpdateData(TRUE)之前至少要调用一次UpdateData(FALSE),否则就会出现这个断言
PrepareCtrl(int nIDC)
在DLGDATA.cpp的下面这个函数中由一个关于控件的断言
全部细节是:
HWND hWndCrtl;
m_pDlgWnd->GetDlgItem(nIDC,&hWndCtrl);
if(hWndCtrl==NULL)
{
TRACE("Error:no data exchange control with ID0x%04X./n",nIDC);
ASSERT(FALSE);
AfxThrowNotSupportedException();
}
通常的原因是释放了一个同数据交换变量关联的控件
void AFXAPI DDX_Radio()
这个方法在DLGDATA.CPP中,和单选按钮有关。其中有如下的断言
ASSERT(::GetWindowLong(hWndCtrl,GWL_STYLE)&WSGROUP);
ASSERT(value==1); //only set once
如果这个调用针对的对象不是一个组中的第一个单选按钮,或者对组中任何一个按钮调用了不止一次,就会引起这个断言。只是第一个按钮可以有WS_GROUP窗口风格。用Class Wnzard时,如何想要把组中的第一个按钮外的其他按钮与一个成员变量关联,唯一的方法时先给这个按钮设置WS_GROUP风格,然后关联变量,最后再去掉WS_GROUP风格。如果忘记去掉WS_GROUP,就会出现断言。
CEditView::PageInateTo()
ASSERT(nPageSzve>1)
这个断言在模块VIEWEDIT.CPP中,通常始由于重载窗口的OnprepareDC()函数时没有首先调用基类的OnprepareDC()引起的,最好OnpreparePrinting()或是OnBeginPrinting()中设置要打印的页数
AFXAPI AfxMessageBox()
这个断言在APPUI.CPP中的如下代码中:
if(!string.LoadString(nIDPrompt))
{
TRACE("Error:failed to load message box prompt string 0x%04X./n",nIDprompt);
ASSERT(FALSE);
}
这里的问题可能是由两种原因引起的:
1.字符串资源不存在
2.没有正确地引用资源(比如说错误地号码,等等)
CDC::SelectObject()
对于每种类型地对象(pen,brush等)都有类似地断言。这些断言地一般形式是:
ASSERT(m_nDC!=NULL)
如何试图没有先调用GetDC(),CreateDC()或是Attach()就使用对象,便会引起这个断言。这个断言本质上是说不存在一个设备上下文.
CGdiObject::FromHandle()
WINGDI.CPP中这个方法包含地断言为:
ASSERT(pObject==NULL || pObject->m_hObject==h)
试图没有释放前一个对象就创建对象,便会引起这个断言---例如,调用了CreateFontIndirect()两次,但在中间没有调用DeleteObject()
CGdiObject::Attach()
这个方法在WINGDI.CPP中紧跟FromHandle()方法之后。断言宏为:
ASSERT(m_hObject == NULL)
这个断言地起因是把绘图对象(pen,brush对象)选入了设备上下文但是没有选出[用SelectObject()函数]
CScrollView::SetScrollSize()
ASSERT(sizeTotal.cx>=0 && sizeTotal.cy>=0)
这个断言在VIEWSCRL.CPP中,多数出现在使用CFromView和CScrollView的时候,起因是不正确地初始化滚动尺寸,或者忘记传递第二个参数
CStidoFile::Open()
这个位于FILETXT.CPP的方法中充满了断言。这些断言捕获比如没有文件名,或者文件名没有以NULL结尾等情况
CMenu::Attach(HMENU())
这个方法在WINMENU.CPP中,其中的断言是
ASSERT(m_hMenu == NULL)
这个断言失败的原因是由于调用了两次LoadMenu(),而中间没有调用DestroyMenu()