INFO: Foundation Classes Common Asserts, Causes, and Solutions
ID: Q117326
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), included with:
-
Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5
-
Microsoft Visual C++, 32-bit Editions, version 1.0
SUMMARY
This article presents a list of over 50 common Microsoft Foundation
Class (MFC) assertions [ASSERT() statements in the Foundation class source
code] that programmers using Visual C++ may commonly come across. The
current version of this text is primarily for Visual C++ 1.0 and 1.5.
It lists some of the most likely causes, and possible solutions, for
each assertion.
In Visual C++ 2.0, a help file entitled "Knowledge Base" can be installed
in the Visual C++ program group. The help file has a section titled "MFC
3.0 Common Asserts".
MORE INFORMATION
While writing and debugging a Microsoft Foundation Classes program,
you may often receive an "Assertion Failed" message indicating
something has gone wrong in your application. There are many
techniques you can use to track down the possible cause of the
assertion.
- The most important bit of information to get when the assertion is
hit is the file and line number of the assertion! This will allow
you to go to the Foundation class source code which caused the
assertion and see what was happening.
The source code for the Microsoft Foundation Classes is under your
Visual C++ (or C/C++ 7.0) directory in MFC\SRC. Headers and .INL
files are in MFC\INCLUDE. Reading this source code when you get
an assertion is often the best way to figure out what is happening
and to solve your problem.
- If you are unfamiliar with how ASSERT(),ASSERT_VALID(), AssertValid(),
AfxIsValidAddress(), and TRACE() work, you will want to read the
on-line help on these macros and functions. These are also described
in the Visual C++ 1.5 "Class Library User's Guide" chapter 15,
Diagnostics. Remember to run the DebugWin utility to display your
applications TRACE messages. Debugging output will display in the
DebugWin window. You may need to run the "MFC Trace Options" utility,
AFX Tracer, to enable tracing.
- When you hit an assertion, you will usually want to figure out where
in your own code the call was made which eventually resulted in the
assertion. If running under a debugger, you can choose "Retry" when
the assertion comes up. This will hit a hard-coded breakpoint which
puts you into the debugger. From there you can examine the call-stack.
In Visual C++ this can be done by pressing Ctrl+K or choosing to examine
the call-stack from the Debug menu. You can also set a breakpoint on
the opening curly bracket of AfxAssertFailedLine() in AFXASERT.CPP in
your Visual C++ MFC\SRC directory. Knowledge Base article Q108112,
"How to View the Call Stack After an MFC ASSERT" describes this
in more detail.
- If you need to track down threads of execution, or which functions
access what variables, you will probably want to build a browser
library for the Foundation Class libraries. This is described in
Knowledge Base article Q98656, "Using Class Library Browser
Information in Your Project."
- General Debugging:
Many assertions you will hit are caused by memory corruption or
invalid parameters passed to Windows API functions. Using MFC
diagnostics techniques and the debugging versions of Windows 3.1
along with the DebugWin utility can help greatly in tracking
down such errors.
Basic MFC debugging techniques are discussed in the Visual C++
1.5 "Class Library User's Guide" chapter 15, Diagnostics. The
most important technique is to use the DEBUG_NEW macro described
there and to set the global afxMemDF variable to always check
validity of memory blocks allocated with new. To do so, just
add the following code to your InitInstance()
#ifdef _DEBUG
afxMemDF |= checkAlwaysMemDF;
#endif
There are two very good articles on using MFC diagnostics for
debugging in the Microsoft System Journal. The articles are
"Built-in Diagnostic Facilities in the Microsoft Foundation
Classes Simplify Debugging" and "MFC Diagnostic Facilities
Part II: More-Sophisticated Debugging Techniques" in MSJ
Volume 8 #2 and #3 (February 1993 and March 1993). These
articles can also be found on the MSDN CD.
Using the debugging version of Windows 3.1 will also allow you
to catch many errors that later cause assertions. The debugging
version of Windows does much stricter error checking and
validation than the retail version and can catch many errors
you might otherwise miss. The debugging version of Windows comes
with Visual C++, but is not installed by default. You can
install it by running setup, checking only the "Tools" checkbox,
and changing the tools to be installed to include only the
debugging version of Windows. Use the N2D.BAT file to change
to the debugging version and the D2N.BAT to change back (without
Windows running, of course). The DebugWin utilities Options,
Settings allows you to change settings for the debugging version
of Windows. Suggested options to set would be "Validate Heap"
which validates internal local heap data structures, "Check
Free Blocks" which verifies that local free memory isn't written
into invalidly, and "Fill Buffers" which helps detect overwrite
problems with buffers passed to some API functions.
You may want to add the lines
[debug]
OutputTo=NUL
to your SYSTEM.INI file so that no debugging output is sent until you
have DebugWin (or some debugger) running. This can avoid problems with
Windows starting up and needing to output error messages, which can
cause applications to run slowly. For more information on the debugging
version of Windows see Appendix C of the Windows SDK "Programming Tools"
manual. The Win31 Help helpfile (in your Visual C++ program group) also
has information on this under Overviews, Windows Debugging Version.
Format of Assertions List:
For each of the following assertions, the following information is
listed:
- File and line number of the assertion.
- Version of C/C++ or Visual C++ the assertion occurs in.
- Foundation class function the assertion occurs in.
- The actual code of the ASSERT() statement, if useful.
- Possible causes of the assertion.
- Possible solutions which will avoid the assertion.
These assertions are listed from most common to less common. Where
there is more than one common assertion in a single source file, all
assertions for that file are listed together, again from most to less
common.
Assertions List
AFXMEM.CPP Line 363 - Visual C++ 1.5
AFXMEM.CPP Line 358 - Visual C++ 1.0
MEMORY.CPP Line 334 - C/C++ 7.0
FreeMemoryDebug()
This assert can be caused by freeing an incorrect memory type.
For example, using delete on memory allocated with malloc(),
or using the global delete operator on a CObject class instead
of CObject::delete.
This assert can also be caused by attempting to delete an object
created on the frame (stack). For example, deleting a local
variable inside a function. It has often been caused by
previously corrupted memory.
----------
AFXMEM.CPP Line 383 - Visual C++ 1.5
AFXMEM.CPP Line 378 - Visual C++ 1.0
FreeMemoryDebug()
This assert can be caused by calling new to allocate an object
in one _USRDLL and using delete to deallocate the object in a
different _USRDLL. Use _AFXDLL instead if this is needed.
----------
VBCTRL.CPP Line 298 - Visual C++ 1.0 and 1.5
CVBControl::Trace()
Fatal errors for CVBControls cause this assert after using TRACE
to output an error message.
The message before this is very often "Invalid Control Object".
Accessing a VBX control before it is valid or created can cause
this error. Make sure that your VBX control has been created
before using it.
For a CDialog derived class this means after the dialogs
WM_INITDIALOG handler has been hit. You can access the VBX
control in your OnInitDialog() handler, but only after calling
CDialog::OnInitDialog().
For a CFormView derived class, the VBX control should not be accessed
until after OnInitialUpdate() has been called. If overriding
OnInitialUpdate(), make sure to call CFormView::OnInitialUpdate()
first.
----------
WINCORE.CPP Line 181 - Visual C++ 1.5
WINCORE.CPP Line 132 - Visual C++ 1.0
CWnd::Attach()
ASSERT(m_hWnd == NULL); // only attach once, detach on destroy
This assert will be caused by attempting to use the same CWnd object
to subclass another window (the same other window) twice.
A CWnd must not already be associated with a window if it
is going to attach to a new window.
----------
WINCORE.CPP Line 182 - Visual C++ 1.5
WINCORE.CPP Line 133 - Visual C++ 1.0
CWnd::Attach(HWND hWndNew)
ASSERT(FromHandlePermanent(hWndNew) == NULL);
// must not already be in permanent map
This assert is caused if the window a CWnd is trying to
attach to is already attached to some other MFC object.
You can only have one MFC object attached to any window,
otherwise the message maps cannot function correctly.
----------
WINCORE.CPP Line 574 - Visual C++ 1.5
WINCORE.CPP Line 509 - Visual C++ 1.0
CWnd::GetSuperWndProcAddr()
static WNDPROC NEAR pfnSuper = NULL;
ASSERT(pfnSuper == NULL); // should never be changed !!!
// if this is non-NULL, then a derived class of CWnd
// forgot to override 'superWndProc' as well as 'className'
This can be caused by calling SubClassWindow() or SubClassDlgItem()
without overriding GetSuperWndProcAddr() in your CWnd derived class.
This has also been caused by memory corruption.
----------
WINCORE.CPP Line 398 - Visual C++ 1.5
WINCORE.CPP Line 349 - Visual C++ 1.0
CWnd::Create()
// can't use for desktop or pop-up windows (use CreateEx instead)
...
ASSERT((dwStyle & WS_POPUP) == 0);
CWnd::Create() doesn't allow WS_POPUP style.
Use CreateEx() instead.
----------
WINCORE.CPP Line 1228 - Visual C++ 1.5
WINCORE.CPP Line 1127 - Visual C++ 1.0
CWnd::OnCommand()
// control notification
ASSERT(::IsWindow(hWndCtrl)); ASSERT(::IsWindow(hWndCtrl)); //
This assert is caused if a WM_COMMAND is received without a valid
child control ID. Some third party controls may send such WM_COMMAND
messages. Override CWnd::OnCommand() to avoid this assert.
----------
WINCORE.CPP Line 1017 - Visual C++ 1.5
WINCORE.CPP Line 916 - Visual C++ 1.0
CWnd::WindowProc()
This has been reported to have been caused by non-NEAR
ON_REGISTERED_MESSAGE messages in _USRDLL's. This was also
associated with a General Protection Fault occurring on lines
913-914 instead of the assert. Override CWnd::WindowProc() to
avoid this problem. See Knowledge Base article Q99787, "PRB: GP
Fault From ON_REGISTERED_MESSAGE() in _USRDLL" for more details.
----------
WINCORE.CPP Line 543 - Visual C++ 1.5
WINCORE.CPP Line 478 - Visual C++ 1.0
CWnd::DestroyWindow()
This has been caused by destroying or closing windows before a
message pump was active - for example, in InitInstance.
----------
WINCORE.CPP Line 384 - Visual C++ 1.5
WINCORE.CPP Line 335 - Visual C++ 1.0
CWnd::PreCreateWindow()
// no WNDCLASS provided - use child window default
ASSERT(cs.style & WS_CHILD);
This assert is because the CWnd default style requires
a WS_CHILD window class style. Use CFrameWnd derived
classes for non-child windows.
----------
WINBTN.CPP Line 109 - Visual C++ 1.0 and 1.5
CBitmapButton::DrawItem()
// must have at least the first bitmap loaded before calling DrawItem()
ASSERT(m_bitmap.m_hObject != NULL); // required
Failed to load CBitmapButton bitmap for normal image.
Note that ID's for AutoLoad() and LoadBitmaps() need to be "STRING" ID's!
----------
APPPRNT.CPP Line 52 - Visual C++ 1.0
CWinApp::UpdatePrinterSelection()
ASSERT(lpDevNames != NULL);
To duplicate, you can run the Scribble or Viewex samples.
Choose File, Print, click Print Setup. Change the printer
driver to a different printer. Choose OK. Select Cancel
from the Print dialog. Select File, Print (or Print Setup).
It will assert. Ignoring this causes a General Protection
Fault.
You can fix this by modifying CWinApp::DoPrintDialog in APPPRNT.CPP.
Modify the line:
while((nResponse = pPD-<DoModal()) != IDOK)
to
int nResponse = pPD-<DoModal();
while(nResponse != IDOK && nResponse != IDCANCEL)
You will need to rebuild the MFC libraries after this modification.
This is fixed in Visual C++ 1.5.
----------
WINCTRL.CPP Line 284 - Visual C++ 1.0 and 1.5
CWnd::SubClassWindow()
Before this assert, two TRACE messages will be output:
Error: Trying to use SubClassWindow with incorrect CWnd derived class
hWnd = 0xABCD is not a CWndClassName
This assert will be hit if the window procedure of the window
the SubClassWindow() is attempting to subclass is different from
the window procedure of any previous window SubClassWindow() was
called on for this CWnd derived class type.
This is checked for as follows. GetSuperWndProcAddr() should be
overridden to return a pointer to a WINDPROC variable. When
SubClassWindow() is called, it uses this pointer to set the WNDPROC
pointer to point to window procedure of the window being subclassed.
Now, if GetSuperWndProcAddr() returned a non-null pointer then this
CWnd derived class's SubClassWindow() was likely used previously to
subclass a window. (This is because GetSuperWndProcAddr() often
returns a pointer to a static variable.) SubClassWindow() should
only be getting called again to subclass a window of the same
window class (WNDCLASS) that it had previously been used to subclass.
Note that SubClassDlgItem() maps to a call to SubClassWindow(). For
an example of using such subclassing, and of overriding
GetSuperWndProcAddr(), see the CTRLTEST sample.
----------
WINCTRL.CPP Line 272 - Visual C++ 1.0 and 1.5
CWnd::SubClassWindow()
ASSERT(oldWndProc != (WNDPROC)AfxWndProc);
This assert occurs because the window being subclassed has
either already been subclassed by another CWnd derived class,
or IS a CWnd window.
----------
WINCTRL.CPP Lines 121, 123, and 125 - Visual C++ 1.0 and 1.5
CListBox::DrawItem()
CListBox::MeasureItem()
CListBox::CompareItem()
These are default asserts. If you have an owner draw listbox,
you must override these member functions.
----------
OBJCORE.CPP Lines 38, 40 - Visual C++ 1.0 and 1.5
CObject::IsKindOf()
ASSERT(this != NULL);
// it better be in valid memory, at least for CObject size
ASSERT(AfxIsValidAddress(this, sizeof(CObject)));
This assert is caused by calling IsKindOf() on an invalid CWnd
derived class object. Most likely the object was either not
initialized (a NULL or wild pointer) or memory has been corrupted.
This has also been caused by trying to access a VBX control
before it is fully created. When handling OnInitDialog(), post
custom message to set VBX properties instead
----------
DLGDATA.CPP Line 516 - Visual C++ 1.5
DLGDATA.CPP Line 491 - Visual C++ 1.0
DDX_Control()
ASSERT(!pDX->m_bSaveAndValidate);
This assert is caused by calling UpdateData() or UpdateData(TRUE)
without calling UpdateData(FALSE) at least once first.
Make sure to call base class CFormView::OnInitialUpdate()
or CDialog::OnInitDialog() to have such a call made, or make
it yourself before calling UpdateData(TRUE).
----------
DLGDATA.CPP Line 41 - Visual C++ 1.0 and 1.5
CDataExchange::PrepareCtrl()
HWND hWndCtrl = ::GetDlgItem(m_pDlgWnd->m_hWnd, nIDC);
if (hWndCtrl == NULL)
{
TRACE1("Error: no data exchange control with ID 0x%04X\n", nIDC);
ASSERT(FALSE);
...
This assertion will generate the TRACE statement
"Error: no data exchange control with ID 0xABCD" before
asserting. It can be caused by removing a control associated
with data exchange variables.
It can also be caused in _AFXDLL applications and DLLs (using
MFC200.DLL or MFC250.DLL), when the ID of a dialog template in
the DLL matches the ID of a dialog template in the applciation.
The reason for this is that _AFXDLL applications and DLL's search
both the application's and DLL's resources when loading dialog
templates or other resources. If a CDialog derived class in an
_AFXDLL DLL is associated with a dialog template in that DLL, but
there is also a dialog template with the same ID in the _AFXDLL
application the DLL is linked to, when the dialog is created in
the DLL it might get the dialog template in the application which,
unsurprisingly, doesn't contain the DDX/DDV control which was in
the DLL's dialog template. To avoid this assertion, just make sure
that ID's of resources in _AFXDLL applications and DLL's don't
match.
----------
DLGDATA.CPP Lines 250 and 269 - Visual C++ 1.5
DLGDATA.CPP Lines 233 and 252 - Visual C++ 1.0
DLGDATA.CPP Lines 276 and 193 - Visual C++ 4.0
DDX_Radio()
ASSERT(::GetWindowLong(hWndFirstCtrl, GWL_STYLE) & WS_GROUP);
ASSERT(value == -1); // only set once
These asserts may be hit if DDX_Radio() is called on a radio
button other than the first radio button in a group, or if
it is called more than once for the radio buttons in a group.
The first radio button in the group should have the WS_GROUP
window style while none of the other buttons in the group should
have it.
----------
DOCTEMPL.CPP Line 325 - Visual C++ 1.5
DOCTEMPL.CPP Line 207 - Visual C++ 1.0
CDocTemplate::InitialUpdateFrame()
This assert has been reported due to incorrect order of creation
of CDocTemplate and framework objects, and incorrect allocation
of memory for CFrameWnd objects.
----------
WINHAND.CPP Line 169 - Visual C++ 1.5
WINHAND.CPP Line 129 - Visual C++ 1.0
CHandleMap::SetPermanent()
ASSERT(!LookupPermanent(h, pObject)); // must not be in there
This assert can be caused by not releasing a device context (DC)
that was attached to a CDC object or by calling Attach on a
GDI resource already associated with some other MFC object and
thus in the permanent handle map.
----------
WINHAND.CPP Lines 145 and 173 - Visual C++ 1.0
CHandleMap::RemoveHandle()
CHandleMap::DeleteTemp()
This assert can be hit if detaching a temporary object. A
workaround to this is described in the Knowledge Base article
Q98867, "BUG: Temporary Object Memory Leak in Foundation Classes."
This is fixed in Visual C++ version 1.1 for Windows NT and in
Visual C++ 1.5 for Windows.
----------
VIEWEDIT.CPP Line 453 - Visual C++ 1.5
VIEWEDIT.CPP Line 417 - Visual C++ 1.0
CEditView::PaginateTo()
ASSERT(nPageSave > 1);
This can be caused if your view overrides OnPrepareDC() and does
not call the base class CEditView::OnPrepareDC(). In general,
for printing, you should set the number of pages to print in
OnPreparePrinting() or OnBeginPrinting(). See the documentation
for these functions for more information.
----------
APPUI.CPP Line 241 - Visual C++ 1.5
APPUI.CPP Line 296 - Visual C++ 1.0
_AfxGetSafeOwner()
ASSERT_VALID(pParent);
This error can be caused by specifying an invalid parent window for
CDialog, or any of the common dialog classes such as CPrintDialog.
Make sure that you are specifying a correct CWnd * as the parent of
the dialog. This is often set in the CDialog constructor.
----------
APPUI.CPP Line 336 - Visual C++ 1.5
APPUI.CPP Line 362 - Visual C++ 1.0
AfxMessageBox()
There will be a TRACE output ""Error: failed to load message box
prompt string 0xABCD" before this assert. The assert is caused
by a LoadString failure. Since the string resource doesn't exist,
either it was incorrectly specified, or the user didn't loaded a
needed RC file, such as afxres.rc (see MFC Technote 23, "Standard
MFC Resources").
----------
AFXWIN1.INL Line 22 - Visual C++ 1.5
AFXWIN1.INL Line 25 - Visual C++ 1.51
APPCORE.CPP Line 602 - Visual C++ 1.0
APPCORE.CPP Line 559 - Visual C++ 1.1 for Windows NT
AfxWinInit()
//Visual C++ 1.5 and 1.51
ASSERT(afxCurrentInstanceHandle != NULL);
// Visual C++ 1.0 and 1.1
ASSERT(pApp != NULL); // must have one CWinApp derived object defined
A CWinApp derived class object is required for all MFC applications.
See Knowledge Base article Q85496, "PRB: Assertion Failed - WINAPP.CPP,
Line 258" for more information. Under some conditions CWinApp objects
are required for _USRDLL's.
----------
DLGCORE.CPP Line 69 - Visual C++ 1.0 and 1.5
_AfxDlgProc()
A TRACE message "Warning: something went wrong in dialog init" will
be output before this assert. This assert can be caused by
LocalAlloc() failures or other dialog problems, such as dialog
controls on the dialog template having fatal errors during their
construction.
----------
WINGDI.CPP Lines 284, 299, 310, 321, and 332 - Visual C++ 1.0 and 1.5
CDC::SelectObject() (multiple locations for overloaded function)
ASSERT( m_hDC != NULL );
This assert can be caused when attempting to use a CDC object
on which none of GetDC(), CreateDC(), or Attach() have been called.
----------
WINGDI.CPP Line 820 - Visual C++ 1.5
WINGDI.CPP Line 796 - Visual C++ 1.0
CGdiObject::FromHandle()
ASSERT(pObject == NULL || pObject->m_hObject == h);
This can be caused by trying to create a new object before
deleting a previous one. For example, calling
m_font.CreateFontIndirect() twice without calling
m_font.DeleteObject() between the calls will cause this.
----------
WINGDI.CPP Line 826 - Visual C++ 1.5
WINGDI.CPP Line 802 - Visual C++ 1.0
CGdiObject::Attach()
ASSERT(m_hObject == NULL); // only attach once, detach on destroy
This can be caused by not selecting GDI objects out of a CDC
that had been selected in to (with SelectObject()).
----------
FILECORE.CPP Lines 335 and 351 - Visual C++ 1.5
FILECORE.CPP Lines 341, 358 - Visual C++ 1.0
CFile::Read(), CFile::Write()
This can be caused by working with a buffer larger than 64K.
See the Knowledge Base article Q92860, "Read From or Write To
CFile From Buffer Larger than 64K" for more information on how to
work around this.
----------
STRCORE.CPP Line 276 - Visual C++ 1.5
STRCORE.CPP Line 336 - Visual C++ 1.0
CString::GetBufferSetLength()
ASSERT(nNewLength >= 0);
This can be caused by using CWnd::GetWindowText(CString&)
when there is no window title. It is a known Windows problem
that GetWindowTextLength() returns -1 for "Drop List" combo
boxes. You can use CWnd::GetWindowText( LPSTR, int max )
to avoid this problem. See Knowledge Base article Q99199,
"PRB: Cwnd::GetWindowText(CSting&) Asserts w/ Drop-Down COmbo"
for more information.
----------
WINMDI.CPP Line 410 - Visual C++ 1.5
WINMDI.CPP Line 375 - Visual C++ 1.0
CMDIChildWnd::PreCreateWindow()
ASSERT(cs.style & WS_CHILD);
// MFC V2 requires that MDI Children are created with proper styles,
// usually: WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW.
// See Technical note TN019 for more details on MFC V1->V2 migration.
CMDIChildWnd classes require the WS_CHILD style. See MFC Technote 19.
----------
WINMDI.CPP Line 434 - Visual C++ 1.5
WINMDI.CPP Line 399 - Visual C++ 1.0
CMDIChildWnd::Create()
ASSERT(pMainWnd != NULL);
MDI children require a frame window first.
----------
DCPREV.CPP Line 289 - Visual C++ 1.0 and 1.5
CPreviewDC::MirrorFont()
ASSERT(cyDesired >= 0 && cyActual >= 0);
Some small TT fonts have been reported to cause this assert in
print preview
----------
VIEWSCRL.CPP Line 155 - Visual C++ 1.5
VIEWSCRL.CPP Line 153 - Visual C++ 1.0
CScrollView::SetScrollSizes()
ASSERT(sizeTotal.cx >= 0 && sizeTotal.cy >= 0);
This assert is caused if scroll sizes are not correctly initialized
- if no second parameter is passed to SetScrollSizes().
----------
VIEWSCRL.CPP Lines 662 and 668 - Visual C++ 1.5
VIEWSCRL.CPP Lines 528 and 534 - Visual C++ 1.0
CScrollView::OnHScroll()
CScrollView::OnVScroll()
ASSERT(pScrollBar == GetScrollBarCtrl(SB_HORZ)); // may be nulll
ASSERT( pScrollBar == GetScrollBarCtrl(SB_VERT) );
This assert explicitly checks to see if the message was generated
by a control. If the message might not generated by a control,
commenting out this assert is one option.
----------
AFXWIN1.INL Line 25 - Visual C++ 1.5
AFXWIN.INL Line 27 - Visual C++ 1.0
AfxGetResourceHandle()
ASSERT(afxCurrentResourceHandle != NULL);
This assert has been reported to be caused by problems with the
constructors of global objects.
----------
AFXDLGS.INL Line 27 - Visual C++ 1.0 and 1.5
CFontDialog::GetCurrentFont()
ASSERT( m_hWnd != NULL )
This assert is caused by calling GetCurrentFont() while the dialog is
NOT actually displaying. For example, after the DoModal() has returned.
GetCurrentFont() must be called while dialog is active.
----------
APPHELP.CPP Line 34 - Visual C++ 1.0 and 1.5
AfxFormatStrings()
{
char szFormat[256];
if (!_AfxLoadString(nIDS, szFormat) != 0)
{
TRACE1("Error: failed to load AfxFormatString string 0x%04x\n", nIDS);
ASSERT(FALSE);
This assert is caused by a LoadString() failure. Before the assert,
TRACE will output " Error: failed to load AfxFormatString string 0xABCD".
A common cause of this is not including the resources needed, such
as resources for print preview. See MFC Technote 23, "Standard MFC
Resources" for more information.
----------
TIMECORE.CPP Line 43 - Visual C++ 1.0 and 1.5
CTime::CTime()
This assert is caused by the mktime() function returning -1.
Although there are a number of previous error checks for the
validity of the parameters being passed to mktime, these
asserts do not catch all possible bad dates or times. Check
all data being passed to this function carefully.
----------
FILETXT.CPP Line 71 - Visual C++ 1.0 and 1.5
CStdioFile::Open()
ASSERT((nOpenFlags & CFile_shareMask) == 0);
CStdioFile represents C run-time stream file opened by fopen().
The fopen() function doesn't accept share flags.
----------
WINMENU.CPP Line 70 - Visual C++ 1.0 and 1.5
CMenu::Attach()
ASSERT(m_hMenu == NULL); // only attach once, detach on destroy
This assert can be caused by doing two LoadMenu() calls without
doing a DestroyMenu() call between them.
Additional query words:
2.00 2.10 2.50
Keywords : kbprg kb16bitonly kbnokeyword kbMFC kbVC
Version : 1.0 1.5
Platform : NT WINDOWS
Issue type : kbinfo
Last Reviewed: July 7, 1999