Click here to Skip to main content
Click here to Skip to main content

MultiPage PrintPreview enhancements for MFC Doc/View applications

By , 27 Apr 2002
 

Sample Image - 9pages.gif

Acknowledgements

First I would like to acknowledge some articals 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 this these enhancements?

    Adding the required resources

    To use this enhanced preview mode, you need to include the folowing resources into your project

    • The replacement toolbar resource
    • The popup menu resource
    • The button bitmaps
    • 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)

    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:

    // replace the default print preview with ours!
    
    // In derived classes, implement special window handling here
    // Be sure to Unhook Frame Window close if hooked.
        
    // must not create this on the frame.  Must outlive this function
    CPrintPreviewState* pState = new CPrintPreviewState;
        
    // DoPrintPreview's return value does not necessarily indicate that
    // Print preview succeeded or failed, but rather what actions are necessary
    // at this point.  If DoPrintPreview returns TRUE, it means that
    // OnEndPrintPreview will be (or has already been) called and the
    // pState structure will be/has been deleted.
    // If DoPrintPreview returns FALSE, it means that OnEndPrintPreview
    // WILL NOT be called and that cleanup, including deleting pState
    // must be done here.
        
    if (!DoPrintPreview(IDD_PREVIEW, this, RUNTIME_CLASS(CMultiPagePreviewView),
                        pState)) // note, put your class name in here
    {
        // In derived classes, reverse special window handling here for
        // Preview failure case
            
        TRACE0("Error: DoPrintPreview failed.\n");
        AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
        delete pState;      // preview failed to initialize, delete State now
        pState = NULL;
    }
    

    Update your CWinApp derived class

    The additonal 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 a follows:

    // prototype for CWinApp derived class
    void        SetPrintOrientation(int mode) ;
    
    void CYourApp::SetPrintOrientation(int mode)
    {
        switch (mode)
            {
            case DMORIENT_PORTRAIT :
                    {
                    // portrait mode
                    PRINTDLG pd;
                    pd.lStructSize = (DWORD)sizeof(PRINTDLG) ;
                    BOOL bRet = GetPrinterDeviceDefaults(&pd) ;
                    if (bRet)
                        {
                        // protect memory handle with ::GlobalLock and ::GlobalUnlock
                        DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(m_hDevMode) ;
                        // set orientation to portrait
                        pDevMode->dmOrientation = DMORIENT_PORTRAIT ;
                        ::GlobalUnlock(m_hDevMode) ;
                        }
                    }
                    break ;
            case DMORIENT_LANDSCAPE :
                    {
                    // landscape mode
                    PRINTDLG pd;
                    pd.lStructSize = (DWORD)sizeof(PRINTDLG) ;
                    BOOL bRet = GetPrinterDeviceDefaults(&pd) ;
                    if (bRet)
                        {
                        // protect memory handle with ::GlobalLock and ::GlobalUnlock
                        DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(m_hDevMode) ;
                        // set orientation to landscape
                        pDevMode->dmOrientation = DMORIENT_LANDSCAPE ;
                        ::GlobalUnlock(m_hDevMode) ;
                        }
                    }
                    break ;
            default :    ASSERT(FALSE) ;        // invalid parameter
            }
    }
    

    If your 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 update the scrollbar control code

    Future enhancements

    I would like to add in the future the following features:

    • Make the pages flicker free

    Or you could always add them yourselves.

    License

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

    About the Author

    Roger Allen
    Software Developer (Senior) Sirius Analytical Instruments
    United Kingdom United Kingdom
    Member
    A research and development programmer working for a pharmaceutical instrument company for the past 17 years.
     
    I am one of those lucky people who enjoys his work and spends more time than he should either doing work or reseaching new stuff. I can also be found on playing DDO on the Cannith server (Send a tell to "Maetrim" who is my current main)
     
    I am also a keep fit fanatic, doing cross country running and am seriously into [url]http://www.ryushinkan.co.uk/[/url] Karate at this time of my life, training from 4-6 times a week and recently achieved my 1st Dan after 6 years.

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    QuestionWhat piece of code should I change to get rid of the spacing..memberMember 78714814 Mar '13 - 8:01 
    Great article!
     
    One quick question.
     
    What piece of code should I change to remove the blank spacing between the pages?
    So that each page would be beside each other in other words?
    I have tried everything.
     
    Thank you!
    GeneralHellomemberMark Jefferson27 Apr '08 - 4:41 
    Could I send email to you?
    I have some question about printing in MFC. thank you. Smile | :)
    GeneralDon't need to modify you CWinApp classmemberWolfram Rösler21 Jan '07 - 21:59 
    You can get/set the current printer orientation without having to modify your application class because it's not necessary to access CWinApp::m_hDevMode - you find another hDevMode in the PRINTDLG structure retrieved with GetPrinterDeviceDefaults which is ready for use. Just try this, which can go right into the view's message handler:
     
         CWinApp *const pApp = AfxGetApp();
         if (pApp!=NULL)
         {
              PRINTDLG pd;
              pd.lStructSize = sizeof(PRINTDLG);
              if (pApp->GetPrinterDeviceDefaults(&pd))
              {
                   DEVMODE FAR *const pDevMode
                        = reinterpret_cast<DEVMODE FAR *>(::GlobalLock(pd.hDevMode));
                   pDevMode->dmOrientation   = DMORIENT_LANDSCAPE:
                   ::GlobalUnlock(pd.hDevMode);
              }
         }
     
    And it looks just better without those ugly C casts. Smile | :)

    GeneralprintingmemberAlexDa1 Dec '05 - 23:25 
    In a network printer, when the printer print the document, How many pages printer lets print & which system sent the data to print.
     
    How to find this job fron VC++/VB
     
    Please help me



    GeneralCombine pages with portrait and landscapememberStoil24 Sep '04 - 4:47 
    First, great work!!!
    I wonder if it's possible to change your code to have opportunity to add pages with different size and orientation!?
    To have portrait and landscape together!?
    Thank you in advance and Good luck!
     
    Stoil Todorov
    GeneralRe: Combine pages with portrait and landscapememberStoil16 Oct '04 - 0:26 
    I understood how to combine pages with portrait and landscape.
    I found Microsoft Knowledge Base Article - 214617 "Changing the Page Orientation to Landscape Without Interacting with the Print Dialog Box in an MFC-Based Application" in MSDN and I used the given code in my project.
    Now I can change orientation of page during printing and in print preview. The key was in OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) where I change orientation with this function: pDC->ResetDC(m_lpDevMode) - m_lpDevMode show page orientation.
     
    Stoil Todorov
    QuestionFont Bug ?membermroy_10016 Feb '04 - 5:44 
    Why the Print Preview font (Page X of X) change from Courier to Arial, and back to courier depending of the zooming factor and the orientation ?
     
    I'm using WinXP and Win2K and have this issue on both systems
    GeneralFrom landscape to full setupmemberasconaga3 Dec '03 - 3:08 
    Instead of just limiting your code to landscape and portrait why not add the setup dialog.
     
    CWinApp *pApp = AfxGetApp();
    CPrintDialog pd(TRUE);
    pApp->DoPrintDialog(&pd); // print setup dialog
     
    CPrintInfo *pInfo = m_pPreviewInfo;
    m_pPreviewInfo = NULL;
     
    m_dcPrint.Detach(); // print DC is deleted by CPrintInfo destructor
    delete pInfo;
    SetPrintView(m_pPrintView);
     
    This allows the view to change options, printer and orientation
     
    Asconaga Blush | :O
    GeneralProblem with hiding the viewmemberwolfbert17 Oct '03 - 2:27 
    Hello,
    first very nice job, seems to be very helpfull
     
    But before i could even think using this new Print Preview, maybe somebody could help me with following problem.
     
    I use Visual STudio .Net (VC++7.0), migrated a middlesized Application from VC++6.0, But experiences hangups when I try to switch into Print preview.
    I debugged the project and found out that so far everything seems right, Until in
    CFrameWnd::OnSetPreviewMode,
    following code is executed
    HWND hWnd = ::GetDlgItem(m_hWnd, pState->nIDMainPane);
    ASSERT(hWnd != NULL); // must be one that we are hiding!
    ::ShowWindow(hWnd, SW_HIDE);
    where
    pState->nIDMainPane==AFX_IDW_PANE_FIRST
    which should be correct, and the retrieved hWnd seems to be ok too (Its not NULL) but then on the ::ShowWindow command, somehow the application went into an endless loop...
     
    Did anybody had the same Problems and could solve this?
     
    THanks in Advance
    Wolfbert

    Generalvery usefulmemberMarco Walle25 Sep '03 - 5:45 
    This is great! thanks Roger!
    GeneralJust a little improvement...memberKickaha19 Sep '03 - 13:29 
    Good work.
    I know this article is about one year old, but I am new here and there is still something to do:
     
    If the orientation is already landscape, the Checkbox is not checked when you open the preview.
     
    To fix this, we need another additional function in our CWinApp derived class. This is for the same reason, you provided the SetPrintOrientation function. The prototype of this function and the code for it is as follows:
    // prototype
    short GetPrintOrientation(void) ;
     
    // code
    short CYourApp::GetPrintOrientation()
    {
       short sReturnvalue;
    	PRINTDLG pd;
    	pd.lStructSize = (DWORD)sizeof(PRINTDLG);
    	BOOL bRet = GetPrinterDeviceDefaults(&pd);
    	if (bRet)
    	{
    	// protect memory handle with ::GlobalLock and ::GlobalUnlock
    	DEVMODE *pDevMode = (DEVMODE*)::GlobalLock(m_hDevMode);
    	// get orientation
    	sReturnvalue = pDevMode->dmOrientation;
    	::GlobalUnlock(m_hDevMode);
    	}
       return sReturnvalue;
    }
    Don't forget to mod the code so it uses your CWinApp derived class name and not that of the demo project.
     
    Now we just have to put the following code in the CMultiPagePreviewView::OnCreate function, just before the return:
       // initialize landscape Checkbox
       CWinApp *pApp = AfxGetApp();
       CPrinterTestApp *pOurApp = static_cast<CYourApp*>(pApp) ;
       ASSERT(pOurApp);
       short sOrientation = pOurApp->GetPrintOrientation();
       CWnd	*pWnd = m_pToolBar->GetDlgItem(IDC_LANDSCAPE);
       ASSERT(pWnd);
       CButton *pButton = static_cast<CButton*>(pWnd);
       ASSERT(pButton);
       if(sOrientation == DMORIENT_LANDSCAPE)
          pButton->SetCheck(BST_CHECKED);
       else
          pButton->SetCheck(BST_UNCHECKED);
    I hope i did not forget something...
     
    By the way, does someone have a solution for this problem:
     
    When you set the preview to show one page, leave the preview and enter it again, the page is not shown centered as expected. It is shown in the left side of the window, just like it would be, if there were 2 pages to show. If you try this in the landscape mode, it is even more obvious.
     
    Thanks Wink | ;)
    Generali want to send u my ProjectzipmemberBalaji20001 Jun '03 - 20:57 
    can i have ur mail id.. otherwise say how to attach one zipfile to u?..
     
    Balaji
    GeneralAny body Know !..Help Me!..memberBalaji200029 May '03 - 2:07 
    is it Posible to Print richtext with in a given rectangle area
     
    don't worry with the size of file..
    is a simple thing i expliend in lot..
    Trying: Edit,RichEdit control printing,
    with in a rectangle as per they are drawn
    in scroll view..
     
    ----
    //***************************************************************************************
    // I want to draw the RichTextControl content in a specified rectangle on my printing page
    // (as i done with editbox control) using FormatRange function with the different
    // Font styles as in RichEditControl - HelpMe please!.
    // DrawRichText(CDC *pDC) -> could u solve the problem that i have in this function ?..
    //***************************************************************************************
    //The partial code
     
    //RTCtrlPrint1View.h
    public:
    CRTCtrlPrint1Doc* GetDocument();
    //My*************************************
    void RTCtrlCreate();
    void DrawRichText(CDC *pDC);
    void DrawEditText(CDC *pDC);
     
    CRichEditCtrl m_redit;
    CRect m_redRect;
     
    CEdit m_edit;
    CRect m_edRect;
    UINT r;
    CFont font;
    //***************************************
     
    //RTCtrlPrint1View.cpp
    //=======================
    void CRTCtrlPrint1View::OnInitialUpdate()
    {
    CScrollView::OnInitialUpdate();
     
    //edith box displaytext font
    font.CreateFont(14,0,0,0,FW_NORMAL,FALSE,FALSE,
    0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
    CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
    DEFAULT_PITCH|FF_MODERN,"Arial");
     
    r=14;
    m_edRect = CRect(50*r,-100*r,240*r,-700*r);
    m_redRect = CRect(250*r,-100*r,750*r,-700*r);
     
    CSize sizeTotal;
    sizeTotal.cx = 850*r;
    sizeTotal.cy = 1100*r;
    SetScrollSizes(MM_TWIPS, sizeTotal); //MM_TWIPS
     
    RTCtrlCreate();
    }
     
    void CRTCtrlPrint1View::OnDraw(CDC* pDC)
    {
    CRTCtrlPrint1Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
     
    pDC->Rectangle(1*r,1*r,800*r,-1100*r);//Print Area Rect
     
    if(pDC->IsPrinting())
    {
    DrawEditText(pDC);//Simple Edit box text
    DrawRichText(pDC);//My RichEdit box text
    }
    }
     
    #define IDC_REDIT 4001 //defining a resource ID
    #define IDC_EDIT 4002 //defining a resource ID
     
    void CRTCtrlPrint1View::RTCtrlCreate() //creates both Rich edit & Edit Controls
    {
    CRect m_temp;
     
    CClientDC dc(this);
    OnPrepareDC(&dc);
     
    //creating edit box in scroll view
    m_temp = m_edRect;
    dc.LPtoDP(m_temp);
    m_edit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,m_temp,this,IDC_EDIT);
    m_edit.SetFont(&font,FALSE);
    m_edit.SetWindowText("Help Me! Thank u");
     
    //creating rich edit box in scroll view
    m_temp = m_redRect;
    dc.LPtoDP(m_temp);
    m_redit.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,m_temp,this,IDC_REDIT);
     
    //writing some text in richtext control
    CString str;
    str="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang2057{\\fonttbl{\\f0\froman\\fprq2\\fcharset0 Times New Roman;}{\\f1\\fswiss\\fprq2\\fcharset0 System;}}{\\colortbl ;\\red255\\green0\\blue0;\\red51\\green153\\blue102;\\red0\\green0\\blue255;}\\viewkind4\\uc1\\pard\\cf1\\i\\f0\\fs24 ThankYou\
    \\cf0\\i0 \\cf2\\b for\
    \\cf0\\b0 \\cf3 Trying\
    \\cf0 !\\b\\f1\\fs20 \\par }";
     
    EDITSTREAM es;
    es.dwCookie = (DWORD)&str;
    es.pfnCallback = RichEditStreamInCallback;
    m_redit.StreamIn(SF_RTF,es);
    }
     
    void CRTCtrlPrint1View::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
    {

    CScrollView::OnPrepareDC(pDC, pInfo);
     
    // pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetMapMode(MM_TWIPS);
    }
     

    void CRTCtrlPrint1View::DrawEditText(CDC *pDC)
    {
    CRect m_temp;
    m_temp = m_edRect;
     
    CString str;
    m_edit.GetWindowText(str);
    pDC->SetBkMode(TRANSPARENT);
    pDC->Rectangle(m_temp);
    //Draws with Fonts as we wish
    pDC->DrawText(str,m_temp,DT_WORDBREAK|DT_EXPANDTABS|DT_NOPREFIX);
    }
     
    //****************************************************************************
    // I want to draw the RichTextControl content in a specified rectangle on my
    // printing page (as i done with editbox control) using FormatRange function
    // with the different Font styles as in RichEditControl - HelpMe please!.
    // DrawRichText(CDC *pDC) -> could u solve the problem that i have in this
    // function ?..
    //****************************************************************************
    void CRTCtrlPrint1View::DrawRichText(CDC *pDC)
    {
    CRect m_temp;
    FORMATRANGE fmtRange;
    long lLineWidth;
     
    m_temp = m_redRect;
    // pDC->LPtoDP(m_temp);
    pDC->Rectangle(m_temp);
     
    lLineWidth = ::MulDiv(pDC->GetDeviceCaps(PHYSICALWIDTH), 1440,
    pDC->GetDeviceCaps(LOGPIXELSX));
     
    fmtRange.hdc = pDC->m_hDC;
    fmtRange.hdcTarget = pDC->m_hDC;
    fmtRange.rc = m_temp;
    fmtRange.rcPage = m_temp;
    fmtRange.chrg.cpMin = 0;
    fmtRange.chrg.cpMax = -1;
     
    m_redit.SetTargetDevice(pDC->m_hDC, lLineWidth);
    m_redit.FormatRange(&fmtRange, TRUE);
    }
    my MailID: cpbalaji2000@yahoo.com
     
    Balaji
    General...I need help on overwriting CWinAppmembervanjaESS7 May '03 - 10:25 
    I need to provide that my aplication, which inherits CWinApp class, has it's own clipboard - that is, to provide copying, cuting and pasteing only in my aplication's scope.
    I would be gratefull for any kind of tip or a hint...
    GeneralProblems with VC++ 7sussPaul Steane7 Mar '03 - 22:19 
    I have used this code in a VC++ 6 project and it works very well - great!
     
    However (I think) I want to convert this project to VC++7, and there seem to be a couple of problems.
     
    One is easy to fix: in MultiPagePreview.h,
    #include <..\src\afximpl.h>
    needs changing to
    #include <..\src\mfc\afximpl.h>
    (I think this has been referred to in another article)
     
    The other seems more tricky, and seems to be caused by the different presentation of the Print Preview in VC++7 - you can still see the main frame window. If you Exit while in Preview mode, "OnEndPrinting" never gets called so any fonts created in OnBeginPrinting don't get deleted - memory leaks! Cry | :(( It seems likely that the same problem would occur with the "standard" print preview.
     
    Having had a look at the VC++7 documentation, print/preview seems to be done in a somewhat different way. So the question is, is it worth struggling with VC++7 to make this part work? Or does somebody have a quick fix?
    GeneralRe: Problems with VC++ 7memberPaul Steane6 Nov '04 - 9:12 
    I had abandoned VC++7 for other reasons - back to trying it now. And I've solved this problem.
     
    I found it occured when switching from Portrait to Landscape mode within the view.
     
    I was creating some new fonts inside my OnBeginPrinting function, and then deleteing them inside my OnEndPrinting. In VC++6 the latter is called when switching from Portrait to Landscape, but in VC++7 it is not - only when closing the print preview.
     
    Improving the new / delete logic stopped this problem.
     
    Hope this is of some assistance to somebody - evan after all this time!
     
    Paul
    GeneralAnother Bug/Oversite foundmemberEldon Zacek1 Jan '03 - 18:30 
    When you switch between Landscape and Portrait view, you did a very nice job of figuring out how to reset the PreviewView with very little duplicated code. SetPrintView goes through the process of OnPreparePrinting and OnBeginPrinting. The only thing that I found, via my own implementation, was that I perform some operations in OnBeginPrinting that need to be reversed in OnEndPrinting. Therefore, I found that I need to call OnEndPrinting before destroying the PrintInfo class, etc. You will also need to declare this class as a "friend" to the AppView class or make OnEndPrinting a "public" function.
     
    void CMultiPagePreviewView::OnLandscape()
    {
    .
    .
    .
    int state = pButton->GetCheck() ; // portrait or landscape mode?
     
    (OurAppView *)m_pPrintView)->OnEndPrinting(m_pPreviewDC, m_pPreviewInfo);
     
    // get the current CPrintInfo object
    CPrintInfo *pInfo = m_pPreviewInfo ;
    m_pPreviewInfo = NULL ;
    .
    .
    .
    SetPrintView(m_pPrintView) ;
    }

     
    Eldon Zacek
    VP of Engineering
    Czech-Mate Enterprises, LLC

    QuestionHow to realize multipage printpreview in a D/V whose parent class is CStrollView?memberwilliam_shen1 Jan '03 - 2:26 
    I have finished a program using MFC D/V. I used CStrollView class. But I can realize multipage printpreview for every page having the same text.
    I have overload OnPreparDC function like this:
    if (pDC->IsPrinting())
    {int pageHeight = pDC->GetDeviceCaps(VERTRES);
    int originY = pageHeight * (pInfo->m_nCurPage - 1);
    pDC->SetViewportOrg(0, originY);
    }
     
    and in the OnPrint function like this to set mapmode:
    pDC->SetMapMode(MM_ISOTROPIC);
    pDC->SetWindowExt(70,70);
    pDC->SetViewportExt(pDC->GetDeviceCaps (LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSX));Smile | :)

     
    willima
    AnswerRe: How to realize multipage printpreview in a D/V whose parent class is CStrollView?memberRoger Allen2 Jan '03 - 0:41 
    william_shen wrote:
    But I can realize multipage printpreview for every page having the same text
    This will not be a problem in OnPrepareDC() it will be the OnPrint(). This function needs to generate the correct output based on the value of pInfo->m_nCurPage which is the current page being printed. OnPrint() is called once by the MFC for every page of output generated when printing or previewing (everytime a page needs to be re-drawn). THis value is the only thing which tells you what output needs to be generated.

     
    Roger Allen
    Sonork 100.10016
     
    This is a multiple choice question, choose wisely
    Why did the hedgehog cross the road?
    A: To show he had guts?
    B: To see his flat mate?


    Generalquestion about CPrintDialog and DEVMODE Structurememberlavocat2 Dec '02 - 0:21 
    I would like to retrieve the height and the width of the paper selected in
    the CPrintDialog by the user.
    When I display the CPrintDialog then if the user change the paper,
    dmPaperLength and dmPaperWidth are not updated but dmFormName is updated.
     
    dmPaperLength and dmPaperWidth are updated only if I reload the CPrintDialog and
    press ok button again.
     
    I remarq that dmpapersize is updated but how can I retrieve the height and the width
    from dmpapersize??
     
    Thank you,
     
    Christophe from Belgium
     

    This is my code :
    //-------------------------------------------
    int ret;
    PRINTDLG PRT_DLG;
    LPDEVMODE lpDevMode;
     
    CPrintDialog pd( true,PD_ALLPAGES|PD_RETURNDC|PD_HIDEPRINTTOFILE,NULL);
    ret = AfxGetApp()->DoPrintDialog(&pd);
    if(ret == IDOK)
    {
    AfxGetApp()->GetPrinterDeviceDefaults(&PRT_DLG);
    lpDevMode = (LPDEVMODE)::GlobalLock(PRT_DLG.hDevMode);

    if(lpDevMode != NULL)
    {
    CString str2;
    m_paperHeight.cm = (float)(lpDevMode->dmPaperLength/100) ;
    m_paperHeight.inches = (lpDevMode->dmPaperLength/100) * (float)0.39;
    m_paperWidth.cm =(float) (lpDevMode->dmPaperWidth/100) ;
    m_paperWidth.inches = (lpDevMode->dmPaperWidth/100) * (float)0.39;
    CEdit * ptre=(CEdit *) GetDlgItem(IDC_EDIT14);
    ptre->SetWindowText(( char*) lpDevMode->dmFormName);
    initWidthHeightofPaper();
    ::GlobalUnlock(PRT_DLG.hDevMode);
    }
    }
    //--------------------------------------------

    GeneralGreat, but one more questionsussLubin25 Oct '02 - 15:33 
    I have a multi-document application linking a doc/view DLL. The code works great except the OnLandscape() function.
     
    What I want to do is to preview doc in the DLL. In the code you provided, we need get an object of the CMultiPagePrintApp by using AfxGetApp() in OnLandscape(). I could not figure out how to do this in the DLL. When linking the DLL, SetPrintOrientation(int) could not be resolved. Hope you understand my question and kindly provide a solution.
     
    Thanks a lot.
     
    LubinEek! | :eek:
    GeneralRe: Great, but one more questionmemberRoger Allen21 May '04 - 1:58 
    I recently cam back to this and found this solution for those of you who need to do this:
     
    bool CMultiPagePreviewView::SetPrintOrientation(int mode) const
    {
        PRINTDLG	pd;
     
        pd.lStructSize = (DWORD)sizeof(PRINTDLG);
        BOOL bRet = AfxGetApp()->GetPrinterDeviceDefaults(&pd);
     
        if (bRet)
        {
            switch (mode)
    	        {
    	        case DMORIENT_PORTRAIT :
    			        {
    			        // portrait mode
    			        LPDEVMODE pDevMode = (LPDEVMODE)::GlobalLock(pd.hDevMode) ;
    			        // set orientation to portrait
    			        pDevMode->dmOrientation = DMORIENT_PORTRAIT ;
    			        ::GlobalUnlock(pd.hDevMode) ;
    			        }
    			        break ;
    	        case DMORIENT_LANDSCAPE :
    			        {
    			        // landscape mode
    			        LPDEVMODE pDevMode = (LPDEVMODE)::GlobalLock(pd.hDevMode) ;
    			        // set orientation to landscape
    			        pDevMode->dmOrientation = DMORIENT_LANDSCAPE ;
    			        ::GlobalUnlock(pd.hDevMode) ;
    			        }
    			        break ;
    	        default :	
    			        ASSERT(FALSE) ;		// invalid parameter
    			        return false ;
    	        }
            return true ;
        }
        return false;
    }
    
    This avoids all the requirement of having functions as part of the CWinApp derived class
     
    Roger Allen - Sonork 100.10016
    Strong Sad: I am sad I am flying
    Who is your favorite Strong?

    GeneralBug...memberMulot16 Sep '02 - 10:36 
    You must override the OnDraw function from the CMultiPagePreviewView class and there should be this code into it to avoid the blank page at the end of the document:
     

    //Set the number of displayed pages to avoid MFC to display a blank page at the end...
    int OldnPages=m_nPages;
    m_nPages=min(m_nPages,max(1,m_pPreviewInfo->GetMaxPage()-m_nCurrentPage+1));

    CPreviewView::OnDraw(pDC);

    m_nPages=OldnPages;
     

     
    Mulot Wink | ;)
    GeneralTool bar buttons are slow?!memberMulot16 Sep '02 - 10:27 
    I just integrated this preview class into my app and the toolbar buttons are quite a bit slower than the standard MFC toolbar button were... I did not investigated a lot around this but if someone know about this please post!
     
    Oops, almost forgot to add that the keyboard equivalent are still quick!
     
    thanksConfused | :confused:
     
    Mulot Wink | ;)
    GeneralCrashesmemberBob Eastman13 May '02 - 11:14 
    I tried this class in an rtf application. When I get to:
     
    if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
    CRect(0,0,0,0), pParent, AFX_IDW_PANE_FIRST, &context))
     
    The app crashes. Any suggestions as to what might be wrong would be appreciated.

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Permalink | Advertise | Privacy | Mobile
    Web02 | 2.6.130523.1 | Last Updated 28 Apr 2002
    Article Copyright 2002 by Roger Allen
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid