Click here to Skip to main content
15,898,035 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
The problem happens on 64 bit Windows version. If I run an application (build in Debug mode) calling:
CPrintDialog dlg
dlg.DoModal
then I select cancel, when I exit from the application I get a crash on wincore.cpp line 415
The problem does not happen if the application is build in release mode, but I would like to keep it in debug mode.
Is there any clue?

What I have tried:

DeleteDC(dlg.m_pd.hDC) does not work because it fails
Posted
Updated 30-Jun-18 21:12pm
v2

It is not a crash but an assertion is thrown. Assertions are only thrown in debug builds. They are mainly used to inform you during development that something weird has happened (read: the developer has made a serious mistake).

When mentioning a line number within an MFC source file like wincore.cpp, you should also mention the used VS version or better open that file (it is located at VC\atlmfc\src\mfc) and add the function name and the line content.

With my wincore.cpp version the lines 412 to 414 are
C++
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
ASSERT(pWnd != NULL);					
ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd);
with the AfxWndProc() function.

Run the program from the debugger and check the call stack when the assertion occurs to know for which window the function is called.

Read also about the CPrintDialog Class[^] and check if your code applies. Because you are creating the print dialog on the stack, it is deleted when going out of scope. Then an assertion for that window would occur earlier and not when closing the application. So the real reason for the assertion might be somewhere else in your application.

For better help you should post the complete function that uses the print dialog. Something like
C++
void SomeClass::SomeFunc()
{
    BOOL bPrintSetupOnly = FALSE;
    CPrintDialog dlg(bPrintSetupOnly);
    if (dlg.DoModal() == IDOK)
    {
        // do something here

        // If dlg.m_pd.hDC has not been assigned to a member variable
        if (!bPrintSetupOnly) // or GetDefaults, or GetPrinterDC has been called
            DeleteDC(dlg.m_pd.hDC);
        // Otherwise do it when not used anymore 
        //  (at least when this SomeClass instance destroyed).
        // But that requires tracking the state (clear member variable after deleting)
        //  and deleting it also on top of this function when not NULL
    }
}
 
Share this answer
 
Comments
MarcoChiesi 6-Apr-18 2:59am    
Thank you for answering. I'm developing the software with VS2010 on my WXP pc, because I need that this software can run on XP also (I noticed that developing on W7 makes that software does not run on XP). Everything is fine, but I noticed the problem when testing software on a PC with W10. So I wrote a very little test software with a simple window with a simple button which just do:

CPrintDialog dlg(TRUE);
dlg.DoModal();
DeleteDC(dlg.m_pd.hDC);

so, I already wrote the whole code :)
I know that building in release makes the assertion disappear, but passing to release version for the whole big software I'm developing makes several troubles elsewhere in it, so that's why I'm trying to keep debug version.

That's what I have at line 415 and near in wincore:

WNDPROC AFXAPI AfxGetAfxWndProc()
{
#ifdef _AFXDLL
return AfxGetModuleState()->m_pfnAfxWndProc;
#else
return &AfxWndProc;
#endif
}

Thank you again!
Jochen Arndt 6-Apr-18 3:30am    
Some notes (which will not solve the problem).

You can develop applications for XP when running VS on Win 7 or Win 10.

Using a simple test application isa good idea beacuse it simplifies finding problems.

When creating a CPrintDialog with bPrintSetupOnly = TRUE and not querying a DC by functions no DC will be created. So there is no need to call DeleteDC.

Installing debug versions requires installing debug versions of the C/C++ standard and MFC DLLs (or linking to those statically). But you are not allowed to publish such debug builds because the debug DLLs versions are not redistributable. However, installing on different systems for testing purposes is allowed.

Your code snippet from wincore.cpp does not include any assertion statement.

Create the test application on W10 and run it within the debugger. Then check the call stack when the assertion occurs.

When the error is happening in the provided code line than are some error causes possible. First: set hDC in the constructor to 0 to avoid any unneeded call!!!

try:

- multiple delete of the hDC (check that it is only called once
- some buggy manipulation of dlg.m_pd
C++
if(dlg.m_pd.hDC !=0) 
{
  DeleteDC(dlg.m_pd.hDC);
  dlg.m_pd.hDC = 0;
  dlg.m_pd = 0;//if possible or somewhere else.
}
Take the error seriously because the error may only the symptom of a greater problem. (I learned that the hard way)
 
Share this answer
 
Comments
MarcoChiesi 6-Apr-18 3:01am    
Thank you for answering. I tried it but the assertion does not disappear (dlg.m_pd=0; is not accepted by compiler). As I wrote in the other comment, it is just a simple test program to investigate the matter and apply a possible solution in my big software.
I'm having exactly the same problem. When CPrintDialog.DoModal() or CPrintDialog.GetDefaults() is called, then the assertion fires when the application exits. This is happening in a code base that was originally developed in VC6 (toolset v60). The problem arises when the code is build with VS2010 (toolset v100).
 
Share this answer
 
Comments
CHill60 2-Jul-18 5:10am    
is this meant to be a solution?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900