C++/CLIで印刷する画像が表示されない

[戻る]
C++/CLI初心者 2010/11/09(火) 22:13:19
filenameで指定したbmpファイルを印刷させるプログラムを作っているのですが、
どうやっても指定したファイル名のアドレスの画像が表示されなくて困っています。
どうやったら良いのでしょうか??

bool printFile(char *filename)
{
    PRINTDLG pd;
    DOCINFO di;
    HWND hWnd;
    HDC hBuffer;
    static HBITMAP hBitmap;

    //プリンタの設定
    memset(&pd, 0, sizeof(PRINTDLG));
    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner = NULL;
    pd.hDevMode = NULL;
    pd.hDevNames = NULL;
    pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC |
        PD_NOPAGENUMS | PD_NOSELECTION | PD_HIDEPRINTTOFILE|
        PD_RETURNDEFAULT;
    pd.nCopies = 1;
    pd.nFromPage = 1;
    pd.nToPage = 1;
    pd.nMinPage = 1;
    pd.nMaxPage = 1;
    memset(&di, 0, sizeof(DOCINFO));
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = filename;
    
    //印刷を実行
    if (PrintDlg(&pd)==TRUE)
    {
        StartDoc(pd.hDC, &di);
        StartPage(pd.hDC);

        //描画を実行
        int lnWidth = 2000;
        int lnHeight = 5000;
        HDC hMemDC = CreateCompatibleDC(pd.hDC);
        HBITMAP hBitmap = CreateCompatibleBitmap
(pd.hDC,lnWidth,lnHeight);
        HBITMAP Obj = (HBITMAP)SelectObject(hMemDC,hBitmap);
        
        int iRet = GetDeviceCaps(hMemDC,RASTERCAPS);
        
        // コピー
        iRet = BitBlt
(hMemDC,0,0,lnWidth,lnHeight,pd.hDC,0,0,SRCCOPY);

        EndPage(pd.hDC);
        EndDoc(pd.hDC);
        DeleteDC(pd.hDC);
        return true;
    }
    return false;
}

しま 2010/11/10(水) 02:54:41
>指定したファイル名のアドレスの画像が表示されなくて
少し意味不明な表現ですが、表示とはプリンターに印刷することなんですね?

>filenameで指定したbmpファイル
を読込む(取得する)のはどこですか?
読込んでいない画像は画面にもプリンターにも出力できないでしょう
まさか
>di.lpszDocName = filename;
で画像の取得するつもりではないですよね?

>BitBlt(hMemDC,0,0,lnWidth,lnHeight,pd.hDC,0,0,SRCCOPY);
の動作が説明できますか?
MSDN によれば BitBlt() はコピー先(hMemDC)へコピー元(pd.hDC)から各ピクセル
のコピーを行うとあるので、プリンターDCからメモリーDCに画像の転送を
しようとしているように見えます

特に、印刷する場合には DIB か DIBSection かを使うことをお薦めします

C++/CLI初心者 2010/11/10(水) 21:19:45
>>指定したファイル名のアドレスの画像が表示されなくて
>少し意味不明な表現ですが、表示とはプリンターに印刷することなんですね?
そうです、プリンターに印刷することです。

>>filenameで指定したbmpファイル
>を読込む(取得する)のはどこですか?
>読込んでいない画像は画面にもプリンターにも出力できないでしょう
>まさか
>>di.lpszDocName = filename;
>で画像の取得するつもりではないですよね?
一応filenameは表示名なので、アドレスを名前にしてみました。
なお、filenameで指定したbmpファイルはこの関数で指定しようと思ったのですが、
エラーで盛り込むことができませんでした。

>>BitBlt(hMemDC,0,0,lnWidth,lnHeight,pd.hDC,0,0,SRCCOPY);
>の動作が説明できますか?
>MSDN によれば BitBlt() はコピー先(hMemDC)へコピー元(pd.hDC)から各ピクセル
>のコピーを行うとあるので、プリンターDCからメモリーDCに画像の転送を
>しようとしているように見えます
書いた後で気がつきましたが、完全に逆ですね、それでも表示されないので、完全に困っ
ています。
画像の読み込み指定をどうするのかで、完全に手詰まり状態になっています。

>特に、印刷する場合には DIB か DIBSection かを使うことをお薦めします
ありがとうございます。早速調査してみますね。

一応、解決した場合、出来上がった関数のソースコード添えて、ほかの人の参考になるよ
うにしたいと思いますので、よろしくお願いいたします。

C++/CLI初心者 2010/11/13(土) 21:26:04
ご指摘を受けて一部ソースコードを修正しました。
//描画を実行
int lnWidth = 20000;
int lnHeight = 50000;
HDC hMemDC = CreateCompatibleDC(pd.hDC);
HBITMAP hBitmap = (HBITMAP)LoadImage( NULL, filename, IMAGE_BITMAP,
    0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
HBITMAP Obj = (HBITMAP)SelectObject(hMemDC,hBitmap);
int iRet = GetDeviceCaps(hMemDC,RASTERCAPS);
// コピー
iRet = BitBlt(pd.hDC,0,0,lnWidth,lnHeight,hMemDC,0,0,SRCCOPY);

ただ、これでは画像が印刷されない問題が治っておらず未だに原因がわかりません。
どうしたらよいのでしょうか?

しま 2010/11/14(日) 09:34:12
せっかく BitBlt(); の戻り値を受取っているのですから、値を見てましょう
もし、エラーの場合は GetLastError() でエラーコードを得て、原因を調べ
ましょう

同様に、 LoadImage(); の戻り値についても調べてみましょう

C++/CLI初心者 2010/11/14(日) 21:24:21
LoadImage();の返り値は未定義、
ほかの返り値は1でした、ためしに
iRet = MoveToEx( pd.hDC, 100, 100 , NULL);
iRet = LineTo( pd.hDC, 500, 800 );

をやってみたところ、返し値が1なのに、
ラインが印刷されないという問題がありました、
これはどういうことでしょうか?

しま 2010/11/14(日) 23:56:04
>iRet = MoveToEx( pd.hDC, 100, 100 , NULL);
>iRet = LineTo( pd.hDC, 500, 800 );
>
>をやってみたところ、返し値が1なのに、
>ラインが印刷されないという問題がありました、
>これはどういうことでしょうか?

神ならぬ身の私にはこれだけの情報からは原因は分りません

只、あてずっぽうでいいのなら
ペンオブジェクトはDCに選択しましたか?
どんなペンで描画しましたか?(色は?太さは?)
また、 100 だとか 500 だとかいう値はどういった単位なんでしょう?
MM_TEXT だとすると
 プリンターにもよりますがずいぶんと小さな値(mm 単位換算で)
 のように思いますし、 Y軸の向きは正だと下向きでしたか?

それと
>LoadImage();の返り値は未定義、
とは、どんな値だったんでしょう?

C++/CLI初心者 2010/11/17(水) 20:19:27
[[解決]]
いろいろ試してみたところ、以下のソースコードにしてみたら、
戻り値が正常で、印刷されたことが分かりました。いろいろありがとうございました。

bool printFile(char *filename)
{
    PRINTDLG pd;
    DOCINFO di;
    HWND hWnd;
    HDC hBuffer;

    //プリンタの設定
    memset(&pd, 0, sizeof(PRINTDLG));
    pd.lStructSize = sizeof(PRINTDLG);
    pd.hwndOwner = NULL;
    pd.hDevMode = NULL;
    pd.hDevNames = NULL;
    pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC |
        PD_NOPAGENUMS | PD_NOSELECTION | PD_HIDEPRINTTOFILE|
        PD_RETURNDEFAULT;
    pd.nCopies = 1;
    pd.nFromPage = 1;
    pd.nToPage = 1;
    pd.nMinPage = 1;
    pd.nMaxPage = 1;
    memset(&di, 0, sizeof(DOCINFO));
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = filename;
    
    //印刷を実行
    if (PrintDlg(&pd)==TRUE)
    {
        StartDoc(pd.hDC, &di);
        StartPage(pd.hDC);

        //描画の設定
        long int lnWidth = 500000;
        long int lnHeight = 700000;
        HDC hMemDC = CreateCompatibleDC(pd.hDC);
        HANDLE hBitmap = LoadImage( NULL, filename, IMAGE_BITMAP,
            0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | 
LR_LOADFROMFILE );
        HGDIOBJ Obj = SelectObject(hMemDC,hBitmap);
        int iRet = GetDeviceCaps(hMemDC,RASTERCAPS);
        //描画を実行
        iRet = BitBlt
(pd.hDC,0,0,lnWidth,lnHeight,hMemDC,0,0,SRCCOPY);
        
        EndPage(pd.hDC);
        EndDoc(pd.hDC);
        DeleteDC(pd.hDC);

        return true;
    }
    return false;
}

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