printdlg.cpp

来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,043 行 · 第 1/3 页

CPP
1,043
字号
/////////////////////////////////////////////////////////////////////////////
// Name:        printdlg.cpp
// Purpose:     wxPrintDialog, wxPageSetupDialog
// Author:      Julian Smart
// Modified by:
// Created:     04/01/98
// RCS-ID:      $Id: printdlg.cpp,v 1.33.2.1 2006/01/17 09:52:53 JS Exp $
// Copyright:   (c) Julian Smart
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// ===========================================================================
// declarations
// ===========================================================================

// ---------------------------------------------------------------------------
// headers
// ---------------------------------------------------------------------------

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
    #pragma implementation "printdlg.h"
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

// Don't use the Windows print dialog if we're in wxUniv mode and using
// the PostScript architecture
#if wxUSE_PRINTING_ARCHITECTURE && (!defined(__WXUNIVERSAL__) || !wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW)

#ifndef WX_PRECOMP
    #include "wx/app.h"
#endif

#include "wx/cmndata.h"
#include "wx/printdlg.h"
#include "wx/msw/printdlg.h"
#include "wx/dcprint.h"
#include "wx/paper.h"

#include <stdlib.h>

#include "wx/msw/wrapcdlg.h"

#ifndef __WIN32__
    #include <print.h>
#endif

//----------------------------------------------------------------------------
// wxWindowsPrintNativeData
//----------------------------------------------------------------------------

#ifdef __WXDEBUG__
static wxString wxGetPrintDlgError()
{
    DWORD err = CommDlgExtendedError();
    wxString msg = wxT("Unknown");
    switch (err)
    {
        case CDERR_FINDRESFAILURE: msg = wxT("CDERR_FINDRESFAILURE"); break;
        case CDERR_INITIALIZATION: msg = wxT("CDERR_INITIALIZATION"); break;
        case CDERR_LOADRESFAILURE: msg = wxT("CDERR_LOADRESFAILURE"); break;
        case CDERR_LOADSTRFAILURE: msg = wxT("CDERR_LOADSTRFAILURE"); break;
        case CDERR_LOCKRESFAILURE: msg = wxT("CDERR_LOCKRESFAILURE"); break;
        case CDERR_MEMALLOCFAILURE: msg = wxT("CDERR_MEMALLOCFAILURE"); break;
        case CDERR_MEMLOCKFAILURE: msg = wxT("CDERR_MEMLOCKFAILURE"); break;
        case CDERR_NOHINSTANCE: msg = wxT("CDERR_NOHINSTANCE"); break;
        case CDERR_NOHOOK: msg = wxT("CDERR_NOHOOK"); break;
        case CDERR_NOTEMPLATE: msg = wxT("CDERR_NOTEMPLATE"); break;
        case CDERR_STRUCTSIZE: msg = wxT("CDERR_STRUCTSIZE"); break;
        case  PDERR_RETDEFFAILURE: msg = wxT("PDERR_RETDEFFAILURE"); break;
        case  PDERR_PRINTERNOTFOUND: msg = wxT("PDERR_PRINTERNOTFOUND"); break;
        case  PDERR_PARSEFAILURE: msg = wxT("PDERR_PARSEFAILURE"); break;
        case  PDERR_NODEVICES: msg = wxT("PDERR_NODEVICES"); break;
        case  PDERR_NODEFAULTPRN: msg = wxT("PDERR_NODEFAULTPRN"); break;
        case  PDERR_LOADDRVFAILURE: msg = wxT("PDERR_LOADDRVFAILURE"); break;
        case  PDERR_INITFAILURE: msg = wxT("PDERR_INITFAILURE"); break;
        case  PDERR_GETDEVMODEFAIL: msg = wxT("PDERR_GETDEVMODEFAIL"); break;
        case  PDERR_DNDMMISMATCH: msg = wxT("PDERR_DNDMMISMATCH"); break;
        case  PDERR_DEFAULTDIFFERENT: msg = wxT("PDERR_DEFAULTDIFFERENT"); break;
        case  PDERR_CREATEICFAILURE: msg = wxT("PDERR_CREATEICFAILURE"); break;
        default: break;
    }
    return msg;
}
#endif

static HGLOBAL wxCreateDevNames(const wxString& driverName, const wxString& printerName, const wxString& portName)
{
    HGLOBAL hDev = NULL;
    // if (!driverName.empty() && !printerName.empty() && !portName.empty())
    if (driverName.empty() && printerName.empty() && portName.empty())
    {
    }
    else
    {
        hDev = GlobalAlloc(GPTR, 4*sizeof(WORD)+
                           ( driverName.Length() + 1 +
            printerName.Length() + 1 +
                             portName.Length()+1 ) * sizeof(wxChar) );
        LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(hDev);
        lpDev->wDriverOffset = sizeof(WORD) * 4 / sizeof(wxChar);
        wxStrcpy((wxChar*)lpDev + lpDev->wDriverOffset, driverName);

        lpDev->wDeviceOffset = (WORD)( lpDev->wDriverOffset +
                                       driverName.Length() + 1 );
        wxStrcpy((wxChar*)lpDev + lpDev->wDeviceOffset, printerName);

        lpDev->wOutputOffset = (WORD)( lpDev->wDeviceOffset +
                                       printerName.Length() + 1 );
        wxStrcpy((wxChar*)lpDev + lpDev->wOutputOffset, portName);

        lpDev->wDefault = 0;

        GlobalUnlock(hDev);
    }

    return hDev;
}

IMPLEMENT_CLASS(wxWindowsPrintNativeData, wxPrintNativeDataBase)

wxWindowsPrintNativeData::wxWindowsPrintNativeData()
{
    m_devMode = (void*) NULL;
    m_devNames = (void*) NULL;
    m_customWindowsPaperId = 0;
}

wxWindowsPrintNativeData::~wxWindowsPrintNativeData()
{
    HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
    if ( hDevMode )
        GlobalFree(hDevMode);
    HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
    if ( hDevNames )
        GlobalFree(hDevNames);
}

bool wxWindowsPrintNativeData::Ok() const
{
    return (m_devMode != NULL) ;
}

bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
{
    HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
    HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;

    if (!hDevMode)
    {
        return false;
    }
    else
    {
        LPDEVMODE devMode = (LPDEVMODE)GlobalLock(hDevMode);

        //// Orientation
        if (devMode->dmFields & DM_ORIENTATION)
            data.SetOrientation( devMode->dmOrientation );

        //// Collation
        if (devMode->dmFields & DM_COLLATE)
        {
            if (devMode->dmCollate == DMCOLLATE_TRUE)
                data.SetCollate( true );
            else
                data.SetCollate( false );
        }

        //// Number of copies
        if (devMode->dmFields & DM_COPIES)
            data.SetNoCopies( devMode->dmCopies );

        //// Bin
        if (devMode->dmFields & DM_DEFAULTSOURCE) {
            switch (devMode->dmDefaultSource) {
                case DMBIN_ONLYONE        : data.SetBin(wxPRINTBIN_ONLYONE       ); break;
                case DMBIN_LOWER          : data.SetBin(wxPRINTBIN_LOWER         ); break;
                case DMBIN_MIDDLE         : data.SetBin(wxPRINTBIN_MIDDLE        ); break;
                case DMBIN_MANUAL         : data.SetBin(wxPRINTBIN_MANUAL        ); break;
                case DMBIN_ENVELOPE       : data.SetBin(wxPRINTBIN_ENVELOPE      ); break;
                case DMBIN_ENVMANUAL      : data.SetBin(wxPRINTBIN_ENVMANUAL     ); break;
                case DMBIN_AUTO           : data.SetBin(wxPRINTBIN_AUTO          ); break;
                case DMBIN_TRACTOR        : data.SetBin(wxPRINTBIN_TRACTOR       ); break;
                case DMBIN_SMALLFMT       : data.SetBin(wxPRINTBIN_SMALLFMT      ); break;
                case DMBIN_LARGEFMT       : data.SetBin(wxPRINTBIN_LARGEFMT      ); break;
                case DMBIN_LARGECAPACITY  : data.SetBin(wxPRINTBIN_LARGECAPACITY ); break;
                case DMBIN_CASSETTE       : data.SetBin(wxPRINTBIN_CASSETTE      ); break;
                case DMBIN_FORMSOURCE     : data.SetBin(wxPRINTBIN_FORMSOURCE    ); break;
                default:
                    if (devMode->dmDefaultSource>=DMBIN_USER) {
                        data.SetBin((wxPrintBin)((devMode->dmDefaultSource)-DMBIN_USER+(int)wxPRINTBIN_USER));
                    } else {
                        data.SetBin(wxPRINTBIN_DEFAULT);
                    }
                    break;
            }
        } else {
            data.SetBin(wxPRINTBIN_DEFAULT);
        }

        //// Printer name
        if (devMode->dmDeviceName[0] != 0)
            // This syntax fixes a crash when using VS 7.1
            data.SetPrinterName( wxString(devMode->dmDeviceName, CCHDEVICENAME) );

        //// Colour
        if (devMode->dmFields & DM_COLOR)
        {
            if (devMode->dmColor == DMCOLOR_COLOR)
                data.SetColour( true );
            else
                data.SetColour( false );
        }
        else
            data.SetColour( true );

        //// Paper size

        // We don't know size of user defined paper and some buggy drivers
        // set both DM_PAPERSIZE and DM_PAPERWIDTH & DM_PAPERLENGTH. Since
        // dmPaperSize >= DMPAPER_USER wouldn't be in wxWin's database, this
        // code wouldn't set m_paperSize correctly.

        bool foundPaperSize = false;
        if ((devMode->dmFields & DM_PAPERSIZE) && (devMode->dmPaperSize < DMPAPER_USER))
        {
            if (wxThePrintPaperDatabase)
            {
                wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperTypeByPlatformId(devMode->dmPaperSize);
                if (paper)
                {
                    data.SetPaperId( paper->GetId() );
                    data.SetPaperSize( wxSize(paper->GetWidth() / 10,paper->GetHeight() / 10) );
                    m_customWindowsPaperId = 0;
                    foundPaperSize = true;
                }
            }
            else
            {
                // Shouldn't really get here
                wxFAIL_MSG(wxT("Paper database wasn't initialized in wxPrintData::ConvertFromNative."));
                data.SetPaperId( wxPAPER_NONE );
                data.SetPaperSize( wxSize(0,0) );
                m_customWindowsPaperId = 0;

                GlobalUnlock(hDevMode);
                return false;
            }
        }

        if (!foundPaperSize) {
            if ((devMode->dmFields & DM_PAPERWIDTH) && (devMode->dmFields & DM_PAPERLENGTH))
            {
                // DEVMODE is in tenths of a millimeter
                data.SetPaperSize( wxSize(devMode->dmPaperWidth / 10, devMode->dmPaperLength / 10) );
                data.SetPaperId( wxPAPER_NONE );
                m_customWindowsPaperId = devMode->dmPaperSize;
            }
            else
            {
                // Often will reach this for non-standard paper sizes (sizes which
                // wouldn't be in wxWidget's paper database). Setting
                // m_customWindowsPaperId to devMode->dmPaperSize should be enough
                // to get this paper size working.
                data.SetPaperSize( wxSize(0,0) );
                data.SetPaperId( wxPAPER_NONE );
                m_customWindowsPaperId = devMode->dmPaperSize;
            }
        }

        //// Duplex

        if (devMode->dmFields & DM_DUPLEX)
        {
            switch (devMode->dmDuplex)
            {
                case DMDUP_HORIZONTAL:   data.SetDuplex( wxDUPLEX_HORIZONTAL ); break;
                case DMDUP_VERTICAL:     data.SetDuplex( wxDUPLEX_VERTICAL ); break;
                default:
                case DMDUP_SIMPLEX:      data.SetDuplex( wxDUPLEX_SIMPLEX ); break;
            }
        }
        else
            data.SetDuplex( wxDUPLEX_SIMPLEX );

        //// Quality

        if (devMode->dmFields & DM_PRINTQUALITY)
        {
            switch (devMode->dmPrintQuality)
            {
                case DMRES_MEDIUM:  data.SetQuality( wxPRINT_QUALITY_MEDIUM ); break;
                case DMRES_LOW:     data.SetQuality( wxPRINT_QUALITY_LOW ); break;
                case DMRES_DRAFT:   data.SetQuality( wxPRINT_QUALITY_DRAFT ); break;
                case DMRES_HIGH:    data.SetQuality( wxPRINT_QUALITY_HIGH ); break;
                default:
                {
                    // TODO: if the printer fills in the resolution in DPI, how
                    // will the application know if it's high, low, draft etc.??
                    //                    wxFAIL_MSG("Warning: DM_PRINTQUALITY was not one of the standard values.");
                    data.SetQuality( devMode->dmPrintQuality );
                    break;

                }
            }
        }
        else
            data.SetQuality( wxPRINT_QUALITY_HIGH );

        if (devMode->dmDriverExtra > 0)
            data.SetPrivData( (char *)devMode+devMode->dmSize, devMode->dmDriverExtra );
        else
            data.SetPrivData( NULL, 0 );

        GlobalUnlock(hDevMode);
    }

    if (hDevNames)
    {
        LPDEVNAMES lpDevNames = (LPDEVNAMES)GlobalLock(hDevNames);
        if (lpDevNames)
        {
            // TODO: Unicode-ification

            // Get the port name
            // port is obsolete in WIN32
            // m_printData.SetPortName((LPSTR)lpDevNames + lpDevNames->wDriverOffset);

            // Get the printer name
            wxString printerName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;

            // Not sure if we should check for this mismatch
//            wxASSERT_MSG( (m_printerName.empty() || (devName == m_printerName)), "Printer name obtained from DEVMODE and DEVNAMES were different!");

            if (!printerName.empty())
                data.SetPrinterName( printerName );

            GlobalUnlock(hDevNames);
        }
    }

    return true;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?