Acknowledgements
First, I would like to acknowledge some articles which I used as a reference when putting this project together.
Overview
The standard Print Preview mechanism supplied by MFC is a little understood phenomenon. There are few enhancements currently published for it, and none for showing more than 2 pages at a time in preview mode. I set out to solve this! It turned out to be reasonably easy to do, working from the examples supplied by Robin and Yasuhiko. In my solution, I used small parts of both examples (Robins onwner drawn buttons, and Yasuhiko's extra zoom levels).
The enhancement are:
- From 1 to 9 pages viewed at a time - selectable by a popup menu
- The scrollbar will not allow blank pages to be scrolled into view
- You can switch dynamically between portrait and landscape mode using the toolbar command
So how do you go about using these enhancements?
Adding the Required Resources
To use this enhanced preview mode, you need to include the following resources into your project.
These should be copied and pasted into your project. You can do this from the VC IDE, or by manually editing the .rc file (not really recommended):
- The replacement toolbar resource
- The popup menu resource
- The button bitmaps
Add the Source Files
The enhanced preview uses the following source files:
- MappedBitmapButton.cpp/h - Robin J. Leatherbarrow
- MultiPagePreview.cpp/h - Myself with some code from Yasuhiko
- An additional function in your
CWinApp
derived class - see later
Replacing the Standard Print Preview
To replace the standard PrintPreview
supplied by the MFC Doc/View architecture, you have to write a handler in your projects CView
class to handle the ID_FILE_PRINT_PREVIEW
command. You put the following code in that handler to supplant the MFC preview with the new one:
CPrintPreviewState* pState = new CPrintPreviewState;
if (!DoPrintPreview(IDD_PREVIEW, this, RUNTIME_CLASS(CMultiPagePreviewView),
pState))
{
TRACE0("Error: DoPrintPreview failed.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState;
pState = NULL;
}
Update Your CWinApp Derived Class
The additional functionality to switch dynamically between portrait and landscape mode in print preview requires support of an additional function in your CWinApp
derived class. This is because the m_hDevMode
object is a protected
member and cannot be accessed directly by the preview class. The prototype of this function and the code for it is as follows:
void SetPrintOrientation(int mode) ;
void CYourApp::SetPrintOrientation(int mode)
{
switch (mode)
{
case DMORIENT_PORTRAIT :
{
PRINTDLG pd;
pd.lStructSize = (DWORD)sizeof(PRINTDLG) ;
BOOL bRet = GetPrinterDeviceDefaults(&pd) ;
if (bRet)
{
DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(m_hDevMode) ;
pDevMode->dmOrientation = DMORIENT_PORTRAIT ;
::GlobalUnlock(m_hDevMode) ;
}
}
break ;
case DMORIENT_LANDSCAPE :
{
PRINTDLG pd;
pd.lStructSize = (DWORD)sizeof(PRINTDLG) ;
BOOL bRet = GetPrinterDeviceDefaults(&pd) ;
if (bRet)
{
DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(m_hDevMode) ;
pDevMode->dmOrientation = DMORIENT_LANDSCAPE ;
::GlobalUnlock(m_hDevMode) ;
}
}
break ;
default : ASSERT(FALSE) ;
}
}
If you are adding this to your application, you will also have to mod the code so it uses your CWinApp
derived class name and not that of the demo project. If you insert the code and compile. The errors generated will get you to the lines you will need to update.
Once all of this is in, the preview mode should work automatically. You should now be able to preview upto a maximum of 9 pages simultaneously. This can be expanded for more by enhancing the options in the popup menu, and modifying the function CMultiPagePreviewView::OnPreviewPages()
to handle the new layout. Just make sure that you increase the size of the m_pageInfoArray2
array in the .h file to avoid overwriting memory. So if you wanted to support a 4 * 4 preview, the array size needs to be increased from 9 to 16.
Changes Made
- 24-4-2002 Release 1
- 28-4-2002 Release 2 - Added portrait/landscale switching and updated the scrollbar control code
Future Enhancements
I would like to add the following features in the future:
- Make the pages flicker free
Or you could always add them yourselves.