コントロールの再描画

解決


鈴木  2003-02-23 00:49:43  No: 51094

前回ボタンを再描画する方法をお聞きしたので、同じ失敗をしないようにとやってみたのですが、どうしても一旦別のウィンドウに隠れてしまったコントロールが再描画されません。
前回は背景にビットマップを読み込ませて表示しようとしていて、「WM_PAINT」で「GetDC」使って描画しようとしたために失敗していたのですが、今度は「WM_CREATE」で単純にコントロールを配置しただけです。
親ウィンドウのスタイルは
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,WS_EX_CONTROLPARENT | WS_EX_WINDOWEDGE
です。
ウィンドウプロシージャの他のメッセージに対する応答は終了のためのものと「default:return(DefWindowProc(hwnd, uMsg, wParam, lParam));」以外何も書いていません。
どのように改善すればよいのか回答お願いします。
環境:Windows2000、C++6(SP5)、SDK、SDI

hChdWnd[0] = CreateControlWindow(hwnd,10,10,200,20,0,WS_GROUP | WS_TABSTOP | BS_AUTOCHECKBOX,
      "ロゴを表示する",
      "BUTTON",(HMENU)1500,(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE));


鈴木  2003-02-24 06:58:44  No: 51095

呼び出してるコントロールウィンドウ作る関数を書くの忘れてました。

HWND CreateControlWindow(HWND hwndParent, int Left, int Top,int Width, int Height,int dwExStyle ,int dwFlag ,LPCTSTR Caption, LPCTSTR ClassName,HMENU ChildID,HINSTANCE hInstance)
{
  return CreateWindowEx(dwExStyle,ClassName,Caption,WS_CHILD | WS_VISIBLE | dwFlag ,
                         Left, Top, Width, Height, hwndParent, ChildID, hInstance, NULL);
}


YuO  2003-02-25 03:16:02  No: 51096

根本的に,再現していない以上答えようがないです。
実際に失敗するプログラムを載せてみるとよいかと。


鈴木  2003-02-25 08:05:53  No: 51097

下記のアドレスへアップしました。
質問を書き込んだ時点ではウィンドウを作成してそこにコントロールを配置しただけだったのですが、それから少しずつ足していってフォント変更とウィザードもどきの追加をしています。しかし、足しただけでその他の変更は加えておりません。
また常識はずれのことをしでかしてるのかも知れません。ご面倒とは思いますが、チェックよろしくお願いします。
http://www.geocities.co.jp/SiliconValley-Oakland/1272/AutorunStudio.lzh


YuO  2003-02-25 09:01:53  No: 51098

とりあえず,WM_PAINTに対してreturn 0;としかしていないので,
無効領域が有効化されていないです。
なので,WM_PAINTからシステムに戻った後,再びWM_PAINTが送られています。

return 0;
ではなく,
return DefWindowProc(hwnd, uMsg, wParam, lParam);
とするか,
BeginPaintを呼び出す必要があります。
#ValidateRectでもいいですが……。


YuO  2003-02-25 10:41:16  No: 51099

せっかくなので,原因発見までの道のり。

1. 描画されないということはWM_PAINTまわりの問題なので,SPYでコントロールにWM_PAINTが来るか調べる→来ていない
2. 親ウィンドウのWM_PAINTを調べる→大量に来ている

これから,WM_PAINT応答がまずいことがわかります。
あとは,WM_PAINTの発生要因を考えるだけです。

そーいや,書き忘れていたことです。
WNDCLASS:hbrBackgroundへ渡す値は,
reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
のように,+1する必要があります。
#なんでWindowsがそんな設計になっているのかは謎。
現状では,メインウィンドウの背景ブラシの色として(HBRUSH)COLOR_WINDOW,
つまりは(HBRUSH)(COLOR_MENU + 1)ということで,
メニューバーの色が選択されてしまっています。


鈴木  2003-02-26 03:19:43  No: 51100

ありがとうございました。無事解決いたしました。
return DefWindowProc(hwnd, uMsg, wParam, lParam); を入れておきました。
しかし、よくよく考えて見ると、処理しないメッセージはWindowsにそのまま返さなければならないのだから、WM_PAINTを拾ってそのまま終わらせてたら正常にならないのは当たり前ですね。
まだ何も処理を書いてないのでWM_PAINTの部分をコメントアウトしておきました。

それと、(HBRUSH)COLOR_WINDOW は (HBRUSH)(COLOR_MENU + 1)に変えておきました。
ボタンコントロールなどを並べていく予定なので、親ウィンドウの背景色はメニューバーと同じ色の方が良いかと思ったので、そのままメニューバーの色を使うようにしておきました。
(HBRUSH)(COLOR_MENU + 1) とした方が明らかにどの色を使っているのかわかり安いですね。


鈴木  2003-02-26 03:21:10  No: 51101

書き忘れてました。
SPY++を使って教えていただいたように調べて見ました。
どのメッセージを確かめればいいのかがわかれば非常に便利なツールですね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加