ウインドウをリサイズした時のペイント・イベントでの再描画について
教えて下さい。
ウインドウのクライアントエリアの大きさに合わせて赤色の
四角ボックスを描画する簡単なテストプログラムを下の様に
書きました。(この質問の末尾にソースを)
まずクリエイトイベントで、
リサイズ時の再描画を自動的に行わないように、
ウインドウクラススタイルの変更をしておきます。
'CS_HREDRAWとCS_VREDRAWを取り除いてセット
SetClassLong(hMainWnd,GCL_STYLE,CS_DBLCLKS)
リサイズとペイントの各イベントではそれぞれが実行されたことを示すために
プロンプト画面に"Resize()"、"Paint()"と表示するようにします。
この設定してからウインドウをリサイズしたとき
結果は、リサイズでウインドウサイズが以前の状態よりも、
小さくなるとき--->ペイント・イベントは実行されない
大きくなるとき--->ペイント・イベントは実行される
となるようです。
ここで気になるのが「ウインドウサイズが大きくなるとき」の動作。
ペイント・イベントへ確かに飛んでいる筈ですが
(プロンプト画面に"Paint()"と表示される)、
クライアントエリア全体は再描画されず、あくまでも
ウインドウ枠を広げた分だけのいわゆる「無効領域」だけが
再描画されている模様。
ただしこのプログラムのペイント・イベントでは「無効領域」は
引数として受け取っておらず、常に画面全体を再描画するような
形になっているので、部分的な無効領域の再描画はそもそも
無理なハズと思うのですが。。
もちろん「リサイズ・イベント」内に
InvalidateRect(hMainWnd, ByVal NULL, FALSE)
と一文書けば何故か解決するのですが、書かなくとも
大きくなるときにはペイントイベントに飛んでいってるようなので、
重複することなら出来れば避けたいと思います。
それ以前にやはり、このペイントイベントが実行されているなら
クライアントエリアは「必ず」全体が再描画されるのではないかと。。
このことがどうにも腑に落ちないでいます。
ウインドウをリサイズした時のペイント・イベントでの再描画について
お知りの方がおられましたら教えて下さい。
(AB4.24/WinMe)
ここにソースが表示されます [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]
コード:
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
#prompt
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
'
'●デストロイ・イベント
'
Sub MainWnd_Destroy()
Scroll_PaintTest424_DestroyObjects()
PostQuitMessage(0)
End Sub
'
'●クリエイト・イベント
'
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
'リサイズ時の再描画を自動的に行わないように、ウインドウクラススタイルの変更。
'CS_HREDRAWとCS_VREDRAWを取り除いてセット
SetClassLong(hMainWnd,GCL_STYLE,CS_DBLCLKS)
End Sub
'
'●ペイント・イベント
'
Sub MainWnd_Paint(hDC As HDC)
Print "Paint()"
'クライアントエリアの大きさに合わせて赤色の枠を描画。
Dim rc As RECT
Dim hPen As HPEN
Dim hOldPen As HPEN
Dim hBrush As HBRUSH
Dim hOldBrush As HBRUSH
GetClientRect(hMainWnd,rc)
hPen= CreatePen(PS_SOLID,0,RGB(255,0,0))
hOldPen=SelectObject(hDC,hPen)
hBrush= CreateSolidBrush(RGB(0,0,0))
hOldBrush=SelectObject(hDC,hBrush)
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom)
SelectObject(hDC,hOldBrush)
DeleteObject(hBrush)
SelectObject(hDC,hOldPen)
DeleteObject(hPen)
End Sub
'
'●リサイズ・イベント
'
Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer)
Print "Resize()"
'↓ここで再描画命令を送れば確かにリサイズ後に
' 画面全体は再描画されるが、とりあえずコメントアウトして無しで実験。
'InvalidateRect(hMainWnd, ByVal NULL, FALSE)
'すると結果は、リサイズでウインドウサイズが以前の状態よりも、
' 小さくなるとき--->ペイント・イベントは実行されない
' 大きくなるとき--->ペイント・イベントは実行される
'となります。
'ここで気になるのが「ウインドウサイズが大きくなるとき」の動作。
'ペイント・イベントへ確かに飛んでいる筈ですが(プロンプト画面に"Paint()"と
'表示される)、クライアントエリア全体は再描画されず、あくまでも
'ウインドウ枠を広げた分だけの「無効領域」が再描画されている模様。
'ただしこのペイント・イベントでは「無効領域」は引数として受け取っておらず
'常に画面全体を再描画するような形になっているので、部分的な無効領域の
'再描画はそもそも無理なハズと思うのですが。。
End Sub