none
Problem bei "Seite einrichten" in CPageSetupDialog RRS feed

  • Frage

  • Hallo Experten,

    zum Einstellen des Papierformats und der Seitenränder benutze ich CPageSetupDialog und habe mich dabei an dem Code orientiert, der im WordPad Beispiel zu finden ist. So sieht er bei mir aus:

    void CMyApp::OnPageSetup()
    {
        CPageSetupDialog dlg;
        PAGESETUPDLG& psd = dlg.m_psd;
        LPDEVMODE pDevMode = NULL;

        psd.Flags |= PSD_MARGINS | PSD_INHUNDREDTHSOFMILLIMETERS;
        psd.rtMargin.bottom = m_Profile.PageProperties.nBottomMargin * 10;
        psd.rtMargin.left = m_Profile.PageProperties.nLeftMargin * 10;
        psd.rtMargin.right = m_Profile.PageProperties.nRightMargin * 10;
        psd.rtMargin.top = m_Profile.PageProperties.nTopMargin * 10;
        psd.ptPaperSize.x = m_Profile.PageProperties.nWidth * 10;
        psd.ptPaperSize.y = m_Profile.PageProperties.nHeight * 10;

        // get the current device from the app
        PRINTDLG pd;
        memset(&pd, 0, sizeof(pd));
        pd.lStructSize = (DWORD)sizeof(PRINTDLG);
        pd.hDevNames = NULL;
        pd.hDevMode = NULL;

        GetPrinterDeviceDefaults(&pd);

        psd.hDevNames = pd.hDevNames;
        psd.hDevMode = pd.hDevMode;
        pDevMode = (LPDEVMODE)::GlobalLock(psd.hDevMode);
        if (pDevMode != NULL)
        {
            pDevMode->dmOrientation = m_Profile.PageProperties.nOrientation;
            pDevMode->dmPaperSize = m_Profile.PageProperties.nPaperSize;
            ::GlobalUnlock(pDevMode);
        }

        if (dlg.DoModal() == IDOK)
        {
            m_Profile.PageProperties.nBottomMargin = psd.rtMargin.bottom / 10;
            m_Profile.PageProperties.nLeftMargin = psd.rtMargin.left / 10;
            m_Profile.PageProperties.nRightMargin = psd.rtMargin.right / 10;
            m_Profile.PageProperties.nTopMargin = psd.rtMargin.top / 10;
            m_Profile.PageProperties.nWidth = psd.ptPaperSize.x / 10;
            m_Profile.PageProperties.nHeight = psd.ptPaperSize.y / 10;
            SelectPrinter(psd.hDevNames, psd.hDevMode);
            LPDEVMODE pDevMode = dlg.GetDevMode();
            if (pDevMode != NULL)
            {
                // Change printer settings in here.
                m_Profile.PageProperties.nOrientation = pDevMode->dmOrientation;
                m_Profile.PageProperties.nPaperSize = pDevMode->dmPaperSize;
                ::GlobalUnlock(pDevMode);
            }
        }
    }

     

    In der Funktion SelectPrinter(psd.hDevNames, psd.hDevMode) bekomme ich eine Assertion, weil hDevNames mit ::GlobelFree(...) nicht freigegeben werden kann. Warum funktioniert das im Beispiel und bei mir nicht?


    Danke für Tipps und Hilfe

    Michael

    Montag, 1. August 2011 09:33

Antworten

  • OK. Erkläre ich es anders.

    PageSetupDlg verändert die Handles, d.h. gibt diese frei.
    Die Doku sagt dazu:
    Note that the values of hDevMode and hDevNames in PAGESETUPDLG may
    change when they are passed into PageSetupDlg. This is because these members are filled on both input and output.

    D.h. Dein Aufruf der Funktion löscht die alten Handles. Damit die MFC dies nicht selber auch noch macht musst Du:

    SelectPrinter(psd.hDevNames, psd.hDevMode,FALSE);

    aufrufen.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 1. August 2011 11:35
    Moderator

Alle Antworten

  • > In der Funktion SelectPrinter(psd.hDevNames, psd.hDevMode) bekomme ich eine Assertion, weil hDevNames mit ::GlobelFree(...) nicht freigegeben werden kann. Warum funktioniert das im Beispiel und bei mir nicht?

    hDevNames und hDevMode werden von der MFC intern selbst in CWinApp verwaltet.

    Du darfst psd.hDevNames und psd.hDevMode IMHO nicht vorbelegen. Das macht das System selbst...


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 1. August 2011 09:55
    Moderator
  • Und wie bekomme ich CPageSetupDialog dazu, meine Seitenorientierung und mein Papierformat anzuzeigen?
    Montag, 1. August 2011 10:05
  • OK. Erkläre ich es anders.

    PageSetupDlg verändert die Handles, d.h. gibt diese frei.
    Die Doku sagt dazu:
    Note that the values of hDevMode and hDevNames in PAGESETUPDLG may
    change when they are passed into PageSetupDlg. This is because these members are filled on both input and output.

    D.h. Dein Aufruf der Funktion löscht die alten Handles. Damit die MFC dies nicht selber auch noch macht musst Du:

    SelectPrinter(psd.hDevNames, psd.hDevMode,FALSE);

    aufrufen.


    Martin Richter -- MVP for VC++ [Germany] -- http://blog.m-ri.de
    Montag, 1. August 2011 11:35
    Moderator
  • Danke, das hat geholfen!
    Dienstag, 2. August 2011 13:19