• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:TreeView表示がおかしいです。)

TreeView表示がおかしいです。

このQ&Aのポイント
  • Borland C++でWindowsAPIの練習中にTreeView表示がおかしい問題
  • フレームウィンドウの中に作成した子ウィンドウでTreeViewを表示しているが、正しく表示されない
  • TreeViewの作成時に設定すべきプロパティが抜けている可能性

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.3

>子ウィンドウにSendMessage ( hTree, WM_PAINT, NULL, NULL );メッセージを送ります。 このhTreeはどのウィンドウです? 掲示されているコードでは未設定(グローバル変数なので0(NULL))…のようですが? 親ウィンドウのWM_PAINTに対して、実際の描画を行わず子ウィンドウに投げるだけ…だと、親ウィンドウの表示が不正になります。 (子ウィンドウですべて覆ってしまえば見えないでしょう…が) また、BeginPaint()~EndPaint()で無効領域の解除を行っていませんので、OSから延々とWM_PAINTが飛んでくることになります。 # Borland C++ではSpy++は無いでしょうけど…Winspectorでメッセージの確認ができます。 子ウィンドウには「SendMessageでWM_PAINTを投げる」のではなく、InvalidateRect()などで無効領域を設定してOSに投げさせる…べきかと。 # もっとも、親ウィンドウにWM_PAINTが飛んできた時点でDefWindowProc()に任せればやってくれる…ハズですが。(子ウインドウのスタイルにも寄りますけど。) ……次は、コントロール(TreeView)がチラつく…でしょうかね? # ちゃんと親ウィンドウに乗っかっているから、親のWM_ERASEBKGNDの影響はない…かな??

dido123
質問者

お礼

おおお、まさしくその通りです。spy++で確認できました。 確かに永遠とWM_PAINTが飛んできています。 私の中では Cls_OnPaint(HWND hwnd){ } と親ウィンドウの中で設定すれば、それでWM_PAINT処理は終わりだと思っていました。 実際は無効領域の解除をしないと何度でもWM_PAINTが飛んできて永久ループ状態だったのですね。 親ウィンドウの処理 ----------------------------------------------------------------------- BOOL Cls_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) { RECT rc; HINSTANCE hInst; GetClientRect (hwnd, &rc); hInst = (HINSTANCE)GetWindowLong ( hwnd, GWL_HINSTANCE ); hTree = CreateWindowEx ( NULL, (LPCTSTR)"TreeWindow", NULL, WS_CHILD | WS_VISIBLE | WS_SIZEBOX, rc.left, rc.top, rc.left+200, rc.bottom, hwnd,NULL,hInst,NULL ); } void Cls_OnPaint(HWND hwnd) { PAINTSTRUCT ps; BeginPaint ( hwnd, &ps ); EndPaint ( hwnd, &ps ); } ----------------------------------------------------------------------- 子ウィンドウの処理 ----------------------------------------------------------------------- void Cls_OnTreeSize(HWND hwnd, UINT state, int cx, int cy) { MoveWindow (hwndTreeView, 0, 0, cx, cy, TRUE); } void Cls_OnTreePaint(HWND hwnd) { PAINTSTRUCT ps; BeginPaint ( hwnd, &ps ); EndPaint ( hwnd, &ps ); } ----------------------------------------------------------------------- とソースを変更して実行すると、希望していた通りの動きになりました。 「無効領域の解除」は大変、勉強になりました。 「Wr5」さん、何度も何度も的確なアドバイスありがとうございました。 今後とも、宜しくお願いいたします。

その他の回答 (2)

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.2

>void Cls_OnTreeSize(HWND hwnd, UINT state, int cx, int cy) >{ > MoveWindow (hwndTreeView, 0, 0, cx, cy, TRUE); >} コンパイル通りますか? hwndTreeViewの宣言がありませんけど? グローバル変数なのでしょうか? グローバル変数だとしても、この変数の中身は0(NULL)になっているかと思われますが… # Cls_OnTreePaint()の方も同様。 「Cls_OnTreeCreate()で設定している。」というのであれば、残念ながらそれはCls_OnTreeSize()やCls_OnTreePaint()には引き継がれません。 Cls_OnTreeCreate()内のローカル変数に設定しただけで、抜けた後には失われてしまうモノですから。 # 「ローカル変数に設定しているが大丈夫か?」と回答したんですが…。 # 「大丈夫だ、問題ない。」なんですか? Cls_OnTreeSize()で、ウィンドウサイズ全体にまでTreeViewを広げようとしていますが、実際に掲示された画像では広がっていませんよね? その関係で、Cls_OnTreePaint()も正しく動作していないのではありませんか?

dido123
質問者

補足

失礼しました。No1さんのご指摘を受け static HWND hwndTreeView; として、再利用できるようにしました。 Cls_OnTreeSize()は子ウィンドウ画面の全体に広げています。 将来的には、ドッキング可能な子ウィンドウにしようと考えています。 理由がわからないのですが、親ウィンドウでWM_PAINTを受け取った時に、子ウィンドウにSendMessage ( hTree, WM_PAINT, NULL, NULL );メッセージを送ります。子ウィンドウでWM_PAINTを受け取った処理を void Cls_OnTreePaint(HWND hwnd) { UpdateWindow (hwndTreeView); } と変更すると、不思議とすべての表示問題が解決されました。なぞです。 根本的な解決になっていないので、このまま、もう少し質問を継続としてご指摘を受けようと思います。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.1

解決には役立たないと思いますが、気になったので指摘を。 >InitCommonControls();// コモンコントロールの初期化 WinMain()あたりでやっておけば良いです。 WM_CREATEのたびに実行が必要なモノではありません。 # 私ならInitCommonControlsEx()で初期化実施しますけど。 >hwndTreeView = CreateWindowEx( ここから抜けた後、TreeViewのウィンドウハンドルが不明になりますが大丈夫ですか? ID(ID_MYTREE)から取得は可能ですから、回避策自体はありますけど…。 実際のアイテム設定(挿入)部分、および描画をおこなっている部分が不明ですので…なんとも。

dido123
質問者

補足

ご助言ありがとうございます。実際のアイテム設定部分等が不明ではお答えできませんよね。 失礼致しました。以下、前回のソースの続きです。 --------------------------------------------------------------------------------- memset((char *)&tv, '\0', sizeof(tv)); tv.hInsertAfter = TVI_LAST; tv.item.mask = TVIF_TEXT; tv.hParent = TVI_ROOT; tv.item.pszText = "粂井"; hParent1 = TreeView_InsertItem(hwndTreeView, &tv); tv.item.pszText = "田中"; hParent2 = TreeView_InsertItem(hwndTreeView, &tv); tv.item.pszText = "佐藤"; hParent3 = TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hParent1; tv.item.pszText = "康孝"; hChild1 = TreeView_InsertItem(hwndTreeView, &tv); tv.item.pszText = "ひとみ"; hChild2 = TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hChild1; tv.item.pszText = "志麻"; TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hChild1; tv.item.pszText = "櫻都"; TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hParent2; tv.item.pszText = "マイケル"; TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hParent3; tv.item.pszText = "パトリシア"; TreeView_InsertItem(hwndTreeView, &tv); } void Cls_OnTreeSize(HWND hwnd, UINT state, int cx, int cy) { MoveWindow (hwndTreeView, 0, 0, cx, cy, TRUE); } void Cls_OnTreePaint(HWND hwnd) { RECT rc; GetClientRect (hwnd, &rc); MoveWindow (hwndTreeView, rc.left, rc.top, rc.right, rc.bottom, TRUE); } /* void Cls_OnTReeClose(HWND hwnd) { DestroyWindow ( hwnd ); } void Cls_OnTReeDestroy(HWND hwnd) { PostQuitMessage ( 0 ); } */ -------------------------------------------------------------------------------- 以上です。 何かおかしな所がありましたら、ご教授お願いします。