OnDraw()とOnPaint()関係

[戻る]
CC 2009/04/27(月) 10:26:36
いつも、お世話になっています。CCです。

ViewクラスにOnDraw()とOnPaint()があります、
DilgBoxにOnPaint()あります、

質問1、
OnDraw()とOnPaint()どういう関係でしょうか。

質問2、
どう使い分けでしょうか。

質問3.
Viewクラスにスクロールバーを使っていますが、
縦(横)をスクロールと移動分だけ再描画したいのですが、
その移動分の再描画部分をOnPaint()に書くでしょうか、
今の状態はスクロールと全体描画しています
(OnDraw()で使っています)、ちらつきが発生しています。

環境:.Net2002 MFC使用
よろしくお願いします。

PATIO 2009/04/27(月) 10:54:27
この辺の話はMSDNの中で解説されているところがあります。
(描画部分の実装に関して解説しているところがあったと思います。)

で、CDialogにもCViewにもあるOnPaintが実際には
ウインドウメッセージのWM_PAINTを受け取ったときに動く関数です。
OnDrawは、OnPaintからさらに描画部分だけを分離した関数で
OnPaintの中から呼ばれます。
OnDrawには実は印刷時にも呼ばれます。
これによって画面上に描画したものと同じ物を印刷できるという
考え方を実装しています。
実際には画面と印刷では解像度が違うのでその部分を考慮した
プログラムにする必要が有りますけれど。

この辺は、ちゃんと解説本とかで勉強した方が良いです。
掲示板だけでは多分抜けが出てきてしまうので。

ウインドウメッセージとかで既にわからないのであれば、
書籍により勉強をお勧めします。
この辺の仕組みについて解説している本を使って勉強した方が
後々の為になりますよ。

PATIO 2009/04/27(月) 10:56:17
日本語が変。(^^;

> OnDrawには実は印刷時にも呼ばれます。

OnDrawには印刷時にも呼ばれるという仕事があります。
と書きたかったんですが、変になってます。(^^;

仲澤@失業者 2009/04/27(月) 11:18:05
−−質問1へのアドバイス−−
確かにマニュアルを見ただけじゃわかりませんね(vv;)。
MFCのソースを見るとCViewのOnPaint()の実装は以下の様になってます。
コメントは自分が入れたものなのでMFCソースにはありません。

void CView::OnPaint()
{
    CPaintDC dc(this);    // BignPaint()でDCを作成
    OnPrepareDC(&dc);     // DCやCScrollView等の属性を調整できる
    OnDraw(&dc);          // 描画メンバを実行する
    // dcのデストラクタでEndPaint()する
}

−−質問2へのアドバイス−−
見ればわかる通りですね。OnDraw()の前になんかすることがあり、
かつ、通常のOnPrepareDC()と別の操作がしたい場合はOnPaint()
を書き換える必要があるかもしれません。

−−質問3へのアドバイス−−
OnPaint()/OnDraw()では渡されたDCに描画できる全てを描画すべきです。

>今の状態はスクロールと全体描画しています
>(OnDraw()で使っています)、ちらつきが発生しています。

OnDraw()内を変更しても有効なことは何もありません。
チラつくのは、スクロールするときにView全体を無効(InvlidateRect())に
しているからです。MFCに任せないで、自前でScrollWindowEx()しましょう。
それでも気になる場合は画面(DC)のバッファリング(裏バッファ)
という手法を使います。

CC 2009/04/27(月) 13:29:45
[[解決]]
PATIOさん、仲澤@失業者さん
ご返事ありがとう。

>OnDrawは、OnPaintからさらに描画部分だけを分離した関数で
>OnPaintの中から呼ばれます。
わかりました。

>チラつくのは、スクロールするときにView全体を無効(InvlidateRect())に
>しているからです。MFCに任せないで、自前でScrollWindowEx()しましょう。
わかりました。
 
どうも、ありがとうございました。

古いスレッドには追加発言できません。