dポイントプレゼントキャンペーン実施中!

 初歩的な質問でごめんなさい。

VC.netのMFCで、OnLButtonDownで描画の処理をしているのですが、これだと画面を最小化したりするとクライアント領域に描画していたものが消去されてしまうので、画面全体のビットマップをメモリに保存しておきOnPaint関数でブロック転送すればよいと参考書に載っているのですが、このメモリに保存してブロック転送というのがうまくできません。

 BitBltを使うのはわかるのですが、どうもうまくいきません。よろしければ、恐縮ですがソースを教えていただきたいです。お願いします。

A 回答 (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の破棄を
適当に処理してください。

この回答への補足

ありがとうございます。質問させて頂きたいのですが
最初の行のCRECT Rect;からCBitmap *OldBmp;までを
Viewクラスのメンバー変数にし、
void CMyView::OnDestroy()
{
memDC.SelectObject(OldBmp);
Bmp.DeleteObject();
memDC.DeleteDC();
CView::OnDestroy();
}
を追加し、後はthulalaさんのご指摘どうり書かせていただいたのですが、ビルドは通っても実行するとフリーズするもしくはDebug Assertion Failedというウィンドウが表示されるます。OnPaintの中では何も書かなくてもよいのでしょうか? 恐縮ですが、もう一度アドバイス頂けないでしょうか?

補足日時:2004/08/21 22:45
    • good
    • 0

Visual C++ 6.0 なら


ClassView内の鍵マークのついた赤い関数を右クリックして削除を選択します。

Visual C++ .NET なら
表示-プロパティウインドウのプロパティでWM_****と
たくさん書かれている項目があります。
そこで、追加のときと同様にクリックして、削除を選択します。

この回答への補足

うまくいけました。
OnPaintは必要ないのですね。
お手数を御かけ致してすいません。
本当にありがとうございました。

補足日時:2004/08/22 14:58
    • good
    • 0

**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;とはしません。
    • good
    • 0

メンバー変数にするならば、


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を初期化するのでしょうか?

補足日時:2004/08/22 00:53
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!