CImageのGetDC()で取得できるHDCにSelectObject

解決


ryo  2007-10-25 18:37:48  No: 66648

XP、VS2005、MFC

二つのCImageから、GetDC()でデバイスコンテキストを取得し、
個別に作成したペンを順にSelectObjectをしようとしています。

以下の処理を行ったところ、pen1とold2の値が同じになってしまいました。
(当然なのかこの作業の後、img1に対しラインを引くと白い線になります)

これは何故なのでしょうか?

//ペンの設定
  CImage img1;
  CImage img2;

  img1.Create( 100,100,24 );
  img2.Create( 100,100,24 );
  
  HPEN old1,pen1,old2,pen2;
  pen1 = ::CreatePen( PS_SOLID,1,RGB(  0, 0,255));
  pen2 = ::CreatePen( PS_SOLID,1,RGB(255,255,255));

  HDC hdc;
  hdc = img1.GetDC();
  old1 = (HPEN)::SelectObject( hdc , pen1);        // Ima1から取得したHDCにpen1を
  img1.ReleaseDC();                                // Img1のHDCを開放

  hdc = img2.GetDC();                              // Img2のHDCを取得
  old2 = (HPEN)::SelectObject( hdc , pen2);        // pen1が返ってきてしまう(img1のHDC?)
  img2.ReleaseDC();

/////////////////////////////////////////////////////////
// 塗りつぶし(参考)
  (略)
  RECT rec;
        SetRect( &rec,0,0,100,100);

  HDC hdc;
  hdc = img1.GetDC();
  FillRect( hdc , &rec , (HBRUSH)GetStockObject( WHITE_BRUSH ) );
  img1.ReleaseDC();

  hdc = img2.GetDC();
  FillRect( hdc , &rec , (HBRUSH)GetStockObject( BLACK_BRUSH ) );
  img2.ReleaseDC();

  img1.Save("c:\\img1.bmp");
  img2.Save("c:\\img2.bmp");

この場合は、img1.bmpは真っ白BMP、img2.bmpは真っ黒BMPになります。


subaru  2007-10-25 22:56:25  No: 66649

CImage内部に作成したデバイスコンテキストを
ある程度キャッシュして再利用するしくみがあるようです。

今回の場合は、

img1.GetDC();
で(キャッシュにないので)DCを作成。

img1.ReleaseDC();
でDCをキャッシュに保持。

img2.GetDC();
でDCをキャッシュから取得。

img2.ReleaseDC();
でDCをキャッシュに戻す。

といった流れになっていると思います。
参照カウントの管理はありますが基本的に
イメージの選択/解除はGetDC/ReleaseDCの度に行われます。
このときに選択されているペンやブラシには関知しないため
そのようなことになってしまうのでしょう。


ryo  2007-10-27 01:09:41  No: 66650

返答ありがとうございます。
こういう仕様であると認識した上で、対応していこうと思います
とりあえずは、同時にGetDCし、HDCを別々に取得し、
処理を行うことにしました

しかし、このような仕様になったのかMSの意図はちとわからないのですが・・・


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

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






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