• ベストアンサー

MFC ビットマップ描画で残像が残る

MFCです。 ワーカースレッドで取得したDIBを定期的に描画するプログラムを作っています。 ダブルバッファリングで実現しているのですが、画面リサイズを繰り返すと、再描画の後に、拡大して発生した新しいクライアント領域に古い画像が残ってしまいます。 SelectObject()で選択したコンパチDCのビットマップを選択前のものに戻してなかったのですが、これが原因なんでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • BLK314
  • ベストアンサー率55% (84/152)
回答No.1

>SelectObject()で選択したコンパチDCのビットマップを選択前のものに戻してなかった これが100%確実に原因であるとは断言できませんが、 可能性としてはあり得るでしょう。 「リソース・リーク」になり、ビットマップが正常に描画できなくなるのでは? と思います。

real_neo
質問者

お礼

ありがとうございました

関連するQ&A

  • 画面リサイズ時のちらつきをなくす方法

    MFCです。 ワーカースレッドで取得したDIBを定期的に描画するプログラムを作っています。 DIB描画部の下にはタイトル的な文字列をTextOutしています。 リサイズ時にはDIBのサイズとタイトル文字列表示領域のサイズも変化させる必要があります。 現在、画面をリサイズするとちらつくという問題の対応に悩んでいます。 コンパチDCなどを使ってダブルバッファリングを行うというのはわかっているのですが、 そもそもリサイズ時にちらつくということは、背景が白(デフォルトのブラシ)で塗りつぶされてしまうのが原因だと思っているので、 OnEraseBkgnd()をオーバーライドして、return TRUE するようにしました。 ちらつかなくなったのですが、OnEraseBkgnd()でほかに何もしていないので、リサイズ前のDIBとタイトル文字列が残ってしまって、新たに書き込んだものと重なってしまいます。 OnEraseBkgnd()で背景をいったん塗りつぶせばいいのではないかと思っているのですが、私の考えは正しいでしょうか?

  • ビットマップに描画をしてピクチャーコントロールに貼り付けるためには?

    ビットマップに描画をしてピクチャーコントロールに貼り付けるためには どうすればよいでしょうか? ネットで検索しましたそして、 下のようなコードを書きましたがうまくゆきません。 void CXXXView::OnButton() { CStatic m_ctlImage; // ピクチャーボックスに関連付けした変数 CBitmap m_bmpImage; // ピクチャーボックスに貼り付けるイメージ CDC m_dcImage; // Bitmap描画用のDC CDC* pDC = m_ctlImage.GetDC(); m_dcImage.CreateCompatibleDC(pDC); CRect Cltsz; picture1.GetClientRect(&Cltsz); m_bmpImage.CreateCompatibleBitmap(pDC,Cltsz.Width(),Cltsz.Height()); CBitmap* pOld=m_dcImage.SelectObject(&m_bmpImage); CPen myPEN(PS_SOLID,5,RGB(0,0,255)); CPen* oldPEN=m_dcImage.SelectObject(&myPEN); m_dcImage.MoveTo(10,10); m_dcImage.LineTo(100,100); m_dcImage.SelectObject(oldPEN); m_dcImage.SelectObject(pOld); m_ctlImage.SetBitmap(m_bmpImage); } この様にしましたが、ピクチャーコントロールには 何も描画されません、 何故でしょうか? VS2005で、ボタンをクリックした イベントで描画する場合です、 直線とかは、問題なく描画できました。 ビットマップに描画して貼り付けたいのです、 よろしくお願いします

  • ビットマップの編集について

    どなたかビットマップ編集の経験のある方で分かる方おられましたらアドバイス頂きたいと思い書かせていただきます。 デバイスコンテキストからビットマップを作成したいのですが、作成結果が真っ黒なビットマップになります。多分ビットマップ情報がメモリDCに描画できていないまま作成しているという事なのでしょうか? MemDC = CreateCompatibleDC(元DC); ↓ hBitmap = CreateCompatibleBitmap(元DC,Width,LlnHeight); ↓ SelectObject(MemDC ,hBitmap) ↓ GetObject(MemDC ,tpBitmap,(LPSTR)&tpBitmap); ↓ Liret = GetDIBits(元DC, hBitmap, 0, (WORD)tpBmpIH.biHeight,NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); ↓ Liret = GetDIBits(元DC, hBitmap, 0, (WORD)tpBmpIH.biHeight,(LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); 関係ありそうな所ははこんな感じで操作してます。 Bitbltがサポートされていない様なので別の方法でメモリDCに転送させなければいけないのでしょうか?

  • ビットマップのコピーについて

    はじめまして。 ビットマップ操作について勉強をしております。 現在、ビットマップファイルを読み込んでメモリDC上でコピーし、新しいファイルを生成するプログラムを作っております。 手順としては 1. LoadImageでBMPファイルを読み込み、ハンドルを取得。 hdcmem_old = CreateCompatibleDC ( NULL ); SelectObject( hdcmem_old , hBitmap_old ); 2. hdcmem_new = CreateCompatibleDC ( NULL ); hBitmap_new = CreateDIBSection( hdcmem_new , (BITMAPINFO*)&bmpInfoHeader , DIB_PAL_COLORS , (void **) &Pixel , NULL , 0 ); SelectObject( hdcmem_new, hBitmap_new ); 3. BitBlt( hdcmem_new , 0 , 0 , LCD_WIDTH , LCD_HEIGHT , hdcmem_old , 0 , 0 , SRCCOPY ) でデータを転送後、ビットマップファイルのヘッダを取り出し、&Pixelからビットデータを加えて新たなファイルを生成しているのですが、生成された画像を見ると全黒になっております。 メモリDCを完全に理解してないせいか、解決策がみあたりません。 もしよろしければ、解決策、またはヒントをご教授していただければと思います。 よろしくお願いします。

  • JPanel上での描画と各コンポーネントの配置について

    JPanel上で描画とコンポーネントを共存させたいと思っています。例えば、レイアウトはボーダーレイアウトで、North側にcomboboxとbuttonを、Center側に描画領域をとりたいときには、どうすればいいのでしょうか? 描画はダブルバッファリングを持っているのでどうしてもJPanel上でやりたいのです。よろしくお願いします。

    • ベストアンサー
    • Java
  • 非クライアント領域への描画について

    非クライアント領域に文字を書こうとしました。 以下の(2)では書けますが、(1)では書いてくれません。 CPaintDCはクライアント領域でないとダメなのですか? void CMainFrame::OnPaint() { CPaintDC dc(this); // 描画用のデバイス コンテキスト dc.TextOut(0,0,"こんにちは"); ・・・(1) CDC* pDC = GetWindowDC(); pDC->TextOut(100,0,"こんにちは"); ・・・(2) 環境 WIN98 VC++6.0 MFC

  • クライアント領域のコントロールが描画されない

    WindowsXP / VC2005 / VC++ MFCにてダイヤログベースの画像ビューワの作成を行っています。 機能としては、独自形式のバイナリファイルをダイヤログへドラッグ&ドロップすることにより、 メモリに描画した画像をクライアント領域へ転送して表示します。 こちらが疑問点となるところなのですが、その際にもともと配置していた エディットボックスやスピンボタンなどのコントロールが消えてしまいます。 (見えなくてもボタンを押すことはできるので描画の問題と思われます) 1.なぜこのようなことが起こるのでしょうか? 2・また、コントロールを消さないためにはどうすればよいのでしょうか? 上記に関してご回答いただけると幸いです。 個人的な考えとしては、  1.クライアント領域を描画する際にコントロールを消してしまっている  2.再描画することによりコントロールは表示される(但し問題点としてクライアント領域を書き換える際にちらつく) です。 以下該当関数です //------------------------------------------------------------------------------ void CTestBitBltDlg::OnDropFiles(HDROP hDropInfo) { char acFileName[256]; SHORT sRet; memset(acFileName, 0, sizeof(acFileName)); DragQueryFile(hDropInfo, 0, acFileName, sizeof(acFileName)); memcpy( g_acSpriteFileName, acFileName, 256 - 1 ); CRect rc; GetClientRect(&rc); CClientDC dc(this); CDC dcMem; dcMem.CreateCompatibleDC(&dc); CBitmap bmp; bmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height()); CBitmap* pOldBmp = dcMem.SelectObject(&bmp); dcMem.FillSolidRect(&rc, RGB(0xC0, 0xC0, 0xC0)); // 本関数にてメインとなるメモリDCへの描画をおこなってます sRet = GetMemoryImage(g_acSpriteFileName, 0, &dcMem); if( sRet == FALSE ){ GetDefaultImage(&dcMem); } dc.BitBlt(0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY); dcMem.SelectObject(pOldBmp); //InvalidateRect(FALSE); CDialog::OnDropFiles(hDropInfo); } //------------------------------------------------------------------------------ なお、OnEraseBkgnd関数においてはTRUEのみを返すようにしてます。

  • Windowsプログラミング 画面描画 ちらつき

    SetDIBitsToDevice関数を使って画面に描画をした後、LineTo関数やEllipse関数を使って その画面上に線や丸を表示させる処理をしているのですが、描画処理を一度にできていないためか ちらつきが発生してしまいます。 調べてみるとビットマップのマルチバッファリングなどが解決策にあるのですが、 私は一次元配列で画素値を格納していてビットマップに情報は保持していないため よく解決策で使われているBITBLTが使えない状態です。 裏画面に描画しておいて、最終的に描画は一度だけにするという考えは分かるんですが、 これをSetDIBitsToDevice関数を用いてちらつきが発生しないようにできるんでしょうか? プログラムとしては画像の上に線と円をひたすら描画していくようなイメージをしています。 アドバイスお願いします! case WM_PAINT: hDC=BeginPaint(hParent,&ps); SetDIBitsToDevice( ps.hdc, 0, 0,// コピー先x,y座標 pimg -> bih.biWidth,// DIBの幅 pimg -> bih.biHeight,// DIBの高さ 0, 0,// DIBの座標 0,// 走査線 pimg -> bih.biHeight,/ 走査線数 pimg -> lpBmpData, (BITMAPINFO *)&( pimg -> bih),// BITMAPINFOにキャスト DIB_RGB_COLORS ); for(int i=0; i<number-1; i++){ if(i==0){  hPen1 = CreatePen(PS_SOLID, 1, RGB(255,0,0));  electObject(hDC,hPen1);  MoveToEx(hDC,Xs,Ys,NULL);  Ellipse(hDC,Xs-2,Ys-2,Xs+2,Ys+2); }else{  LineTo(hDC,Xe,Ye);  Ellipse(hDC,Xs-2,Ys-2,Xs+2,Ys+2); } }

  • GDI+について

    いつもお世話になっております。 今回教えていただきたいことは、GDI+についてです。 今まで GDI と OpenGL を組み合わせてプログラミングをしていましたが、GDIでは自前でアンチエリアス処理をしなければならないなど面倒な部分が多く困っていました。 そこで GDI+ を使用して楽にプログラミングしようと考えて色々とプログラムをしてみたのですが、ここにきて壁にぶち当たりましたので、先人の方にご教授していただきたいのです。 《 GDI でプログラムしていた時 》 (1)画像バッファを作成しておく  //ディスクトップのDCを取得  HDC hdcTmp = GetDC( GetDesktopWindow() );  //ビットマップのハンドルと、作成したバッファの先頭アドレスを取得  hBitmap = CreateDIBSection( hdcTmp, &bmi, DIB_RGB_COLORS, (void**)&buffer, 0, 0 );  //HBITMAPにHDCを結び付ける  hdc = CreateCompatibleDC( hdcTmp );     //DIBSection用メモリデバイスコンテキスト作成  hOldHandle = SelectObject( hdc, hBitmap );       //画像バッファ(m_hBitmap)をメモリデバイスコンテキストに選択 (GDIでも描画出来るようにするため) (2)画像バッファ上にGDIで描画する  hdcに対してGDIの関数を使用して描画 (3)BitBlt()でウィンドウに転送する  WM_PAINTのメッセージのときだけウィンドウに対して転送 上記(1)(2)(3)のようにして描画を行っていました。 ■したいこと(1)■ 今したい事は 上記(1)で作成したGDI の画像バッファのhdcを使ってGDI+関数で描画したいのです。 そうするといままで使っていたGDIの知識を生かして両方使えます。 ■したいこと(2)■ したいこと(1)がもし出来ないのであればGDI+での画像バッファがつくれるかどうか、その画像バッファのデバイスコンテキスト は取得できるのかどうか教えていただきたいと思います 情報不足かもしれませんが、ご教授よろしくお願いいたします。

  • エディットコントロールを再描画させるには。

    CreateWindowEx()でエディットボックスを作り、配置して、 その背景のクライアント領域にビットマップを表示しようとしています。 ところが、再描画しようとした時に、BeginPaintで取得したHDCにBitBltでビットマップを表示するのは、問題なく動くのですが、 GetDCで取得したものに、BitBltを行うとエディットボックスが下に隠れてしまいます。(ビットマップで塗りつぶされてしまっています) それで、GetDCでも大丈夫なようにしたいのですが、 何か方法は無いでしょうか? どなたかお願いいたします。