ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 21:05

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 3 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2009年11月12日(木) 20:08 
オフライン

登録日時: 2006年6月02日(金) 18:20
記事: 106
ウインドウをリサイズした時のペイント・イベントでの再描画について
教えて下さい。

ウインドウのクライアントエリアの大きさに合わせて赤色の
四角ボックスを描画する簡単なテストプログラムを下の様に
書きました。(この質問の末尾にソースを)

まずクリエイトイベントで、
リサイズ時の再描画を自動的に行わないように、
ウインドウクラススタイルの変更をしておきます。
'CS_HREDRAWとCS_VREDRAWを取り除いてセット
SetClassLong(hMainWnd,GCL_STYLE,CS_DBLCLKS)
リサイズとペイントの各イベントではそれぞれが実行されたことを示すために
プロンプト画面に"Resize()"、"Paint()"と表示するようにします。


この設定してからウインドウをリサイズしたとき
 結果は、リサイズでウインドウサイズが以前の状態よりも、
  小さくなるとき--->ペイント・イベントは実行されない
  大きくなるとき--->ペイント・イベントは実行される
 となるようです。
ここで気になるのが「ウインドウサイズが大きくなるとき」の動作。
ペイント・イベントへ確かに飛んでいる筈ですが
(プロンプト画面に"Paint()"と表示される)、
クライアントエリア全体は再描画されず、あくまでも
ウインドウ枠を広げた分だけのいわゆる「無効領域」だけが
再描画されている模様。
ただしこのプログラムのペイント・イベントでは「無効領域」は
引数として受け取っておらず、常に画面全体を再描画するような
形になっているので、部分的な無効領域の再描画はそもそも
無理なハズと思うのですが。。

もちろん「リサイズ・イベント」内に
 InvalidateRect(hMainWnd, ByVal NULL, FALSE)
と一文書けば何故か解決するのですが、書かなくとも
大きくなるときにはペイントイベントに飛んでいってるようなので、
重複することなら出来れば避けたいと思います。

それ以前にやはり、このペイントイベントが実行されているなら
クライアントエリアは「必ず」全体が再描画されるのではないかと。。
このことがどうにも腑に落ちないでいます。

ウインドウをリサイズした時のペイント・イベントでの再描画について
お知りの方がおられましたら教えて下さい。

(AB4.24/WinMe)


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2009年11月12日(木) 23:54 
オフライン

登録日時: 2005年7月19日(火) 19:47
記事: 98
お住まい: 山形県
CS_HREDRAW / CS_VREDRAW は、サイズ変更時に「クライアント領域全体」を再描画するためのフラグです。
このフラグが指定されていなければ、サイズ変更時はその広がった部分のみが無効領域となり再描画の対象となります。
つまり、サイズ変更時は(無効領域がクライアント領域全体か広がった部分のみかの違いがあるだけで)
フラグの指定の有無に関係なく WM_PAINT メッセージが飛んでくるのです。

そして、無効領域が広がった部分のみの場合、その外へ描画しても反映されません。
なぜなら、(Callback.wbp を見ると分かりますが)Paint イベントの引数である hDC は、
BeginPaint API から返された、あらかじめクリッピング リージョンが設定されているものだからです。

_________________
Toshi's Recess Room
http://toshi.my.land.to/


通報する
ページトップ
投稿記事Posted: 2009年11月13日(金) 01:28 
オフライン

登録日時: 2006年6月02日(金) 18:20
記事: 106
レスありがとうございます。
引用:
そして、無効領域が広がった部分のみの場合、その外へ描画しても反映されません。
なぜなら、(Callback.wbp を見ると分かりますが)Paint イベントの引数である hDC は、
BeginPaint API から返された、あらかじめクリッピング リージョンが設定されているものだからです。

Callback.wbpを覗いてみるとご指摘の通り
確かにこう書かれていました。
コード:
Case WM_PAINT
  Dim ps As PAINTSTRUCT
  Dim hDC As HDC
  hDC=BeginPaint(hWnd,ps)
  MainWnd_Paint(hDC)
  EndPaint(hWnd,ps)
この「Begin(End)Paint」というのは自分が
ABのプロジェクトでプログラムを書いていると
「見ないで終わってしまう」のでロクに理解せずに
来てしまったなぁと反省しています。
「クリッピングリージョン」が設定されているとその外は
いくらペイントイベント内で描画してても実際には反映
されないんですね。
ペイントイベント内の処理は文字通り画面に反映されるもの
と思い込んでいましたから。

CS_HREDRAW / CS_VREDRAWについては
リサイズ時の再描画の「ちらつきを抑制するため」に
というのでどこかで調べたのをそのまま使っていました。
ということはこれ自体は「再描画のちらつき」には本質的には
関係してないのでしょうか?
確かにこれを外すとリサイズ再描画時に一度背景色(?)で
塗りつぶさなくなるようなので重宝して書いてました。
検索して調べてみると次のような記事を見つけました。
http://social.msdn.microsoft.com/forums ... 97d838262/
これによるとCS_HREDRAW / CS_VREDRAWは外さなくていいような
ことが書かれていますが、、
まだ自分で確かめていないので何とも、なのですが、、
取り急ぎ、書いて頂いたレスのお礼までに。
ありがとうございました。
またよろしくお願いします。


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 3 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: Ahrefs [Bot] & ゲスト[13人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean