Microsoft KB Archive/101130

From BetaArchive Wiki
< Microsoft KB Archive
Revision as of 13:39, 20 July 2020 by X010 (talk | contribs) (Text replacement - "<" to "<")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

FIX: No Print Dialog Box Using Foundation Class Library

Q101130



The information in this article applies to:


  • The Microsoft Foundation Classes (MFC), used with:
    • Microsoft Visual C++, version 1.0





SYMPTOMS

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:


  1. Choose Print from the File menu to open the Print dialog box.
  2. Choose the Setup button.
  3. Change the orientation from portrait to landscape.
  4. Choose OK to close the Setup dialog box.
  5. Choose Cancel to close the Print dialog box.
  6. Choose Print from the File menu to open the Print dialog box.

At this point, the application does not display the Print dialog box and the debugging kernel displays the following message:

   err <Mappname>-<COMMDLG GLOBALLOCK+C: Invalid global handle 

The retail (nondebugging) Windows kernel does not display the Print dialog box; no other error occurs.

In step 3 above, if the user chooses to change the printer to another printer rather than changing the orientation, another symptom occurs for the same reasons as discussed in the Cause section below. Rather than the print dialog box not appearing, an assertion occurs. The assertion occurs in the APPPRNT.CPP source file on line 52.



CAUSE

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.



RESOLUTION

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;
   } 



STATUS

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 kbVC100fix kbDSupport
Issue type : kbbug
Technology : kbAudDeveloper kbMFC


Last Reviewed: May 8, 2001
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.