SelectObjectが失敗する場合があります

解決


こまってる人  2005-05-09 19:05:12  No: 57293

ビットマップの印刷処理の中の SelectObject 関数が失敗(NULLを返す)
する場合があります。

CDC myDC;
myDC.CreateCompatibleDC(&dcPrint);
HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC,hBitmap);

あるパソコンでは問題なく印刷できているのですが、別のパソコン
(OSは同じWindows XP)で、同じプリンタを指定して印刷すると
SelectObject 関数が失敗して、印刷ができませんでした。

同様の経験をしたかたはいらっしゃいますか?


PATIO  2005-05-09 19:41:48  No: 57294

これでだけでは何とも言いかねますが、
hBitmapには正常な値が設定されているのでしょうか?
hBitmapを得る時に失敗していると言う可能性はないですか?


こまってる人  2005-05-09 19:46:24  No: 57295

>hBitmapを得る時に失敗していると言う可能性はないですか?
SelectObject関数の引数 hBitmap から、ビットマップファイルを作成し、
ペイント等で問題ないことを確認できています。


こまってる人  2005-05-10 17:56:25  No: 57296

>HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC,hBitmap);
hBitmap ばかり疑っていましたが、(HDC)myDC が原因の可能性も
あるのでしょうか?


huruya  2005-05-11 02:04:16  No: 57297

>myDC.CreateCompatibleDC(&dcPrint)
dcPrintはどのように作成していますか??
常に印刷できないのでしょうか?


こまってる人  2005-05-11 17:43:00  No: 57298

>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では、常に正常に動作します。

よろしくお願いします


huruya  2005-05-11 19:19:09  No: 57299

失敗するPCと成功するPCのプリンタとの関係に違いはないでしょうか?

たとえば出力するプリンタが「通常使うプリンタに設定」にチェックされているとかいないとか。


こまってる人  2005-05-11 20:13:23  No: 57300

>失敗するPCと成功するPCのプリンタとの関係に違いはないでしょうか?
確認した範囲ではありませんでした。

>たとえば出力するプリンタが「通常使うプリンタに設定」に
>チェックされているとかいないとか。
この辺りも同じにして、テストしてみましたが駄目でした。
(プリンタを選択しなおしたりなどもやってみましたが×)

ちなみに、「印刷できないPC」、「印刷できたPC」ともに2台以上で、
現象を確認しております(T_T)


Gak  2005-05-11 23:26:21  No: 57301

症状の原因に関係あるかどうかは別として…幾つか質問。

> 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 は削除されますが、これは意図通り?


こまってる人  2005-05-12 00:10:01  No: 57302

>SelectObject() 関数が失敗した際、CreateCompatibleDC() の戻り値は何?
1です。

>ここで Attach() してますが、ここ以降で Detach() してますか?
Detachしています。

蛇足
SelectObjectの後で、GetDeviceCapsを実行しているのですが
  HBITMAP pOldBMP = (HBITMAP)SelectObject((HDC)myDC,hBitmap);
  rCode = GetDeviceCaps((HDC)dcPrint,RASTERCAPS);
rCode の値は、28313 (0x00006e99)でした。


Gak  2005-05-12 00:59:19  No: 57303

> 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()
# とすれば良いか)


こまってる人  2005-05-12 02:07:50  No: 57304

>#(hBitmap から DIB を取得して dcPrint に StretchDIBits()
>とすれば良いか)
StretchDIBits を使用する事で印刷ができました。

以下のような構成で、問題を回避することにします。
(こうなると、全部 StretchDIBits でも良い気もしますが。。。)
SelectObject が成功            →  StretchBlt
SelectObject が失敗            →  StretchDIBits
印刷DCが、StretchBlt に未対応  →  StretchDIBits 

Gak さん、huruya さん、PATIO さん
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加