Article ID: 133025
Article Last Modified on 11/21/2006
// Note: for 32-bit compilers, replace occurrences of _fmemcpy()
// with memcpy() (or add windowsx.h to your include files)
void CMyApp::SetPrinterDeviceDefaults(HGLOBAL hDevNames,
HGLOBAL hDevMode)
{
// Lock the handles to the structures to get pointers
LPDEVNAMES pDevNames = (LPDEVNAMES)::GlobalLock(hDevNames);
LPDEVMODE pDevMode = (LPDEVMODE)::GlobalLock(hDevMode);
// Free the old printer information if it exists
if (m_hDevNames != NULL)
::GlobalFree(m_hDevNames);
if (m_hDevMode != NULL)
::GlobalFree(m_hDevMode);
// Allocate space for the new printer info structures
m_hDevNames = ::GlobalAlloc(GPTR, ::GlobalSize(hDevNames));
m_hDevMode = ::GlobalAlloc(GPTR, ::GlobalSize(hDevMode));
// Lock the new handles
LPDEVNAMES m_pDevNames = (LPDEVNAMES)::GlobalLock(m_hDevNames);
LPDEVMODE m_pDevMode = (LPDEVMODE)::GlobalLock(m_hDevMode);
// Copy the printer information into the document
_fmemcpy(m_pDevNames, pDevNames,
(size_t)::GlobalSize(hDevNames));
_fmemcpy(m_pDevMode, pDevMode,
(size_t)::GlobalSize(hDevMode));
// Unlock the handles
::GlobalUnlock(hDevNames);
::GlobalUnlock(hDevMode);
::GlobalUnlock(m_hDevNames);
::GlobalUnlock(m_hDevMode);
}
The function prototype for CMyDoc::SetPrinterDeviceDefaults() should be
added to the class definition of CMyDoc in the header file. The following
declarations should also be added to CMyDoc:
HGLOBAL m_hDevMode;
HGLOBAL m_hDevNames;
void CMyDoc::SetPrinterDeviceDefaults()
{
// Allocate the structure to store the returned printer info
PRINTDLG printDlg;
// Get the printer information
AfxGetApp()->GetPrinterDeviceDefaults(&printDlg);
// Lock the handles to the structures to get pointers
LPDEVNAMES pDevNames =
(LPDEVNAMES)::GlobalLock(printDlg.hDevNames);
LPDEVMODE pDevMode = (LPDEVMODE)::GlobalLock(printDlg.hDevMode);
// Free the old printer information if it exists
if (m_hDevNames != NULL)
::GlobalFree(m_hDevNames);
if (m_hDevMode != NULL)
::GlobalFree(m_hDevMode);
// Allocate space for the new printer info structures
m_hDevNames = ::GlobalAlloc(GPTR,
::GlobalSize(printDlg.hDevNames));
m_hDevMode = ::GlobalAlloc(GPTR, ::GlobalSize(printDlg.hDevMode));
// Lock the new handles
LPDEVNAMES m_pDevNames = (LPDEVNAMES)::GlobalLock(m_hDevNames);
LPDEVMODE m_pDevMode = (LPDEVMODE)::GlobalLock(m_hDevMode);
// Copy the printer information into the document
_fmemcpy(m_pDevNames, pDevNames,
(size_t)::GlobalSize(printDlg.hDevNames));
_fmemcpy(m_pDevMode, pDevMode,
(size_t)::GlobalSize(printDlg.hDevMode));
// Unlock the handles
::GlobalUnlock(printDlg.hDevNames);
::GlobalUnlock(printDlg.hDevMode);
::GlobalUnlock(m_hDevNames);
::GlobalUnlock(m_hDevMode);
}
These routines are similar. They use the same code to allocate a new block
of memory and copy the information from one set of structures to the other.
This ensures that no matter what the application object or document object
does to its respective printer information, the other object is not
affected.
CMyDoc::CMyDoc()
{
// Initialize the handles to the printer information
m_hDevNames = NULL;
m_hDevMode = NULL;
// Initialize printer settings
SetPrinterDeviceDefaults();
}
The next two member functions, one from the view and the other from the
application, guarantee that the application uses the document's printer
information and that the document's information is updated if the user
changes it.
void CMyView::OnFilePrint()
{
CMyDoc* pDoc = GetDocument();
// Set the application's printer information
((CMyApp *)AfxGetApp())->SetPrinterDeviceDefaults(
pDoc->m_hDevNames,
pDoc->m_hDevMode);
CView::OnFilePrint();
// Set the new printer information
pDoc->SetPrinterDeviceDefaults();
}
void CMyApp::OnFilePrintSetup()
{
CFrameWnd* pFrame = ((CFrameWnd *)m_pMainWnd)->GetActiveFrame();
CMyDoc* pDoc = (CMyDoc *)pFrame->GetActiveDocument();
// Set the application's printer information
SetPrinterDeviceDefaults(pDoc->m_hDevNames, pDoc->m_hDevMode);
CWinApp::OnFilePrintSetup();
// Set the new printer information
pDoc->SetPrinterDeviceDefaults();
}
Once these code changes are in place, each object derived from the modified
document class stores its own printer information. Because this could lead
to confusion for users who are used to the standard global printer
configuration model, Microsoft recommends that you include the currently
selected printer name as part of the document title.
Additional query words: kbinf 1.00 2.00 2.10 2.20 2.50 2.51 2.52 3.00 3.10 4.00 4.10
Keywords: kbhowto kbprint kbcode KB133025