FIX: No Print Dialog Box Using Foundation Class LibraryID: Q101130
|
When an application uses the default printing implementation provided by
the Microsoft Foundation Class Library, an attempt to perform the following
steps generates an error in the Microsoft Windows debugging kernel:
err <Mappname>-<COMMDLG GLOBALLOCK+C: Invalid global handle
The retail (nondebugging) Windows kernel does not display the Print dialog
box; no other error occurs.
The CWinApp class contains two member variables, m_hDevMode and
m_hDevNames, that contain handles to memory that describes the current
printer selection.
When the Print dialog box invokes the Setup dialog box, changes some
settings and chooses OK, the internal hDevMode and hDevNames that describe
the printer change as well. However, at this point, the Print dialog box
remains active. When the user chooses Cancel in the Print dialog box, the
Foundation Class Library executes its error handling logic which does not
properly update the m_hDevMode and m_hDevNames variables in this case.
Therefore, the next time the user invokes the Print dialog box, these
handles refer to invalid memory and the debugging kernel generates an
error.
This problem has been fixed in version 2.5 of the Microsoft Foundation
Classes. So the workaround below is only necessary if you are using the
Microsoft Foundation Classes version 2.0.
Add the following four functions to your application class derived from
CWinApp:
void SetDevNames(HANDLE hDevNames) {m_hDevNames = hDevNames;}
void SetDevMode(HANDLE hDevMode) {m_hDevMode = hDevMode;}
HANDLE GetDevNames() {return m_hDevNames;}
HANDLE GetDevMode() {return m_hDevMode;}
Then, modify the OnPreparePrinting() function to correct this problem. In
step 5 of the SCRIBBLE sample, modify the function as follows:
BOOL CScribView::OnPreparePrinting(CPrintInfo* pInfo)
{
BOOL bRetValue;
HANDLE hDevMode = ((CScribbleApp*)AfxGetApp())->GetDevMode();
HANDLE hDevNames = ((CScribbleApp*)AfxGetApp())->GetDevNames();
pInfo->SetMaxPage(2); // the document is two pages long:
// the first page is the title page
// the second is the drawing
pInfo->m_nNumPreviewPages = 2; // preview 2 pages at a time
// default preparation
bRetValue = DoPreparePrinting(pInfo);
if (!bRetValue) // User canceled dialog box or an error
// occurred. In either case, if hDevMode or
// hDevNames changed, update the member
// variables.
{
if (hDevMode != pInfo->m_pPD->m_pd.hDevMode)
((CScribbleApp*)AfxGetApp())->
SetDevMode(pInfo->m_pPD->m_pd.hDevMode);
if (hDevNames != pInfo->m_pPD->m_pd.hDevNames)
((CScribbleApp*)AfxGetApp())->
SetDevNames(pInfo->m_pPD->m_pd.hDevNames);
}
return bRetValue;
}
Microsoft confirmed this to be a problem in version 2.0 of the Microsoft Foundation classes. This problem was corrected in version 2.5 of the Microsoft Foundation classes and in version 1.5 of Visual C/C++ for Windows. In addition, this is not a problem in Visual C/C++ 1.0 for Windows NT with Microsoft Foundation Classes, version 2.1.
Additional query words:
Keywords : kberrmsg kbprint kb16bitonly kbMFC kbPrinting kbVC
Version : 1.0
Platform : WINDOWS
Issue type : kbbug
Last Reviewed: July 29, 1999