前提・実現したいこと
windows の api を利用して、guiのアプリケーションを作成しています。
タブコントロールの利用について、ウィンドウの親子関係を利用して描画内容を変えようとしました。
┣メイン┳タブコントロール
┃ ┣その他
┃ ┣親1┳子1
┃ ┃ ┗子2
┃ ┗親2┳子3
┃ ┗子4
上記のような関係のウィンドウを作成しておき、
TCN_SELCHANGE
メッセージに対応して、InvalidateRect
やShowWindow
を親ウィンドウに送ることで、子ウィンドウの描画・非描画ををまとめて管理しようとしました。
発生している問題・エラーメッセージ
想定した内容が描画できていません。コンパイル警告はなし。
親ウィンドウは描画を割り当てていないため確認できず。
描画したい子ウィンドウの内容が確認できないです。
該当のソースコード
c++
1#include <windows.h> 2#include <commctrl.h> 3#include "resource.h" 4 5#define X_MIN 240 6#define Y_MIN 177 7 8#pragma comment(lib, "comctl32.lib") // ステータスバーの作成に必要 9 10// グローバル変数: 11HINSTANCE hInst; // 現在のインターフェイス 12HWND hTab; // タブコントロールのハンドル 13HWND hTabgroup1, hTabgroup2; // タブの描画グループのハンドル 14WNDPROC OrgStaticProc; // スタティックコントロールのプロシージャ 15HWND hStatus; // ステータスバーのウィンドウハンドル 16HWND hButton1, hButton2; // ボタンのハンドル 17HWND hButtonchat; // チャット送信用ボタン 18 19// このコード モジュールに含まれる関数の宣言を転送します: 20ATOM MyRegisterClass(HINSTANCE hInstance); 21BOOL InitInstance(HINSTANCE, int); 22LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 23LRESULT CALLBACK MyStaticProc(HWND, UINT, WPARAM, LPARAM); 24 25//---------- 26 27int APIENTRY WinMain(HINSTANCE hInstance, 28 HINSTANCE hPrevInstance, 29 LPSTR lpCmdLine, 30 int nCmdShow) 31{ 32 MSG msg; 33 MyRegisterClass(hInstance); 34 35 // アプリケーションの初期化を実行します: 36 if (!InitInstance(hInstance, nCmdShow)) 37 { 38 return FALSE; 39 } 40 // メイン メッセージ ループ: 41 while (GetMessage(&msg, NULL, 0, 0)) 42 { 43 TranslateMessage(&msg); 44 DispatchMessage(&msg); 45 } 46 return (int)msg.wParam; 47} 48 49// 50// 関数: MyRegisterClass() 51// 52// 目的: ウィンドウ クラスを登録します。 53// 54ATOM MyRegisterClass(HINSTANCE hInstance) 55{ 56 WNDCLASSEX wcex; 57 58 wcex.cbSize = sizeof(WNDCLASSEX); 59 60 wcex.style = CS_HREDRAW | CS_VREDRAW; 61 wcex.lpfnWndProc = WndProc; 62 wcex.cbClsExtra = 0; 63 wcex.cbWndExtra = 0; 64 wcex.hInstance = hInstance; 65 wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); 66 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 67 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 68 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_HP); 69 wcex.lpszClassName = TEXT("HP"); 70 wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 71 72 return RegisterClassEx(&wcex); 73} 74 75// 76// 関数: InitInstance(HINSTANCE, int) 77// 78// 目的: メイン ウィンドウを作成します。 79// 80BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 81{* …… *\} 82 83// 84// 関数: WndProc(HWND, UINT, WPARAM, LPARAM) 85// 86// 目的: メイン ウィンドウのメッセージを処理します。 87// 88// WM_CREATE - ウインドウ作成時の処理 89// WM_SIZE - ウインドウサイズ変更時の処理 90// WM_GETMINMAXINFO - ウインドウサイズ・位置変更時の処理 91// WM_COMMAND - アプリケーション メニューの処理 92// WM_DESTROY - 中止メッセージを表示して戻る 93// 94// 95LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 96{ 97 int wmId, wmEvent; 98 int nTab; 99 static RECT rc; 100 TCITEM ti; 101 INITCOMMONCONTROLSEX ic; 102 LPMINMAXINFO lpmm; 103 static HWND hStatic, hEdit; 104 static TCHAR szStr[3][512]; 105 106 switch (message) 107 { 108 case WM_CREATE: 109 ic.dwSize = sizeof(INITCOMMONCONTROLSEX); 110 ic.dwICC = ICC_TAB_CLASSES; 111 InitCommonControlsEx(&ic); 112 GetClientRect(hWnd, &rc); 113 hTab = CreateWindowEx(0, WC_TABCONTROL, 114 TEXT(""), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, rc.right, rc.bottom, 115 hWnd, (HMENU)ID_TAB, hInst, NULL); 116 hStatic = CreateWindowEx(0, TEXT("Static"), 117 TEXT(""), WS_CHILD | WS_VISIBLE, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, 118 hWnd, (HMENU)ID_STATIC, hInst, NULL); 119 hEdit = CreateWindowEx(0, TEXT("Edit"), 120 TEXT(""), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE, 20, 40, 150, 50, 121 hStatic, (HMENU)ID_EDIT, hInst, NULL); 122 SendMessage(hTab, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); 123 ti.mask = TCIF_TEXT; 124 ti.pszText = (WCHAR*)(L"接続系"); 125 TabCtrl_InsertItem(hTab, 0, &ti); 126 ti.pszText = (WCHAR*)(L"ゲーム設定"); 127 TabCtrl_InsertItem(hTab, 1, &ti); 128 //スタティックコントロールのサブクラス化 129 OrgStaticProc = (WNDPROC)GetWindowLong(hStatic, GWL_WNDPROC); 130 SetWindowLong(hStatic, GWL_WNDPROC, (LONG)MyStaticProc); 131 //---------- 132 hStatus = CreateWindowEx(//ステータスバーの作成 133 0, STATUSCLASSNAME, NULL, WS_CHILD | SBARS_SIZEGRIP | CCS_BOTTOM | WS_VISIBLE, 134 0, 0, 0, 0, hWnd, (HMENU)ID_STATUS, hInst, NULL); 135 // シンプルモードを指定 136 SendMessage(hStatus, SB_SIMPLE, TRUE, 0); 137 // ステータスバーに文字を挿入 138 SendMessage(hStatus, SB_SETTEXT, SB_SIMPLEID | 0, (WPARAM)TEXT("ステータスバー")); 139 //---------- 140 hTabgroup1 = CreateWindowEx(0, 0, 141 TEXT("タブグループ1"), WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, 142 10, 10, 1440, 810, hWnd, (HMENU)ID_Tabgroup1, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); 143 hTabgroup2 = CreateWindowEx(0, 0, 144 TEXT("タブグループ2"), WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, 145 10, 10, 1440, 810, hWnd, (HMENU)ID_Tabgroup2, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); 146 //---------- 147 hButton1 = CreateWindowEx(0, TEXT("BUTTON"), 148 TEXT("Button1"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 149 10, 150, 80, 30, hWnd, (HMENU)ID_BUTTON1, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); 150 hButton2 = CreateWindowEx(0, TEXT("BUTTON"), 151 TEXT("Button2"), WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 152 150, 210, 100, 50, hTabgroup2, (HMENU)ID_BUTTON2, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); 153 154 //---------- 155 break; 156 157 case WM_SIZE: 158 GetClientRect(hWnd, &rc); 159 TabCtrl_AdjustRect(hTab, FALSE, &rc); 160 MoveWindow(hTab, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); 161 MoveWindow(hStatic, 162 rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); 163 SendMessage(hStatus, WM_SIZE, wParam, lParam); //ステータスバーサンプル由来 164 break; 165 case WM_NOTIFY: 166 switch (((NMHDR*)lParam)->code) 167 { 168 case TCN_SELCHANGE: 169 InvalidateRect(hTab, NULL, TRUE); 170 InvalidateRect(hStatic, NULL, TRUE); 171 nTab = TabCtrl_GetCurSel(hTab); 172 SetWindowText(hEdit, szStr[nTab]); 173 //---------- 174 switch (nTab) 175 { 176 case 0: 177 UpdateWindow(hEdit); 178 SendMessage(hStatus, SB_SETTEXT, SB_SIMPLEID | 0, (WPARAM)TEXT("タブを0に変更")); 179 InvalidateRect(hStatus, NULL, FALSE); 180 InvalidateRect(hButton1, NULL, FALSE); 181 ShowWindow(hTabgroup1, SW_SHOW); 182 ShowWindow(hTabgroup2, SW_HIDE); 183 InvalidateRect(hTabgroup1, NULL, FALSE); 184 break; 185 case 1: 186 InvalidateRect(hEdit, NULL, TRUE); 187 SendMessage(hStatus, SB_SETTEXT, SB_SIMPLEID | 0, (WPARAM)TEXT("タブを1に変更")); 188 InvalidateRect(hStatus, NULL, FALSE); 189 ShowWindow(hTabgroup1, SW_HIDE); 190 ShowWindow(hTabgroup2, SW_SHOW); 191 InvalidateRect(hTabgroup2, NULL, FALSE); 192 InvalidateRect(hButton2, NULL, FALSE); 193 break; 194 default: 195 break; 196 } 197 break; 198 case TCN_SELCHANGING: 199 nTab = TabCtrl_GetCurSel(hTab); 200 GetWindowText(hEdit, szStr[nTab], sizeof(szStr[nTab])); 201 break; 202 } 203 break; 204 case WM_GETMINMAXINFO: 205 lpmm = (LPMINMAXINFO)lParam; 206 lpmm->ptMinTrackSize.x = X_MIN; 207 lpmm->ptMinTrackSize.y = Y_MIN; 208 break; 209 case WM_COMMAND: 210 wmId = LOWORD(wParam); 211 wmEvent = HIWORD(wParam); 212 // 選択されたメニューの解析: 213 switch (wmId) 214 { 215 //---------- 216 case ID_BUTTON1: 217 SendMessage(hStatus, SB_SETTEXT, SB_SIMPLEID | 0, (WPARAM)TEXT("ボタン1が押されました。")); 218 InvalidateRect(hStatus, NULL, FALSE); 219 220 break; 221 //---------- 222 case ID_BUTTON2: 223 SendMessage(hStatus, SB_SETTEXT, SB_SIMPLEID | 0, (WPARAM)TEXT("ボタン2が押されました。")); 224 InvalidateRect(hStatus, NULL, FALSE); 225 SendMessage(hButton2, BM_SETCHECK, 226 !SendMessage(hButton2, BM_GETCHECK, 0, 0), 0); 227 break; 228 //---------- 229 case IDM_EXIT: 230 DestroyWindow(hWnd); 231 break; 232 default: 233 return DefWindowProc(hWnd, message, wParam, lParam); 234 } 235 break; 236 case WM_DESTROY: 237 PostQuitMessage(0); 238 break; 239 default: 240 return DefWindowProc(hWnd, message, wParam, lParam); 241 } 242 return 0; 243} 244 245 246//サブクラス化されたスタティックコントロールのプロシージャ 247LRESULT CALLBACK MyStaticProc(HWND hStatic, UINT message, WPARAM wParam, LPARAM lParam) 248{* …… *\}
試したこと
言い訳ですが、なんか色々試してたらこうなりました。
補足情報(FW/ツールのバージョンなど)
以下のページを下地にしました。
http://gurigumi.s349.xrea.com/programming/visualcpp/sdk_treeview1.html
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。