ビットマップの印刷処理の中の SelectObject 関数が失敗(NULLを返す)
する場合があります。
CDC myDC;
myDC.CreateCompatibleDC(&dcPrint);
HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC,hBitmap);
あるパソコンでは問題なく印刷できているのですが、別のパソコン
(OSは同じWindows XP)で、同じプリンタを指定して印刷すると
SelectObject 関数が失敗して、印刷ができませんでした。
同様の経験をしたかたはいらっしゃいますか?
これでだけでは何とも言いかねますが、
hBitmapには正常な値が設定されているのでしょうか?
hBitmapを得る時に失敗していると言う可能性はないですか?
>hBitmapを得る時に失敗していると言う可能性はないですか?
SelectObject関数の引数 hBitmap から、ビットマップファイルを作成し、
ペイント等で問題ないことを確認できています。
>HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC,hBitmap);
hBitmap ばかり疑っていましたが、(HDC)myDC が原因の可能性も
あるのでしょうか?
>myDC.CreateCompatibleDC(&dcPrint)
dcPrintはどのように作成していますか??
常に印刷できないのでしょうか?
>dcPrintはどのように作成していますか??
以下のように作成しております。
CDC dcPrint;
dcPrint.Attach(m_PrintInfo.m_pPD->m_pd.hDC); // attach printer dc
dcPrint.m_bPrinting = TRUE;
dcPrint.SetMapMode(MM_TEXT);
// Initialise print document details
DOCINFO di;
::ZeroMemory(&di, sizeof(DOCINFO));
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = (LPCSTR)pDoc->m_OutFileName;
BOOL bPrinting = dcPrint.StartDoc(&di);
>常に印刷できないのでしょうか?
印刷できないPCでは、常に失敗します。
印刷できたPCでは、常に正常に動作します。
よろしくお願いします
失敗するPCと成功するPCのプリンタとの関係に違いはないでしょうか?
たとえば出力するプリンタが「通常使うプリンタに設定」にチェックされているとかいないとか。
>失敗するPCと成功するPCのプリンタとの関係に違いはないでしょうか?
確認した範囲ではありませんでした。
>たとえば出力するプリンタが「通常使うプリンタに設定」に
>チェックされているとかいないとか。
この辺りも同じにして、テストしてみましたが駄目でした。
(プリンタを選択しなおしたりなどもやってみましたが×)
ちなみに、「印刷できないPC」、「印刷できたPC」ともに2台以上で、
現象を確認しております(T_T)
症状の原因に関係あるかどうかは別として…幾つか質問。
> myDC.CreateCompatibleDC(&dcPrint);
SelectObject() 関数が失敗した際、CreateCompatibleDC() の戻り値は何?
> dcPrint.Attach(m_PrintInfo.m_pPD->m_pd.hDC); // attach printer dc
ここで Attach() してますが、ここ以降で Detach() してますか?
Detach() していない場合、スコープを外れる等して CDC dcPrint が無効になった時に
m_PrintInfo.m_pPD->m_pd.hDC は削除されますが、これは意図通り?
>SelectObject() 関数が失敗した際、CreateCompatibleDC() の戻り値は何?
1です。
>ここで Attach() してますが、ここ以降で Detach() してますか?
Detachしています。
蛇足
SelectObjectの後で、GetDeviceCapsを実行しているのですが
HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC,hBitmap);
rCode = GetDeviceCaps((HDC)dcPrint,RASTERCAPS);
rCode の値は、28313 (0x00006e99)でした。
> myDC.CreateCompatibleDC(&dcPrint);
> HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC, hBitmap);
ふと思った事ですけど…
hBitmap はおそらく画面DCと互換性のあるビットマップと予想します。
その hBitmap を印刷DCと互換性のあるメモリDCと結び付けようとしているので
SelectObject() が失敗している。って事はあるのだろうか?
一度 myDC.CreateCompatibleDC() の引数に印刷DCで無く画面DCを渡してみては。
# ただこれだと旨くいっても dcPrint との互換性が無くなるので BitBlt() 等すると
# 色情報が欠落するかも。(hBitmap から DIB を取得して dcPrint に StretchDIBits()
# とすれば良いか)
>#(hBitmap から DIB を取得して dcPrint に StretchDIBits()
>とすれば良いか)
StretchDIBits を使用する事で印刷ができました。
以下のような構成で、問題を回避することにします。
(こうなると、全部 StretchDIBits でも良い気もしますが。。。)
SelectObject が成功 → StretchBlt
SelectObject が失敗 → StretchDIBits
印刷DCが、StretchBlt に未対応 → StretchDIBits
Gak さん、huruya さん、PATIO さん
ありがとうございました。
ツイート | ![]() |