プリンタの設定を初期値に戻すには?

[戻る]
スピードスケート 2010/01/05(火) 11:40:00
VC++ MFC SDI FormView アプリケーションです。

「プリンタ設定」というラジオボタンを設けていて、Aは初期設定のまま、Bはカスタ
ムとしています。
OnPreparePrinting(CPrintInfo* pInfo)の中に次のコードを書いています。

if (m_bPrinter == TRUE) // B:カスタムのとき
{
    PRINTDLG pd;
    pd.lStructSize = (DWORD)sizeof(PRINTDLG);
    BOOL bRet = AfxGetApp()->GetPrinterDeviceDefaults(&pd);
    if (bRet)
    {
        LPDEVMODE lp = (LPDEVMODE)GlobalLock(pd.hDevMode);
        lp->dmOrientation = DMORIENT_LANDSCAPE;
        lp->dmPaperSize = DMPAPER_USER;
        lp->dmPaperWidth = 2000;
        lp->dmPaperLength = 1500;
    }
}

これで、B:カスタムを選択したとき、用紙が横向きでサイズが200X150mmになります。
次に、A:初期設定のままを選択したとき元に戻す方法が判りません。
あらかじめプリンタのhDevModeを取得しておいて、if (m_bPrinter == FALSE) の中にコ
ードを書くことになると思うのですが、どういうコードを書けばいいか判りません。

初心者なので、具体的なコードで教えて戴くと助かります。
よろしくお願いいたします。

PATIO 2010/01/06(水) 09:37:11
初期設定と言うのが何を指しているのかによると思いますよ。

アプリケーションの初期値なのか、
その時にプリンタドライバに設定されている内容を初期値と
言っているのかによって話は変わってきます。
アプリケーションで初期値を持つのであれば、
Bと同じく、その初期値を設定すれば良いだけです。

プリンタドライバに設定されている状態を初期値と言うので
あれば、Bに変更する時に一旦元の値を保持しておいて
それを使って戻すと言うのもありかもしれません。
一回もBに変更していないなら初期値のままと言う認識です。

私の認識だと各アプリケーションが起動した時は、
プリンタドライバの既定値として設定されている値に
なっていると思ったので毎回起動時に既定値を取得すると
良いかもしれませんね。プリンタドライバの既定値は
ユーザーによって変更できるはずなので固定では持てないでしょうし。

スピードスケート 2010/01/06(水) 11:52:41
> プリンタドライバに設定されている状態を初期値と言うのであれば、

こっちです。

当アプリが起動するときに OnInitialUpdate() の中で、GetDevMode() を使って
hDevMode を取得するというのは出来るように思うのですが、hDevMode から
dmOrientation や dmPaperSize を取り出すのが判らないのです。

よろしくお願いいたします。

Blue 2010/01/06(水) 12:14:57
>hDevMode からdmOrientation や dmPaperSize を取り出すのが判らないのです。
って一番最初のコードでできているのでは?

>        LPDEVMODE lp = (LPDEVMODE)GlobalLock(pd.hDevMode);
>        lp->dmOrientation = DMORIENT_LANDSCAPE;
>        lp->dmPaperSize = DMPAPER_USER;

PATIO 2010/01/06(水) 13:03:25
>        LPDEVMODE lp = (LPDEVMODE)GlobalLock(pd.hDevMode);
>        lp->dmOrientation = DMORIENT_LANDSCAPE;
>        lp->dmPaperSize = DMPAPER_USER;

lp使って設定が出来ているなら取得もできるのが理屈ではないかと。

ITO 2010/01/06(水) 13:23:13
FormViewですね。
ん? VC6.0? 
VC6.0なら印刷の環境も構築されるからいいけど、
違うなら、多分自分で構築しないといけないですね。
バージョンアップで変わっている可能性あり。

>hDevMode からdmOrientation や dmPaperSize を取り出すのが判らないのです。
ん? 
構造体 PAGESETUPDLG から取得する。

印刷方法は、VCのバージョンによって変わるのでMSDNLibrary等をよく見ることが大切で
す。

スピードスケート 2010/01/06(水) 14:12:24
VC 2005 です。FormViewに無理矢理、標準の印刷/印刷プレビューリソースをインクルー
ドしています。今のところ、VC6.0と同じように印刷/印刷プレビューも問題なく動作し
ています。

ヘッダーファイル
PRINTDLG m_lpPrintDlg;

ソースファイル
CXxxxView::OnInitialUpdate()
{
    memset(&m_lpPrintDlg, 0, sizeof(m_lpPrintDlg));
    m_lpPrintDlg.lStructSize = sizeof(m_lpPrintDlg);
    m_lpPrintDlg.Flags = PD_RETURNDEFAULT;
    ::PrintDlg(&m_lpPrintDlg);
}

これで、本アプリ起動時のプリンタの設定が m_lpPrintDlg に取得できていると思いま
す。

>        LPDEVMODE lp = (LPDEVMODE)GlobalLock(pd.hDevMode);
>        lp->dmOrientation = DMORIENT_LANDSCAPE;
>        lp->dmPaperSize = DMPAPER_USER;
これは、B:カスタムを設定するときです。
元に戻すために、m_lpPrintDlg.hDevMode の中に入っている用紙の向きやサイズを使っ
て設定したいのですが、そのやり方が判りません。
よろしくお願いします。

ITO 2010/01/06(水) 14:30:14
> 元に戻すために、m_lpPrintDlg.hDevMode の中に入っている用紙の向きやサイズを
> 使って設定したいのですが、そのやり方が判りません。

OnBeginPrinting()のところで処理します。
>        LPDEVMODE lp = (LPDEVMODE)GlobalLock(pd.hDevMode);
>        lp->dmOrientation = DMORIENT_LANDSCAPE;
>        lp->dmPaperSize = DMPAPER_USER;

CDCが有効なので、ResetDC()でCDCをっ再設定します。

ITO 2010/01/06(水) 14:38:14
変換が有効でなかったです。
 「CDCを再設定」しますですね。
コマンドがResetDCだから、
  あたらしいDEVMODEでDCを再初期化します。
の方が再開かもしれません。
詳しくはMSDNを参照

スピードスケート 2010/01/06(水) 15:26:31
ITO様、ありがとうございました。
出来たようです。
OnBeginPrinting()のところに、
if (ラジオボタン:A) pDC->ResetDC(NULL);
と入れたら元に戻りました。
引数は NULL でよかったでしょうか?

スピードスケート 2010/01/06(水) 18:20:33
[[解決]]
目的がかなったので、解決にします。
皆様ありがとうございました。

ITO 2010/01/06(水) 19:04:27
> 引数は NULL でよかったでしょうか?
変更前のパラメータの値を保持しておいて、保持した値に戻したDEVMODEを入れるのが
筋だと思います。
↑
分かりますか?
ちょっとへん(^^;

スピードスケート 2010/01/06(水) 20:01:02
6つ前の発言に書いた m_lpPrintDlg に変更前のパラメータが入っていると考えて、
pDC->ResetDC(m_lpPrintDlg.hDevMode); としましたが、「1 番目の引数を 'HGLOBAL' 
から 'const DEVMODE *' に変換できません」となってビルド・エラーとなります。
この程度の知識しかありません。
よろしくお願いします。

スピードスケート 2010/01/06(水) 22:14:35
これでいいでしょうか?

DEVMODE *pDevMode = (DEVMODE*)(GlobalLock(m_lpPrintDlg.hDevMode));
pDC->ResetDC(pDevMode);
GlobalUnlock(m_lpPrintDlg.hDevMode);
GlobalFree(m_lpPrintDlg.hDevMode); ←この行は必要でしょうか?

ITO 2010/01/07(木) 10:07:18
>これでいいでしょうか?
いいと思います。
> GlobalFree(m_lpPrintDlg.hDevMode); ←この行は必要でしょうか?
必要ですね。

スピードスケート 2010/01/07(木) 11:13:51
ITO様、ありがとうございました。
これで、ほんとの解決になりました。

古いスレッドには追加発言できません。