はじめまして。
VC.net winXPでプログラムの勉強をしてるんですが、
裏画面(メモリDC?)の処理がうまくできません。
ピクチャのプロパティをビットマップにしてOnInitDialogで
HBITMAPにLoadimageで読み込み
関連しているCstaticにsetbitmapをしてビットマップの表示をしています。
さらにその上にMoveToやらLineToやらで線を引いているんですが、
ウィンドウが隠れた後等の再描画時に引いた線が消えてしまいます。
それを回避する為に裏画面のHBITMAPに描画し、
それをBitBlt等を使ってピクチャに転送すれば良いような事はわかったのですが、
うまくそれを実現する事ができません。
ソースの一部は以下の通りです。
void CtestpictDlg::OnBnClickedDraw()//コマンドボタンを押した時に処理
{
//m_StaticPictureにはOnInitDialogでSetBitmap(m_hBmp)として
//ビットマップのセットがしてあり、ダイアログを見るとちゃんと表示されている。
CDC dc;
CString str;
CWnd *h = GetDlgItem(IDC_STATICPICTURE);
CDC *hdc = h->GetDC();//ピクチャのDCを取得
dc.CreateCompatibleDC(hdc);
HBITMAP test=CreateCompatibleBitmap(hdc->m_hDC,256,256);
//ピクチャからビットマップを初期化
HBITMAP* oldbmp = (HBITMAP*)dc.SelectObject(&test);
//dcにビットマップを割り当て
CPen p(PS_SOLID,1,RGB(0,255,0));
CPen* oldp = (CPen*)dc.SelectObject(&p);
dc.MoveTo(10,10);
dc.LineTo(100,100);//とりあえず斜めに線を引けるように。
//m_StaticPicture.SetBitmap(test);//ここでtestを見てみると真っ黒な256*256の画像
BitBlt(hdc->m_hDC,0,0,256,256,dc.m_hDC,0,0,SRCCOPY);
//UpdateData(FALSE);必要かどうかわからない…
//以下に開放処理等
}
まだ勉強し始めて日が浅いので、
ちぐはぐな事をしているかもしれませんがよろしくお願いします。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
> CDCを使ってHBITMAPに描画する、
> というソース部分は合っていますでしょうか?
とりあえず動きそうにも見えますが、CDC/HDC と CBitmap/HBITMAPなど、MFCとWin32APIが混在していて、提示範囲だけではなんとも…。
MFCを使うのであれば、HBITMAPなどを直接使うのはお勧めできません。
(リソース解放などがわかりにくい<気づきにくいバグの温床)
ラッパーがMFCにいるのでそちらで統一してください。
また、BitBlt等もメンバ変数がいるのでそれを使ってください。m_hDC などを直接使うのも美しくありません。
# 一応、m_hDC や HBITMAP を使わなくても書ける様にできてます>MFC
>//UpdateData(FALSE);必要かどうかわからない…
これはDDX用なので描画には直接関係ないです。
> ピクチャからメモリDCへのBitBlt
> メモリDCからピクチャへのBitBlt
簡単な検証コードも書いてみましたが、これらはいずれも可能。
描画されないのは、どこかコードがおかしいのでしょう。
> //m_StaticPicture.SetBitmap(test);//ここでtestを見てみると真っ黒な256*256の画像
このコメントアウト部で確認できると考えているのなら、SetBitmapの役割にも誤解がありそうな気が。大丈夫ですか。
CStaticのSetBitmapは、呼んだ瞬間に画像を転送するものではなく、CStaticとビットマップを関連付けるもので、以後必要に応じて渡したビットマップを表示しようとしますから、設定以後はそのビットマップが常に有効でなければなりません。
「以下に開放処理等」でtestを破棄したりしてると、まともに表示されないと思います。
その上で、仮にコードが直ったとして、単純に OnPaint で線を引こうとしても、おそらくうまくいきません。
これは、ダイアログとピクチャは別のウィンドウであり、ダイアログのOnPaintで描画しても、ピクチャの描画で塗りつぶされるためと思われます。
対策:
1.ピクチャ用のサブクラスを作り、そちらのOnPaintで描画。
2.ピクチャを使わず、ダイアログに直接描画
なにか、ピクチャを使わなければならない理由がありますか?
ピクチャコントロールは、ダイアログが描画内容をコントロール任せにするためにあると思うので、それを外から弄る用途には向いてないような。
少なくともOOの観点からすれば、ピクチャを使うなら、その描画はピクチャでやるのが好ましいです。
// static とあるものは、メンバ等
// エラー処理や解放系をだいぶ省略、やっつけ処理
// 初期化
static CImageimage;
HRESULTresult= image.Load(TEXT("c:/work/cg4.jpg"));
ASSERT(SUCCEEDED(result));
pict.SetBitmap(image);
pict.GetClientRect(backRct);
CDC*dc= GetDC();
ASSERT_VALID(dc);
VERIFY(backDc.CreateCompatibleDC(dc));
VERIFY(backBmp.CreateCompatibleBitmap(dc, backRct.Width(), backRct.Height()));
oldBmp= backDc.SelectObject(&backBmp);
VERIFY(ReleaseDC(dc));
// 描画
CPaintDCdc(this);
CDC*frontDc= pict.GetDC();
VERIFY(backDc.BitBlt(backRct.left,backRct.top,backRct.right,backRct.bottom,frontDc,0,0,SRCCOPY));
CPenpen;
VERIFY(pen.CreateStockObject(WHITE_PEN));
CPen*oldPen= backDc.SelectObject(&pen);
backDc.MoveTo(10,10);
backDc.LineTo(100,100);
backDc.SelectObject(oldPen);
VERIFY(frontDc->BitBlt(backRct.left,backRct.top,backRct.right,backRct.bottom,&backDc,0,0,SRCCOPY));
pict.ReleaseDC(frontDc);
//CDialog::OnPaint();
これで、ダイアログを無効化せずにピクチャだけ無効化するとcg4の上に線が引かれます。ダイアログの無効化ではcg4が表示されるのみで、線は引かれません。
No.2
- 回答日時:
> ピクチャからビットマップを取得しtestに入れて、
ぱっと見、この処理が見当たりません。
> HBITMAP test=CreateCompatibleBitmap(hdc->m_hDC,256,256);
このAPIは、互換ビットマップを作るだけで、画像自体はコピーしてくれません。
この回答への補足
MrBanさん回答ありがとうございます。
CreateCompatibleBitmapを調べたところ
仰るとおり互換のビットマップだけでした。
なのでBitbltを用いtestにコピーをとりそこに描画し、
ピクチャにBitbltで戻す。という事をやってみました。
ソースの変更点は以下の通りです
-------------------------------------------------------------
HBITMAP test=CreateCompatibleBitmap(hdc->m_hDC,256,256);
//ピクチャからビットマップを初期化
dc.BitBlt(0,0,256,256,hdc,0,0,SRCCOPY);//ピクチャのDCからビットマップtestへBitblt
~~~
dc.MoveTo(10,10);
dc.LineTo(100,100);//とりあえず斜めに線を引けるように。
hdc->BitBlt(0,0,256,256,&dc,0,0,SRCCOPY);//ビットマップtestからピクチャのDCへBitblt
--------------------------------------------------------------
以上の事を行ってもhdcへ描画されませんでした。
m_StaticPicture.SetBitmap(test);
UpdateData(FALSE);
を最後のBitbltの代わりに行うと、testの中身は相変わらず真っ黒な画像でした。
ここから考察して、
ピクチャからメモリDCへのBitBlt
メモリDCからピクチャへのBitBlt
が行えていない(行えない)、と考えているんですが実際のところどうなんでしょうか?
No.1
- 回答日時:
>ウィンドウが隠れた後等の再描画時に引いた線が消えてしまいます。
それは
>void CtestpictDlg::OnBnClickedDraw()//コマンドボタンを押した時に処理
で線の描画をしているからです。
普通、これらの描画処理はOnPaintで行います。
この回答への補足
FAYさん回答ありがとうございます。
DialogのOnPaint時にOnBnClickedDraw();を呼んでみましたが、
>//m_StaticPicture.SetBitmap(test);
>//ここでtestを見てみると真っ黒な256*256の画像
と同じく真っ黒な画像になってしまいました。
やりたい事としては裏画面(HBITMAP)に
マウスで線や円の描画を行ってそれを
ピクチャに表示したいのですが…。
上のプログラムは
ピクチャからビットマップを取得しtestに入れて、
testをdcに結びつけdcで描画、
それをBitBltでピクチャに転送。
というような事ができると思っていました。
しかしtestの中は真っ黒で線さえ引けていませんでした。
CDCを使ってHBITMAPに描画する、
というソース部分は合っていますでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PDF AutoCAD図面をPDF fileに変換した際、画像情報やブロック名はわかるのでしょうか。 1 2022/06/03 09:42
- その他(AV機器・カメラ) カメラ LUMIX「DC-S5M2」のライブ配信について。 「DC-S5M2X」が2023年6月中旬 2 2023/04/01 17:35
- デスクトップパソコン キャプチャーボードDRECAP DC-HC4のドライバー 1 2022/05/30 15:40
- LANケーブル・USBケーブル USB-C DCケーブルを探しています。 下記画像の両方がL字型のUSB-C DCケーブルを探してい 4 2022/08/09 19:49
- 数学 『Cの微分.2』 3 2023/02/15 19:47
- バッテリー・充電器・電池 小型シール鉛蓄電池の放電後の電池電圧について教えてください。 5 2022/09/08 10:10
- 扇風機・冷風機・サーキュレーター 家にある扇風機がR30A-Fというものでしてかなり古い機種でしてどうやらDCモーターを使っているらし 2 2022/07/27 00:36
- その他(結婚) dcカード 毎月 久しぶりに記帳してみると、 数ヶ月前から毎月dcカードで10万を超える引き落としが 4 2023/06/28 08:28
- フィナンシャルプランナー(FP) FPやDCプランナーなどの資格で試験の出題内容の改定は毎年何時ですか?古いテキストは使えませんか? 2 2022/11/05 14:23
- 電車・路線・地下鉄 補助電源としてDC-DCコンバーターを採用してる電車 3 2023/05/13 19:39
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
[VB.net] DataGridViewの列ヘッ...
-
PCで「使用可能な場合はグラフ...
-
VB6,リストボックスの特定行の...
-
多角形の描画。(VC++)
-
C++にて、塗りつぶされた円を描...
-
UpdateData( FALSE); による文...
-
word
-
WM_SIZEとWM_SIZINGの違い (Win...
-
ちらつきを何とかしたい
-
CScrollViewの使用方法について
-
タブコントロール上のピクチャ...
-
MFCのタイマーのつかい方を教え...
-
VBAにGDI+を参照させる方法
-
VB.netでのライン描画方法がわ...
-
MFCタブコントロールのグラデー...
-
NVIDIAのシェーダーキャッシュ
-
アプリケーションのデザイン
-
ビューにビットマップファイル...
-
c++ ダブルバッファリング、以...
-
ペーパーマリオみたいにドット...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
[VB.net] DataGridViewの列ヘッ...
-
NVIDIAのシェーダーキャッシュ
-
MFCでOnPaintのタイミング
-
TextBoxに文字を書いても表示さ...
-
word
-
UpdateData( FALSE); による文...
-
VC++プログラムをつかったBMP画...
-
InvalidateRectの使い方について
-
StretchBlt関数について
-
OneNote 2010 文字と描画がずれる
-
C# ラバーバンドの描画を快適に...
-
エクセルでガンチャートを作成...
-
C++にて、塗りつぶされた円を描...
-
VBAにGDI+を参照させる方法
-
MFC DrawText 背景色とフォント
-
GDI+で高速な描画
-
MFCのタイマーのつかい方を教え...
-
Labelの文字をスクロールする際...
-
FlexGridの一部のみ表示を更新...
おすすめ情報