C3Lab研究室

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

最終更新日: 1998年 12月 07日 月曜日

 

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

・今回は4本のプログラムリストになっていますので必要なかたはダウンロードしてください。

今回の拡張は以下の用になります

 印刷にプレヴュー機能を追加する
サンプルとしてオーバーラップウィンドゥを生成しそのなかでプレヴューを行う
ダイアログボックスではプレビュー表示を行うための表示エリアの確保が難しいので専用の ウィンドゥを開き、その中で表示を行う。
 画面表示用CDC(CPaintDC)クラスをアタッチしプリンター出力との共通化
 画面出力とプリンター出力の切り替えを、CDCのアタッチかデフォルトプリンター のオープンかで切り替えることで出力部分のプログラムを共通にする。
 表示のスケーリングオプションを追加し表示サイズの調整を可能にする
 表示スケーリングを調整することで拡大縮小表示を行う事を可能にする。
 表示フォントの変更方法の提示
 スケーリングに合わせたサイズのフォントや日本語フォントの指定などを行えるようにし 拡大縮小時などの表示や印刷のずれを補正できるようにする。

 

 今回の拡張でもう少し幅広い使い方ができるように改良してみました。基本部分はほぼ 同じなので全体と同様にプリンターへの出力のみにも使用できますが、印刷プリビューを可能 にするため、オーバーラップウィンドゥを一度生成し、その表示メッセージ部分で印刷か表示 かを行う部分を定義してみました。
 こうした部分はここのアプリケーションによってユーザーインターフェースが異なるため 一貫したものを作成するのは難しいので参考までにどのようにして制御するかを示す程度に しておきます。
 もっと、使いやすく汎用性のあるprintingクラスの作成も可能でしょうが、とりあえず印刷を 行う部分と画面表示を行う部分のCDCクラスによる共通化に重点をおいて作成してみました。
実際に使用する用紙に合わせたイメージ表示や、フォントの調整、スケーリングによる拡大 縮小表示等を拡張するのに必要な部分を追加して有りますので、個人用にカスタマイズすれば 結構使えると思います。

 

 

Printing.h で定義したプリビュークラスを生成する部分

{
    Printing printwnd;
    printwnd.Initialize(this);
    printwnd.ShowWindow(SW_NORMAL);
}

Printing.h サンプルプリヴュー用クラス定義部分(CWndから派生)

 これ以降の4本のプログラムリストはアーカイブしてまとめて有りますので必要なかたは ダウンロードしてください。

 

#if !defined(AFX_PRINTING_H__17DD5621_8C66_11D2_A7A9_0090CCA04D48__INCLUDED_)
#define AFX_PRINTING_H__17DD5621_8C66_11D2_A7A9_0090CCA04D48__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Printing.h : ヘッダー ファイル
//

/////////////////////////////////////////////////////////////////////////////
// Printing ウィンドウ
#include "..\CPrinterDev.h"

class Printing : public CWnd
{
// コンストラクション
public:
    Printing();
    void Initialize(CWnd *cwnd);
public:
    void OnPaintArea(CDC &dc,RECT &rc);
public:
    CPrinterDev* cpd;    // this
    CFont *cfont;
    LOGFONT pLogFont;
    BOOL    bPreView;
    TEXTMETRIC tm;

public:
    BOOL    Preview(void);
    BOOL    Preview(BOOL bPreview);

// アトリビュート
public:

// オペレーション
public:

// オーバーライド
    // ClassWizard は仮想関数のオーバーライドを生成します。

    //{{AFX_VIRTUAL(Printing)
    //}}AFX_VIRTUAL

// インプリメンテーション
public:
    virtual ~Printing();

    // 生成されたメッセージ マップ関数
protected:
    //{{AFX_MSG(Printing)
    afx_msg void OnPaint();
    afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
    afx_msg void OnMove(int x, int y);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。

#endif // !defined(AFX_PRINTING_H__17DD5621_8C66_11D2_A7A9_0090CCA04D48__INCLUDED_)

Printing.CPP サンプルプリヴュー用クラス(CWndから派生)


// Printing.cpp : インプリメンテーション ファイル
//

#include "Printing.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Printing

Printing::Printing()
{
    cpd = new CPrinterDev;
    cpd->PaperSize(DMPAPER_A4); // 用紙サイズを設定
    cpd->SetLandscape();    // 横書き
    cfont = new CFont;
    bPreView=FALSE;
}

Printing::~Printing()
{
    delete cfont;
    delete(cpd);
}


BEGIN_MESSAGE_MAP(Printing, CWnd)
    //{{AFX_MSG_MAP(Printing)
    ON_WM_PAINT()
    ON_WM_ACTIVATE()
    ON_WM_MOVE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Printing メッセージ ハンドラ
void Printing::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
    CWnd::OnActivate(nState, pWndOther, bMinimized);
   
    // TODO: この位置にメッセージ ハンドラ用のコードを追加してください
    if(nState==WA_INACTIVE){
        ShowWindow(SW_HIDE);
    }
}
void Printing::OnMove(int x, int y)
{
    CWnd::OnMove(x, y);
   
    // TODO: この位置にメッセージ ハンドラ用のコードを追加してください
    InvalidateRect(NULL,TRUE);
}

/////////////////////////////////////////////////////////////////////////////
// Printing メッセージ ハンドラ


void Printing::Initialize(CWnd*cwnd){
    RECT rect;
    rect.top = 0;
    rect.bottom = 300;
    rect.left = 0;
    rect.right = 600;
    UINT nClassStyle;
    nClassStyle = CS_CLASSDC;
    CreateEx(WS_EX_CLIENTEDGE,
        AfxRegisterWndClass(nClassStyle),
        "Print Window",
        WS_OVERLAPPED | WS_THICKFRAME | WS_CAPTION ,
        rect,this,0);
}
BOOL Printing::Preview(void){return(bPreView);};
BOOL Printing::Preview(BOOL bPreview){
    BOOL b = bPreView; bPreView=bPreview; return b;
};

void Printing::OnPaint()
{
    CPaintDC dc(this); // 描画用のデバイス コンテキスト
   
    // TODO: この位置にメッセージ ハンドラ用のコードを追加してください
    RECT rc;
    CSize csize;
    ZeroMemory(&rc,sizeof(rc));
    cpd->SetScale(50);
    cpd->PaperSize((DWORD*)&csize.cx,(DWORD*)&csize.cy); // w/Scaling
    dc.SetMapMode(MM_TEXT);
    csize.cx*=10; // convert to LOMETRIC to HIMETRIC
    csize.cy*=10; // convert to LOMETRIC to HIMETRIC
    //-----------------------------------------------
    Preview(TRUE); // if TRUE, output to Display
//    Preview(FALSE); // if TRUE, output to Display この部分でプリビューと印刷を分けています
    //-------------
    dc.HIMETRICtoLP(&csize);
    CBrush cb;
    GetWindowRect(&rc);
    rc.top=0; rc.left=0;
    cb.CreateSolidBrush(COLORREF(0x00808080));
    dc.FillRect(&rc,&cb);
    rc.left = 200;
    rc.top = 10;
    rc.right = csize.cx + rc.left;
    rc.bottom = csize.cy + rc.top;
    cb.DeleteObject();
    cb.CreateSolidBrush(COLORREF(0x00FFFFFF));
    dc.FillRect(&rc,&cb);
    cb.DeleteObject();
    {
        cfont->CreatePointFont(120,"MS 明朝",NULL);
        dc.SelectObject(cfont);
        dc.TextOut(10,10,CString("プリンター情報"));
        cfont->DeleteObject();
    }
    //---------------------------------------
    // 印刷 OR 画面出力
    {
        DWORD dwfontsize;
        int         scale;
        dwfontsize = (200 * cpd->GetScale()) / 100;
        if(bPreView==TRUE)    {
            cpd->AttachDC(dc);
            cfont->CreatePointFont(dwfontsize ,"MS 明朝",NULL);
        }else{
            scale = cpd->SetScale(100);
            cpd->StartPrinting("Windows");
            cpd->SelectObject(cfont);
            cpd->StartPage();
            cfont->CreatePointFont(dwfontsize*4 ,"MS 明朝",NULL);
        }
        short s = cpd->SetMapMode(MM_TEXT);
        cpd->SelectObject    (cfont);
        cpd->SetMapMode         (s);
        cfont->GetLogFont     (&pLogFont);
        cpd->GetTextMetrics(&tm);
        if( Preview()==FALSE){
            rc.bottom -= rc.top; rc.top=0;
            rc.right -= rc.left; rc.left=0;
            tm.tmHeight=0-tm.tmHeight;
        }else{
            rc.top         +=(20*cpd->GetScale())/100;
            rc.left         +=(20*cpd->GetScale())/100;
            rc.right     -=(20*cpd->GetScale())/100;
            rc.bottom     -=(20*cpd->GetScale())/100;
        }
        OnPaintArea(dc,rc);
        if(bPreView==TRUE) cpd->Detach();
        else{
            cpd->EndPage();
            cpd->EndDoc();
            cpd->DeleteDC();
            cpd->SetScale(scale);
        }
        cfont->DeleteObject();
    }
}
void Printing::OnPaintArea(CDC &dc,RECT &rc){
    CString s="Sample Text";
    //------------------------------------------
    cpd->TextOut(rc.left,rc.top,s);
    s += " (2)";
    cpd->TextOut(rc.left,rc.top+tm.tmHeight,s);
    //------------------------------------------
};


CPrinterDev.h

/*
*    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=NULL);
        virtual ~CPrinterDev();

    public :
        BOOL AttachDC(CDC& cpdc);

    //-----------------------------------
    // 印刷準備用
    public : // 状態修得
        short    PaperSize     (void);
        void    PaperSize     (short*x,short*y);    // 1/10mm で用紙サイズ修得
        void    PaperSize     (LPDWORD x,LPDWORD y);    // ピクセル単位で用紙サイズ修得
        BOOL    IsLandscape     (void);
        short    GetScale     (void);
        void    PaperType     (CString &csPaperTypeName);

    public : // 状態設定
        BOOL    PaperSize     (short sNewSize);
        BOOL    SetLandscape(void);
        short SetQuality    (short dmPrintQuality);
        short    SetScale     (short dmScale);

    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;
        HWND         hWnd;
        LPDEVMODE    pDevMode;
        BOOL         bOut2DC;    // Outout DC flg
        short         sScale;
        void GetDefPrinterName(void);
        BOOL GetDefaultPrinterSettings(void);
};

#endif

CPrinterDev.CPP



#include "CPrinterDev.h"


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){
    DWORD sx,sy;
    PaperSize(&sx,&sy);
    *x = (short)sx;
    *y = (short)sy;
};
void CPrinterDev::PaperType(CString &pn){
    switch(PaperSize()){
    case DMPAPER_A4                     : pn="A4 : 210 × 297 mm"; break;
    case DMPAPER_A3                     : pn="A3 : 297 × 420 mm"; break;
    case DMPAPER_A4SMALL             : pn="A4 small : 210 × 297 mm"; break;
    case DMPAPER_A5                     : pn="A5 : 148 × 210 mm"; break;
    case DMPAPER_B4                     : pn="B4 : 250 × 354 mm"; break;
    case DMPAPER_B5                     : pn="B5 : 182 × 257 mm"; break;
    case DMPAPER_QUARTO                 : pn="Quarto : 215 × 275 mm"; break;
    case DMPAPER_ENV_DL                 : pn="DL Enve : 110 × 220 mm"; break;
    case DMPAPER_ENV_C5                 : pn="C5 Enve : 162 × 229 mm"; break;
    case DMPAPER_ENV_C3                 : pn="C3 Enve : 162 × 458 mm"; break;
    case DMPAPER_ENV_C4                 : pn="C4 Enve : 229 × 324 mm"; break;
    case DMPAPER_ENV_C6                 : pn="C6 Enve : 114 × 162 mm"; break;
    case DMPAPER_ENV_C65             : pn="C65 Enve : 114 × 229 mm"; break;
    case DMPAPER_ENV_B4                 : pn="B4 Enve : 250 × 353 mm"; break;
    case DMPAPER_ENV_B5                 : pn="B5 Enve : 176 × 250 mm"; break;
    case DMPAPER_ENV_B6                 : pn="B6 Enve : 176 × 125 mm"; break;
    case DMPAPER_ENV_ITALY             : pn="Italy Enve : 110 × 230 mm"; break;
    case DMPAPER_LETTER                 : pn="Letter : 8 1/2 × 11 Inch"; break;
    case DMPAPER_LEGAL                 : pn="Legal : 8 1/2 × 14 Inch"; break;
    case DMPAPER_CSHEET                 : pn="C シート : 17 × 22 Inch"; break;
    case DMPAPER_DSHEET                 : pn="D シート : 22 × 34 Inch"; break;
    case DMPAPER_ESHEET                 : pn="E シート : 34 × 44 Inch"; break;
    case DMPAPER_LETTERSMALL        : pn="Letter Small : 8 1/2 × 11 Inch"; break;
    case DMPAPER_TABLOID             : pn="Tabloid : 11 × 17 Inch"; break;
    case DMPAPER_LEDGER                 : pn="Ledger : 17 × 11 Inch"; break;
    case DMPAPER_STATEMENT             : pn="Statement : 5 1/2 × 8 1/2 Inch"; break;
    case DMPAPER_EXECUTIVE             : pn="Executive : 7 1/4 × 10 1/2 Inch"; break;
    case DMPAPER_FOLIO                 : pn="Folio : 8 1/2 × 13 Inch"; break;
    case DMPAPER_10X14                 : pn="10 × 14 Inch シート"; break;
    case DMPAPER_11X17                 : pn="11 × 17 Inch シート"; break;
    case DMPAPER_NOTE                 : pn="Note : 8 1/2 × 11 Inch"; break;
    case DMPAPER_ENV_9                 : pn="#9 Envelope : 3 7/8 × 8 7/8 Inch"; break;
    case DMPAPER_ENV_10                 : pn="#10 Envelope : 4 1/8 × 9 1/2 Inch"; break;
    case DMPAPER_ENV_11                 : pn="#11 Envelope : 4 1/2 × 10 3/8 Inch"; break;
    case DMPAPER_ENV_12                 : pn="#12 Envelope : 4 3/4 × 11 Inch"; break;
    case DMPAPER_ENV_14                 : pn="#14 Envelope : 5 × 11 1/2 Inch"; break;
    case DMPAPER_ENV_MONARCH        : pn="Monarch Envelope : 3 7/8 × 7 1/2 Inch"; break;
    case DMPAPER_ENV_PERSONAL        : pn="6 3/4 Envelope : 3 5/8 × 6 1/2 Inch"; break;
    case DMPAPER_FANFOLD_US             : pn="US Std Fanfold : 14 7/8 × 11 Inch"; break;
    case DMPAPER_FANFOLD_STD_GERMAN    : pn="German Std Fanfold : 8 1/2 × 12 Inch"; break;
    case DMPAPER_FANFOLD_LGL_GERMAN : pn="German Legal Fanfold : 8 1/2 × 13 Inch"; break;
    default : pn="現在未定義";
    }
}
void CPrinterDev::PaperSize(LPDWORD x,LPDWORD 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;
    }
    if(IsLandscape()==TRUE){
        DWORD s;
        s = *x; *x=*y; *y=s;
    }
    // Scaling
    (*x) *=GetScale(); (*x) /=100;
    (*y) *=GetScale(); (*y) /=100;
};
short    CPrinterDev::GetScale    (void){
    return sScale;
}
short    CPrinterDev::SetScale    (short dmScale){
    ASSERT(pDevMode);
    short s = pDevMode->dmScale;
    if(!OpenPrinter(szDevice,&hPrinter,NULL))return -1; // printer open error
    pDevMode->dmScale = dmScale;
    if(DocumentProperties(hWnd,hPrinter,szDevice,pDevMode,pDevMode,DM_IN_BUFFER | DM_OUT_BUFFER)!=IDOK){
        return -2;} // scale setting error
    ClosePrinter(hPrinter);
    sScale = dmScale;
    return s;
};
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(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(hWnd,hPrinter,szDevice,pDevMode,pDevMode,DM_IN_BUFFER | DM_OUT_BUFFER)!=IDOK)
        {pDevMode->dmPaperSize = s; return FALSE;}
    ClosePrinter(hPrinter);
    return TRUE;
};
BOOL CPrinterDev::IsLandscape(void){
    if(((pDevMode->dmOrientation)&DMORIENT_LANDSCAPE)!=0)return TRUE;
    else return FALSE;
}

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

int CPrinterDev::EndPage(void){
    if(bOut2DC == TRUE) return 0;
    return(::EndPage(m_hDC));
};
BOOL CPrinterDev::AttachDC(CDC& cpdc){
    BOOL b=Attach(cpdc);
    if(b==TRUE){
        bOut2DC = TRUE;
    }
    return b;
};
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;
    bOut2DC = FALSE;
    StartDoc(&docinfo);
    return TRUE;
};

CPrinterDev::CPrinterDev(CWnd*cwnd){
    lpcwnd        = cwnd;
    pDevMode    = NULL;
    hPrinter    = NULL;
    bOut2DC        = FALSE;
    if(cwnd!=NULL)hWnd=cwnd->m_hWnd; else hWnd=NULL;
    GetDefPrinterName();
    // Printer device initialize
    if(!OpenPrinter(szDevice,&hPrinter,NULL))return;
    GetDefaultPrinterSettings();
    SetScale(100); // 100% Scaling (Default Scale)
};
CPrinterDev::~CPrinterDev(){
    if(pDevMode!=NULL) free(pDevMode); pDevMode=NULL;
    if(m_hDC!=NULL){
        if(bOut2DC ==FALSE)EndDoc();
        DeleteDC();
    }
    if(hPrinter!=NULL)ClosePrinter(hPrinter);
};
//------------------------------------------
// Private Functions
BOOL CPrinterDev::GetDefaultPrinterSettings(void){
    DWORD        dwNeeded;
    if(lpcwnd==NULL)    dwNeeded = DocumentProperties(NULL,hPrinter,szDevice,NULL,NULL,0);
    else dwNeeded = DocumentProperties(lpcwnd->m_hWnd,hPrinter,szDevice,NULL,NULL,0);
    pDevMode = (LPDEVMODE)malloc(dwNeeded);
    if(lpcwnd==NULL)    dwNeeded = DocumentProperties(NULL,hPrinter,szDevice,pDevMode,NULL,DM_OUT_BUFFER);
    else 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);
    }
};

Copyright (C) Kitaro 1998