再描画

マウスで右クリックをしたときに、クライアント領域に文字を表示させる、プログラム(test)を実行させ、クライアント領域でマウスの右ボタンをクリックしてください。当然、 "Hello World!"という文字列と、その下に"マウスが押下されました"という文字列が現れます。

ここで、次の作業を行ってください。

1. 表示されてるウィンドウを他のプログラムのウィンドウで、すっかり覆います。例えば、Visual C++のウィンドウが後ろの方に見えているのならば、そのどこかをクリックするれば覆うことができます。

2. 次に、この覆ったウィンドウをどけて(移動するか、最小化するか適当に)、我々の作ったウィンドウが、すべて現れるようにします。

すると、変なことが起こっていることに気がつくでしょう。"Hello World!"という文字列はそのまま残っていますが、"マウスが押下されました"という文字列は消えています。これは、どうしたことでしょう。

あるウィンドウに、他のウィンドウを重ねて隠すと、下になったウィンドウは消されてしまいます。そして、重ねたウィンドウをどけるなどした時に、まるで下になったウィンドウが再び現れてきたように我々に見せるため、Windows(OS)は消されたウィンドウを描き直します。しかし、Windowsはクライアント領域内に描画されていたものについては、全く関知していないので、再描画することができません。その代わりに、再び現れたウィンドウに対して、描画されている文字などが消されたので、もう一度書き直す必要がありますよ、再描画してくださいというメッセージWM_PAINTを、このウィンドウ(に対応するクラスCMainFrameの実体)に送ります。これに対応する関数がOnPaint()だったのです(注)。クライアント領域内に描画されていたものについては、この関数のなかで、再描画しなければなりません。

OnPaint()の中身を見ると、"Hello World!"と書く関数が入っています。このため、"Hello World!"は再描画されて、再びクライアント領域に現れるのです。ところが、メッセージWM_PAINTがウィンドウに送られてきても、OnRButtonDown関数は我関せずです。したがって、"マウスが押下されました"は再描画されず、クライアント領域に現れません。

まとめると、OnPaint()は、再描画が必要なとき、すなわちWindowsがウィンドウに対してメッセージWM_PAINTを送ってきたとき、実行される関数ということになります。これは、大変重要なのでしっかり理解しましょう

それでは、再描画する必要があるときに、"マウスが押下されました"という文字列も再び表示したい場合はどうしましょうか。この問題は保留にしておきます。

最後に、OnPaint()がいつ呼ばれるかを実感するプログラムTraceWnd.zipを作りましたので、興味があればお試しあれ。プログラムを実行すると2つのウィンドウが現れます。白地のウィンドウのタイトルバー(TraceWnd Programと書かれた横棒)をマウスでドラッグすることにより、このウィンドウをディスプレイ画面上をあちらこちらと移動してみてください。OnPaint()が呼ばれた時、灰色地のウィンドウに呼ばれた回数とともに、その旨表示されます。

注:メッセージWM_PAINTに対応するOnPaint()関数は、初めからプログラムに書かれてありました。実は、ClassWizardでメッセージWM_RBUTTONDOWNに対応する関数OnRButtonDownを追加したと同じ要領で、すでに私が追加していたのです。


戻る