Win32APIとDirectXを使ってゲームを開発しているものです。
私が作っているゲームはジャンル上解像度をプレイヤーに選択してもらうことになります。
つまり、ウィンドウが2つ以上必要ということです。
先ほど、Win32APIで解像度選択画面を表示して解像度を選択してもらった後、メインウィンドウを表示するというプログラムを作りました。
しかし、ウィンドウが二つ以上あるためPostQuitMessageを使うと、どちらか一方にしかメッセージがいきません。
どのようにすれば、指定したウィンドウの処理を終わらせることができるでしょうか?
コードは
C++//
1//Copy Right MZK All Rights Reserved 2// 3 4//インクルード 5#include <windows.h> 6#include <stdio.h> 7#include <d3dx9.h> 8#include <d3d9.h> 9 10//ライブラリ 11#pragma comment(lib, "d3d9.lib") 12#pragma comment(lib, "d3dx9.lib") 13 14//定数 15#define BUTTON_ID1 0 16#define BUTTON_ID2 1 17#define BUTTON_ID3 2 18#define BUTTON_ID4 3 19#define BUTTON_ID5 4 20#define BUTTON_ID6 5 21//構造体または変数 22RECT cx, rx; 23int windowX; 24int windowY; 25HWND hwnd; 26HWND hmain; 27MSG msg; 28MSG msg1; 29WNDCLASS winc; 30WNDCLASS winc1; 31PAINTSTRUCT ps; 32HDC hdc; 33int id1; 34int new_width; 35int new_height; 36bool bquitwindow = false; 37bool bSelect1; 38bool bSelect2; 39bool bSelect3; 40bool bfullscreen; 41bool bstartgame; 42static HWND radio1; 43static HWND radio2; 44static HWND radio3; 45static HWND fullscreen; 46static HWND startgame; 47static RECT rect; 48static PCTSTR ctStr = TEXT("解像度を選択してください"); 49bool bCheck1; 50 51//ウィンドウプロシージャ1解像度ウィンドウ用 52LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) { 53 switch (msg) { 54 case WM_DESTROY: 55 PostQuitMessage(0); 56 bquitwindow = true; 57 return 0; 58 case WM_CREATE: 59 radio1 = CreateWindow( 60 TEXT("BUTTON") , TEXT("640x480(低画質)") , 61 WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON , 62 0 , 30 , 200 , 30 , 63 hwnd , (HMENU)BUTTON_ID2 , ((LPCREATESTRUCT)(lp))->hInstance , NULL 64 ); 65 radio2 = CreateWindow( 66 TEXT("BUTTON") , TEXT("960x720(中画質)") , 67 WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON , 68 0 , 60 , 200 , 30 , 69 hwnd ,(HMENU)BUTTON_ID3 , ((LPCREATESTRUCT)(lp))->hInstance , NULL 70 ); 71 radio3 = CreateWindow( 72 TEXT("BUTTON") , TEXT("1280x960(高画質)") , 73 WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON , 74 0 , 90 , 200 , 30 , 75 hwnd , (HMENU)BUTTON_ID4 , ((LPCREATESTRUCT)(lp))->hInstance , NULL 76 ); 77 fullscreen = CreateWindow( 78 TEXT("BUTTON") , TEXT("フルスクリーンでプレイ") , 79 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX , 80 0 , 120 , 200 , 30 , 81 hwnd , (HMENU)BUTTON_ID5 , ((LPCREATESTRUCT)(lp))->hInstance , NULL 82 ); 83 return 0; 84 case WM_COMMAND: 85 if(SendMessage(radio1, BM_GETCHECK, 0, 0) == BST_CHECKED){ 86 bSelect1 = true; 87 bSelect2 = false; 88 bSelect3 = false; 89 } 90 else if(SendMessage(radio2, BM_GETCHECK, 0, 0) == BST_CHECKED){ 91 bSelect2 = true; 92 bSelect1 = false; 93 bSelect3 = false; 94 } 95 else if(SendMessage(radio3, BM_GETCHECK, 0, 0) == BST_CHECKED){ 96 bSelect3 = true; 97 bSelect1 = false; 98 bSelect2 = false; 99 } 100 else{ 101 SendMessage(radio3, BM_SETCHECK, BST_CHECKED, 0); 102 bSelect3 = true; 103 bSelect1 = false; 104 bSelect2 = false; 105 } 106 107 if(SendMessage(fullscreen, BM_GETCHECK, 0, 0) == BST_CHECKED){ 108 bfullscreen = true; 109 } 110 if(SendMessage(fullscreen, BM_GETCHECK, 0, 0) == BST_UNCHECKED){ 111 bfullscreen = false; 112 } 113 114 switch(LOWORD(wp)) { 115 case BUTTON_ID1: 116 if(bSelect1 == true && bfullscreen == false){ 117 id1 = MessageBox(hwnd , TEXT("低めな解像度のウィンドウモードでゲームを開始しますよ") , TEXT("Let's Play Game!!") , MB_YESNO); 118 if(id1 == IDNO){ 119 return 0; 120 } 121 if(id1 == IDYES){ 122 ShowWindow(hwnd , SW_HIDE); 123 ShowWindow(hmain , SW_SHOW); 124 PostQuitMessage(0); 125 return 0; 126 } 127 } 128 if(bSelect1 == true && bfullscreen == true){ 129 id1 = MessageBox(hwnd , TEXT("低めな解像度のフルスクリーンモードでゲームを開始しますよ") , TEXT("Let's Play Game!!") , MB_YESNO); 130 if(id1 == IDNO){ 131 return 0; 132 } 133 if(id1 == IDYES){ 134 ShowWindow(hwnd , SW_HIDE); 135 ShowWindow(hmain , SW_SHOW); 136 PostQuitMessage(0); 137 return 0; 138 } 139 } 140 if(bSelect2 == true && bfullscreen == false){ 141 id1 = MessageBox(hwnd , TEXT("中くらいの解像度のウィンドウモードでゲームを開始しますよ") , TEXT("Let's Play Game!!") , MB_YESNO); 142 if(id1 == IDNO){ 143 return 0; 144 } 145 if(id1 == IDYES){ 146 ShowWindow(hwnd , SW_HIDE); 147 ShowWindow(hmain , SW_SHOW); 148 PostQuitMessage(0); 149 return 0; 150 } 151 } 152 if(bSelect2 == true && bfullscreen == true){ 153 id1 = MessageBox(hwnd , TEXT("中くらいの解像度のフルスクリーンモードでゲームを開始しますよ") , TEXT("Let's Play Game!!") , MB_YESNO); 154 if(id1 == IDNO){ 155 return 0; 156 } 157 if(id1 == IDYES){ 158 ShowWindow(hwnd , SW_HIDE); 159 ShowWindow(hmain , SW_SHOW); 160 PostQuitMessage(0); 161 return 0; 162 } 163 } 164 if(bSelect3 == true && bfullscreen == false){ 165 id1 = MessageBox(hwnd , TEXT("一番高い解像度のウィンドウモードでゲームを開始しますよ") , TEXT("Let's Play Game!!") , MB_YESNO); 166 if(id1 == IDNO){ 167 return 0; 168 } 169 if(id1 == IDYES){ 170 ShowWindow(hwnd , SW_HIDE); 171 ShowWindow(hmain , SW_SHOW); 172 PostQuitMessage(0); 173 return 0; 174 } 175 } 176 if(bSelect3 == true && bfullscreen == true){ 177 id1 = MessageBox(hwnd , TEXT("一番高い解像度のフルスクリーンモードでゲームを開始しますよ") , TEXT("Let's Play Game!!") , MB_YESNO); 178 if(id1 == IDNO){ 179 return 0; 180 } 181 if(id1 == IDYES){ 182 ShowWindow(hwnd , SW_HIDE); 183 ShowWindow(hmain , SW_SHOW); 184 PostQuitMessage(0); 185 return 0; 186 } 187 } 188 break; 189 } 190 return 0; 191 case WM_PAINT: 192 hdc = BeginPaint(hwnd , &ps); 193 GetClientRect(hwnd , &rect); 194 DrawText(hdc , ctStr , -1 , &rect , 195 DT_CENTER | DT_WORDBREAK ); 196 EndPaint(hwnd , &ps); 197 return 0; 198 199 } 200 return DefWindowProc(hwnd , msg , wp , lp); 201} 202 203 204LRESULT CALLBACK WndProc1(HWND hwnd , UINT msg1 , WPARAM wp , LPARAM lp) { 205 switch (msg1){ 206 case WM_DESTROY: 207 return 0; 208 } 209 return DefWindowProc(hwnd , msg1 , wp , lp); 210} 211int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,PSTR lpCmdLine , int nCmdShow ) { 212 213 winc.style = CS_HREDRAW | CS_VREDRAW; 214 winc.lpfnWndProc = WndProc; 215 winc.cbClsExtra = winc.cbWndExtra = 0; 216 winc.hInstance = hInstance; 217 winc.hIcon = LoadIcon(NULL , IDI_APPLICATION); 218 winc.hCursor = LoadCursor(NULL , IDC_ARROW); 219 winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 220 winc.lpszMenuName = NULL; 221 winc.lpszClassName = TEXT("WCN"); 222 223 winc1.style = CS_HREDRAW | CS_VREDRAW; 224 winc1.lpfnWndProc = WndProc1; 225 winc1.cbClsExtra = winc1.cbWndExtra = 0; 226 winc1.hInstance = hInstance; 227 winc1.hIcon = LoadIcon(NULL , IDI_APPLICATION); 228 winc1.hCursor = LoadCursor(NULL , IDC_ARROW); 229 winc1.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 230 winc1.lpszMenuName = NULL; 231 winc1.lpszClassName = TEXT("mainwindow"); 232 233 if (!RegisterClass(&winc)) return -1; 234 235 if (!RegisterClass(&winc1)) return -1; 236 237 238 hwnd = CreateWindow( 239 TEXT("WCN") , TEXT("解像度を選択") , 240 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, 241 500, 300, 205, 208, 242 NULL , NULL , hInstance , NULL 243 ); 244 245 startgame = CreateWindow( 246 TEXT("BUTTON") , TEXT("ゲームを始める") , 247 WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON , 248 0 , 150 , 200 , 30 , 249 hwnd , (HMENU)BUTTON_ID1, hInstance , NULL 250 ); 251 252 hmain = CreateWindow( 253 TEXT("mainwindow") , TEXT(Meinwindow") , 254 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, 255 0, 0, 100, 100, 256 NULL , NULL , hInstance , NULL 257 ); 258 259 GetWindowRect(hmain, &rx); 260 GetClientRect(hmain, &cx); 261 262 //ウィンドウサイズの変更 263 if(bSelect1 == true){ 264 SetWindowPos(hmain, NULL, 0, 0, 640, 480, SWP_SHOWWINDOW); 265 } 266 if(bSelect2 == true){ 267 SetWindowPos(hmain, NULL, 0, 0, 960, 720, SWP_SHOWWINDOW); 268 } 269 if(bSelect3 == true){ 270 SetWindowPos(hmain, NULL, 0, 0, 1280, 960, SWP_SHOWWINDOW); 271 } 272 273 //ウィンドウ表示 274 275 ShowWindow(hmain , SW_HIDE); 276 277 ShowWindow(hwnd , SW_SHOW); 278 279 280 if (hwnd == NULL) { 281 //エラーコード001 282 MessageBox(NULL,TEXT("解像度ウィンドウWin32APIの初期化に失敗しました。\n残念!"),TEXT("エラーコード001"), MB_OK); 283 return -1; 284 } 285 286 if (hmain == NULL) { 287 //エラーコード002 288 MessageBox(NULL,TEXT("メインウィンドウWin32APIの初期化に失敗しました。\n残念!"),TEXT("エラーコード002"), MB_OK); 289 return -1; 290 } 291 292 //ウィンドウループ 293 while(TRUE) { 294 GetMessage(&msg , NULL , 0 , 0); 295 //もし解像度ウィンドウが閉じられたのであれば、メインウィンドウを閉じる 296 if(bquitwindow == true) { 297 PostQuitMessage(0); 298 return 0; 299 } 300 DispatchMessage(&msg); 301 DispatchMessage(&msg1); 302 } 303 return msg.wParam; 304 return msg1.wParam; 305}
です。
ご回答よろしくお願いします。
そもそもですが、ご提示のコードのもとのメッセージループも変です。
無用なデータが入ったままのMSG msg1 をDispatchMessageしているし、returnが2つあったり、PostQuitMessage()の実行後にすぐreturnしていたりして、正しい処理はされていないと思います。
> while(TRUE) {
> GetMessage(&msg , NULL , 0 , 0);
> //もし解像度ウィンドウが閉じられたのであれば、メインウィンドウを閉じる
> if(bquitwindow == true) {
> PostQuitMessage(0);
> return 0;
> }
> DispatchMessage(&msg);
> DispatchMessage(&msg1);
> }
> return msg.wParam;
> return msg1.wParam;
すみません。
いろいろ自力で修正していたのでごちゃごちゃなところがあるかもしれません。
解説サイトではPostQuitMessageの後にすぐにreturnしていらっしゃったので私もそうしていました。
現在、ほかの回答者の方のダイアログボックスを作る方法を試しています。
> 解説サイトではPostQuitMessageの後にすぐにreturnしていらっしゃったので私もそうしていました。
恐らくそれはウィンドウプロシージャ(質問者さんの例ですとWndProcやWndProc1)でのWM_DESTROYメッセージの処理、です。使っている場所が違うはずです。一応コメントしておきます。