- ベストアンサー
クライアント領域の保存
初歩的な質問でごめんなさい。 VC.netのMFCで、OnLButtonDownで描画の処理をしているのですが、これだと画面を最小化したりするとクライアント領域に描画していたものが消去されてしまうので、画面全体のビットマップをメモリに保存しておきOnPaint関数でブロック転送すればよいと参考書に載っているのですが、このメモリに保存してブロック転送というのがうまくできません。 BitBltを使うのはわかるのですが、どうもうまくいきません。よろしければ、恐縮ですがソースを教えていただきたいです。お願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
CRect Rect; CDC memDC; CDC *pDC; CBitmap Bmp; CBitmap *oldBmp; void CPaintView::OnDraw(CDC* pDC) { CPaintDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; pDC->BitBlt(0,0,Rect.Size().cx,Rect.Size().cy,&memDC,0,0,SRCCOPY); // TODO: この場所にネイティブ データ用の描画コードを追加します。 } void CPaintView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO : ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 if(memDC==NULL) { pDC=GetDC(); GetClientRect(&Rect); Bmp.CreateCompatibleBitmap(pDC,Rect.Size().cx,Rect.Size().cy); memDC.CreateCompatibleDC(pDC); oldBmp=memDC.SelectObject(&Bmp); memDC.FillSolidRect(Rect,RGB(255,255,255)); ReleaseDC(pDC); } memDC.TextOut(point.x,point.y,"Hello"); Invalidate(); CView::OnLButtonDown(nFlags, point); } 大まかにはこんな感じだと思います。 WM_DESTROYの時にでも memDC、CBitmapの破棄を 適当に処理してください。
その他の回答 (3)
- thulala
- ベストアンサー率63% (7/11)
Visual C++ 6.0 なら ClassView内の鍵マークのついた赤い関数を右クリックして削除を選択します。 Visual C++ .NET なら 表示-プロパティウインドウのプロパティでWM_****と たくさん書かれている項目があります。 そこで、追加のときと同様にクリックして、削除を選択します。
補足
うまくいけました。 OnPaintは必要ないのですね。 お手数を御かけ致してすいません。 本当にありがとうございました。
- thulala
- ベストアンサー率63% (7/11)
**OnPaint関数は、イベントハンドらごと削除されましたか? //DEL void CPaintView::OnPaint() //DEL { //DEL CPaintDC dc(this); // 描画用のデバイス コンテキスト //DEL //DEL // TODO: この位置にメッセージ ハンドラ用のコードを追加してください //DEL //DEL // 描画用メッセージとして CView::OnPaint() を呼び出してはいけません //DEL } **こんな感じにしてもらえましたか? **ヘッダーも同様 memDC.CreateCompatibleDC(pDC);が初期化作業です。 LButtonを最初に押すときに何も初期化していないので、if(memDC==NULL){}の中の関数が実行されて、memDCなどが構築されます。2度目のLButtonDownで初期化作業が済んでいるのでif(memDC==NULL){}は無視されます。 memDC=NULL;とはしません。
- thulala
- ベストアンサー率63% (7/11)
メンバー変数にするならば、 CDC *pDCをCDC *mDCに変更して、 OnLButtonDown()内のpDCをmDCに変更してください。 void C***View::OnDraw(CDC* pDC) { *** //もしかすると、 if(memDC!=NULL) { pDC->BitBlt(0,0,Rect.Size().cx,Rect.Size().cy,&memDC,0,0,SRCCOPY); } } ウインドウが作成されたときに、まず描画がされます。 そのときに、memDCの中身が何も存在しないので BitBltできずにエラーを起こしたのかもしれません。 へんな書き方をしましたが、 すみません。 MFCのViewには、普通は OnDraw(CDC *pDC){}内部で描画します。 OnPaintには、何もしません。 コードを削除してください。
補足
度々すいません。本当にありがとうございます。 実行時のエラーは出なくなりましたが左クリックを押しても何もウィンドウに描画できません。あと、最初にmemDCをNULLで初期化しようとするとエラーが出て初期化できないのですが、どこでmemDCを初期化するのでしょうか?
補足
ありがとうございます。質問させて頂きたいのですが 最初の行のCRECT Rect;からCBitmap *OldBmp;までを Viewクラスのメンバー変数にし、 void CMyView::OnDestroy() { memDC.SelectObject(OldBmp); Bmp.DeleteObject(); memDC.DeleteDC(); CView::OnDestroy(); } を追加し、後はthulalaさんのご指摘どうり書かせていただいたのですが、ビルドは通っても実行するとフリーズするもしくはDebug Assertion Failedというウィンドウが表示されるます。OnPaintの中では何も書かなくてもよいのでしょうか? 恐縮ですが、もう一度アドバイス頂けないでしょうか?