C3Lab研究室

Back to Title Page(OpenLab)タイトルページへ戻る

最終更新日: 1998年 12月 05日 土曜日

 

ダイアログボックスからデフォルトプリンターで印刷を行う

 今回は、MFCのアプリケーションウイザードを使用してダイアログボックスアプリケーション 作成の場合、MFCでの印刷が直接インプリメントできない(というより必要がないからダイアログ ボックスタイプのアプリケーションにすることが多い)ため、レポートの一部でも印刷しようとすると 結構苦労してしまいます。
 とくに印刷用紙設定等はコモンダイアログを通常使用するのですが、そのデバイスをアクセスする データの作成などがわからない方も多いようなので、一括してプリンターをサポートするオプション で作成しなかったアプリケーションに印刷機能をデフォルトのプリンターを使用して印刷する簡単な クラスを公開いたします。
 結構、必要にせまられて急いで作成したのですが結構使えるようなので個人用にカスタマイズする なりして試してみてください。
 基本的なところはサンプルソースをみてもらえばわかると思います。プリンターの動作を もっと詳しく制御したい方はソースを解析してみてください。基本的に行っていることは、 MFCが行っていることの簡略版で、プリンターデバイスをCDCクラスに割り当てて使用 しているだけです。
 初期化&終了の特殊な所はサンプルにプログラムで表して有りますので参考にしてください。
 このクラス自体はMFCのCDCから派生していますので、割り当てたクラスに対して直接描画メ ソッドを使用してプリンターへの印字指示にすることができます。

 プログラムの動作構造

 プログラムの動作は2段階に別れていて、StartPrinting(LPSTR); 関数より前はプリンターを制御する部分で、この段階で用紙設定等のプリンターの基本制御について 設定します。それ以降は実際の印刷を行う部分で、StartPage()・EndPage()の間で印字処理を行います。 サンプルコードではTextOutを使用して印字文字列を出力しています。
 プリンター出力のモードはデフォルトで、MM_LOMETRIC で0.1mm論理単位に指定していますので 必要に応じてデバイスモードを変更してください。

 基本的な動作で必要と思われることはその大半を裏で行っていますので、あわない部分はカスタ マイズしてください。

 このクラスを使用するサンプルコード

#include "..\CPrinterDev.h"

void CPK003Dlg::OnButton4()
{
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    CPrinterDev cpd(this);
    BOOL b = FALSE;
    {
        // 印刷準備
        short paper;
        paper=cpd.PaperSize();    // 以前の用紙サイズを保存
        cpd.PaperSize(DMPAPER_B5); // 用紙サイズを設定
        cpd.SetLandscape();    // 横書き
        //
        cpd.StartPrinting("Windows"); // print start

        cpd.StartPage();
        cpd.TextOut(0,0,"Sample Text",strlen("Sample Text"));
        cpd.EndPage();
    }
}

 CPrinterDev  クラスの全体リスト


/*
*    CPrinterDev Printer device control class for VC++6.0 & MFC
*
*        Copyright (c) Kitaro , Yukio Hirohata 1998
*
* Revision 1.0.0 Update 1998.12.05
*/

#ifndef __KITARO_CPRINTERDEV__
#define __KITARO_CPRINTERDEV__

/**************************************
// 印刷解像度設定用定数リスト
    DMRES_HIGH
    DMRES_MEDIUM
    DMRES_LOW
    DMRES_DRAFT
*/

/**************************************
// 用紙サイズ設定定数リスト
    DMPAPER_A4                 A4 シート、210 × 297 mm
    DMPAPER_A3                 A3 シート、297 × 420 mm
    DMPAPER_A4SMALL             A4 small シート、210 × 297 mm
    DMPAPER_A5                 A5 シート、148 × 210 mm
    DMPAPER_B4                 B4 シート、250 × 354 mm
    DMPAPER_B5                 B5 シート、182 × 257 mm
    DMPAPER_QUARTO             Quarto、215 × 275 mm
    DMPAPER_ENV_DL             DL Envelope、110 × 220 mm
    DMPAPER_ENV_C5             C5 Envelope、162 × 229 mm
    DMPAPER_ENV_C3             C3 Envelope、324 × 458 mm
    DMPAPER_ENV_C4             C4 Envelope、229 × 324 mm
    DMPAPER_ENV_C6             C6 Envelope、114 × 162 mm
    DMPAPER_ENV_C65             C65 Envelope、114 × 229 mm
    DMPAPER_ENV_B4             B4 Envelope、250 × 353 mm
    DMPAPER_ENV_B5             B5 Envelope、176 × 250 mm
    DMPAPER_ENV_B6             B6 Envelope、176 × 125 mm
    DMPAPER_ENV_ITALY        Italy Envelope、110 × 230 mm

    DMPAPER_LETTER             Letter、8 1/2 × 11 インチ
    DMPAPER_LEGAL             Legal、8 1/2 × 14 インチ
    DMPAPER_CSHEET             C シート、17 × 22 インチ
    DMPAPER_DSHEET             D シート、22 × 34 インチ
    DMPAPER_ESHEET             E シート、34 × 44 インチ
    DMPAPER_LETTERSMALL        Letter Small、8 1/2 × 11 インチ
    DMPAPER_TABLOID             Tabloid、11 × 17 インチ
    DMPAPER_LEDGER             Ledger、17 × 11 インチ
    DMPAPER_STATEMENT        Statement、5 1/2 × 8 1/2 インチ
    DMPAPER_EXECUTIVE        Executive、7 1/4 × 10 1/2 インチ
    DMPAPER_FOLIO             Folio、8 1/2 × 13 インチ
    DMPAPER_10X14             10 × 14 インチ シート
    DMPAPER_11X17             11 × 17 インチ シート
    DMPAPER_NOTE             Note、 8 1/2 × 11 インチ
    DMPAPER_ENV_9             #9 Envelope、3 7/8 × 8 7/8 インチ
    DMPAPER_ENV_10             #10     Envelope、4 1/8 × 9 1/2 インチ
    DMPAPER_ENV_11             #11 Envelope、4 1/2 × 10 3/8 インチ
    DMPAPER_ENV_12             #12 Envelope、4 3/4 × 11 インチ
    DMPAPER_ENV_14             #14 Envelope、5 × 11 1/2 インチ
    DMPAPER_ENV_MONARCH        Monarch Envelope、3 7/8 × 7 1/2 インチ
    DMPAPER_ENV_PERSONAL    6 3/4 Envelope、3 5/8 × 6 1/2 インチ
    DMPAPER_FANFOLD_US        US Std Fanfold、14 7/8 × 11 インチ
    DMPAPER_FANFOLD_STD_GERMAN German Std Fanfold、8 1/2 × 12 インチ
    DMPA PER_FANFOLD_LGL_GERMAN German Legal Fanfold、8 1/2 × 13 インチ
*/


#include <afxwin.h>

#include <winspool.h>    // OpenPrinter,ClosePrinter and others

class CPrinterDev : public CDC {
    public :
        CPrinterDev(CWnd* cwnd);
        virtual ~CPrinterDev();
    public : // 印刷準備用
        short    PaperSize(void);
        BOOL    PaperSize(short sNewSize);
        void     PaperSize(short*x,short*y);    // 1/10mm で用紙サイズ修得
        void    PaperSize(LPDWORD x,LPDWORD y);    // ピクセル単位で用紙サイズ修得
        BOOL    SetLandscape(void);
        short SetQuality(short dmPrintQuality);

    public : // 印刷
        BOOL StartPrinting(LPSTR name=NULL);
        int StartPage(void);
        int EndPage(void);
        void    Conv2Pixel     (LPDWORD x,LPDWORD y=NULL);

    private : //
        char szDevice[128];
        char szDriver[128];
        char szOutput[128];
        HANDLE         hPrinter;
        CWnd*         lpcwnd;
        LPDEVMODE    pDevMode;
        void GetDefPrinterName(void);
        BOOL GetDefaultPrinterSettings(void);
};

void    CPrinterDev::Conv2Pixel(LPDWORD x,LPDWORD y){
    CSize cs;
    cs.cx = *x;
    if(y==NULL)cs.cy = 0; else cs.cy=*y;
    int n = SetMapMode(MM_LOMETRIC); // 0.1mm
    HIMETRICtoDP (&cs);
    *x=cs.cx;
    if(y!=NULL)*y=cs.cy;
    SetMapMode(n);
}

//-------------------------------------------
// 印刷準備用
void    CPrinterDev::PaperSize(short*x,short*y){
    short ps = PaperSize();
    short INCH = 254;
    switch(ps){
    case DMPAPER_A4             : *x=2100; *y=2970; break;    //    DMPAPER_A4                 A4 シート、210 × 297 mm
    case DMPAPER_A3             : *x=2970; *y=4200; break;    //    DMPAPER_A3                 A3 シート、297 × 420 mm/
    case DMPAPER_A4SMALL    : *x=2100; *y=2970; break;     //    DMPAPER_A4SMALL             A4 small シート、210 × 297 mm
    case DMPAPER_A5             : *x=1480; *y=2100; break;    //    DMPAPER_A5                 A5 シート、148 × 210 mm
    case DMPAPER_B4             : *x=2500; *y=3540; break;    //    DMPAPER_B4                 B4 シート、250 × 354 mm
    case DMPAPER_B5             : *x=1820; *y=2570; break;    //    DMPAPER_B5                 B5 シート、182 × 257 mm
    case DMPAPER_QUARTO        : *x=2150; *y=2750; break;    //    DMPAPER_QUARTO             Quarto、215 × 275 mm
    case DMPAPER_ENV_DL        : *x=1100; *y=2200; break;    //    DMPAPER_ENV_DL             DL Envelope、110 × 220 mm
    case DMPAPER_ENV_C5        : *x=1620; *y=2290; break;    //    C5 Envelope 162 × 229 mm
    case DMPAPER_ENV_C3        : *x=3240; *y=4580; break;    //    C3 Envelope 162 × 458 mm
    case DMPAPER_ENV_C4        : *x=2290; *y=3240; break;    //    C4 Envelope、229 × 324 mm
    case DMPAPER_ENV_C6        : *x=1140; *y=1620; break;    //    C6 Envelope、114 × 162 mm
    case DMPAPER_ENV_C65    : *x=1140; *y=2290; break;     //    C65 Envelope、114 × 229 mm
    case DMPAPER_ENV_B4        : *x=2500; *y=3530; break;    //    B4 Envelope、250 × 353 mm
    case DMPAPER_ENV_B5        : *x=1760; *y=2500; break;    //    B5 Envelope、176 × 250 mm
    case DMPAPER_ENV_B6        : *x=1760; *y=1250; break;    //    B6 Envelope、176 × 125 mm
    case DMPAPER_ENV_ITALY    : *x=1100; *y=2300; break;     //    Italy Envelope、110 × 230 mm
   
    case DMPAPER_LETTER        : *x=17*INCH/2; *y=11*INCH;        break;     // Letter、8 1/2 × 11 インチ
    case DMPAPER_LEGAL        : *x=17*INCH/2; *y=14*INCH;        break;     // Legal、 8 1/2 × 14 インチ
    case DMPAPER_CSHEET        : *x=17*INCH;    *y=22*INCH;        break;     // C シート、17 × 22 インチ
    case DMPAPER_DSHEET        : *x=22*INCH;    *y=34*INCH;        break;     // D シート、22 × 34 インチ
    case DMPAPER_ESHEET        : *x=34*INCH;    *y=44*INCH;        break;     // E シート、34 × 44 インチ
    case DMPAPER_LETTERSMALL: *x=17*INCH/2;    *y=11*INCH;         break;    // Letter Small、8 1/2 × 11 インチ
    case DMPAPER_TABLOID    : *x=11*INCH;     *y=17*INCH;        break;     // Tabloid、11 × 17 インチ
    case DMPAPER_LEDGER        : *x=17*INCH;    *y=11*INCH;        break;     // Ledger、17 × 11 インチ
    case DMPAPER_STATEMENT    : *x=11*INCH/2; *y=17*INCH/2;     break;    // Statement、5 1/2 × 8 1/2 インチ
    case DMPAPER_EXECUTIVE    : *x=29*INCH/4;     *y=21*INCH/2;    break;    // Executive、7 1/4 × 10 1/2 インチ
    case DMPAPER_FOLIO        : *x=17*INCH/2; *y=13*INCH;        break;     // Folio、8 1/2 × 13 インチ
    case DMPAPER_10X14        : *x=10*INCH;    *y=14*INCH;        break;     // 10 × 14 インチ シート
    case DMPAPER_11X17        : *x=11*INCH;    *y=17*INCH;        break;     // 11 × 17 インチ シート
    case DMPAPER_NOTE        : *x=17*INCH/2;    *y=11*INCH;         break;    // Note、 8 1/2 × 11 インチ
    case DMPAPER_ENV_9        : *x=26*INCH/8; *y=71*INCH/8;    break;    // #9 Envelope、3 7/8 × 8 7/8 インチ
    case DMPAPER_ENV_10        : *x=33*INCH/8;    *y=19*INCH/2;    break;     // #10 Envelope、4 1/8 × 9 1/2 インチ
    case DMPAPER_ENV_11        : *x=9*INCH/2;    *y=83*INCH/8;    break;    // #11 Envelope、4 1/2 × 10 3/8 インチ
    case DMPAPER_ENV_12        : *x=19*INCH/4;    *y=11*INCH;         break;    // #12 Envelope、4 3/4 × 11 インチ
    case DMPAPER_ENV_14        : *x=5*INCH;    *y=23*INCH/2;    break;    // #14 Envelope、5 × 11 1/2 インチ
    case DMPAPER_ENV_MONARCH : *x=31*INCH/8; *y=15*INCH/2;     break;    // Monarch Envelope、3 7/8 × 7 1/2 インチ
    case DMPAPER_ENV_PERSONAL: *x=29*INCH/8; *y=13*INCH/2;     break;    // 6 3/4 Envelope、3 5/8 × 6 1/2 インチ
    case DMPAPER_FANFOLD_US    : *x=120*INCH/8; *y=11*INCH;     break; // US Std Fanfold、14 7/8 × 11 インチ
    case DMPAPER_FANFOLD_STD_GERMAN    : *x=17*INCH/2; *y=12*INCH;    break;    //German Std Fanfold、8 1/2 × 12 インチ
    case DMPAPER_FANFOLD_LGL_GERMAN : *x=17*INCH/2; *y=13*INCH;     break;    //German Legal Fanfold、8 1/2 × 13 インチ

    default : *x=-1; *y=-1;
    }
};
short CPrinterDev::SetQuality(short dmPrintQuality){
    ASSERT(pDevMode);
    short s = pDevMode->dmPrintQuality;
    if(!pDevMode->dmFields&DM_ORIENTATION)return FALSE;
    if(!OpenPrinter(szDevice,&hPrinter,NULL))return FALSE;
    pDevMode->dmPrintQuality = dmPrintQuality;
    if(DocumentProperties(lpcwnd->m_hWnd,hPrinter,szDevice,pDevMode,pDevMode,DM_IN_BUFFER | DM_OUT_BUFFER)!=IDOK)
        {pDevMode->dmPrintQuality= s; return FALSE;}
    ClosePrinter(hPrinter);
    return TRUE;
}


short    CPrinterDev::PaperSize(void){return(pDevMode->dmPaperSize);};
BOOL    CPrinterDev::PaperSize(short sNewSize){
    ASSERT(pDevMode);
    short s = pDevMode->dmPaperSize;
    if(!pDevMode->dmFields&DM_ORIENTATION)return FALSE;
    if(!OpenPrinter(szDevice,&hPrinter,NULL))return FALSE;
    pDevMode->dmPaperSize = sNewSize;
    if(DocumentProperties(lpcwnd->m_hWnd,hPrinter,szDevice,pDevMode,pDevMode,DM_IN_BUFFER | DM_OUT_BUFFER)!=IDOK)
        {pDevMode->dmPaperSize = s; return FALSE;}
    ClosePrinter(hPrinter);
    return TRUE;
};

BOOL CPrinterDev::SetLandscape(void){
    if(!pDevMode->dmFields&DM_ORIENTATION)return FALSE;
    if(!OpenPrinter(szDevice,&hPrinter,NULL))return FALSE;
    pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
    DocumentProperties(lpcwnd->m_hWnd,hPrinter,szDevice,pDevMode,pDevMode,DM_IN_BUFFER | DM_OUT_BUFFER);
    ClosePrinter(hPrinter);
    return TRUE;
};
//-------------------------------------------
int CPrinterDev::StartPage(void){
    return(::StartPage(m_hDC));
};

int CPrinterDev::EndPage(void){
    return(::EndPage(m_hDC));
};
BOOL CPrinterDev::StartPrinting(LPSTR name){
    if((CreateDC("WINSPOOL",szDevice,NULL,pDevMode))==FALSE)return FALSE;
    SetMapMode(MM_LOMETRIC); // 0.1mm
    DOCINFO docinfo;
    docinfo.cbSize = sizeof(DOCINFO);
    docinfo.lpszDocName = name;
    docinfo.lpszOutput = NULL;
    docinfo.lpszDatatype = NULL;
    docinfo.fwType = 0;
    StartDoc(&docinfo);
    return TRUE;
};

CPrinterDev::CPrinterDev(CWnd*cwnd){
    lpcwnd        = cwnd;
    pDevMode    = NULL;
    hPrinter    = NULL;
    GetDefPrinterName();
    // Printer device initialize
    if(!OpenPrinter(szDevice,&hPrinter,NULL))return;
    GetDefaultPrinterSettings();
};
CPrinterDev::~CPrinterDev(){
    if(pDevMode!=NULL) free(pDevMode); pDevMode=NULL;
    if(m_hDC!=NULL){
        EndDoc();
        DeleteDC();
    }
    if(hPrinter!=NULL)ClosePrinter(hPrinter);
};
//------------------------------------------
// Private Functions
BOOL CPrinterDev::GetDefaultPrinterSettings(void){
    DWORD        dwNeeded;
    dwNeeded = DocumentProperties(lpcwnd->m_hWnd,hPrinter,szDevice,NULL,NULL,0);
    pDevMode = (LPDEVMODE)malloc(dwNeeded);
    dwNeeded = DocumentProperties(lpcwnd->m_hWnd,hPrinter,szDevice,pDevMode,NULL,DM_OUT_BUFFER);
    return TRUE;
}
void CPrinterDev::GetDefPrinterName(void){
    static char szPrinter[64];
    char *sDevice, *sDriver, *sOutput;
    strcpy(szDevice,"");
    strcpy(szDriver,"");
    strcpy(szOutput,"");
    GetProfileString("windows", "device", "", szPrinter, 64);
    if ((sDevice = strtok(szPrinter, "," ))
            && (sDriver = strtok(NULL, ", "))
            && (sOutput = strtok(NULL, ", "))){
        strcpy(szDevice,sDevice);
        strcpy(szDriver,sDriver);
        strcpy(szOutput,sOutput);
    }
};
#endif

Copyright (C) Kitaro 1998