質問編集履歴

1

本文の修正、ソースの追加

2023/05/31 23:26

投稿

kamokamo
kamokamo

スコア12

test CHANGED
File without changes
test CHANGED
@@ -1,12 +1,12 @@
1
1
  ### 実現したいこと
2
2
 
3
- 開発中のゲームプログラムのウィンドウに関してWindows10が記憶していると思われるウィンドウサイズの設定をリセットし、元のサイズで起動する状態に戻したい。
3
+ 開発中のゲームプログラムのウィンドウのサイズが詳細不明な原因で変化してしまった。Windows10が記憶していると思われるウィンドウサイズの設定をリセットし、元のサイズで起動する状態に戻したい。
4
4
 
5
5
  ### 詳細
6
6
 
7
- Windows 10でVisual Studio Community 2022を使用し、ある書籍ゲーム開発系)の付属C++プログラム(DirectX9使用)を一部改変して開発をしていた所、下記のような現象に遭遇しました。
7
+ Windows 10でVisual Studio Community 2022を使用し、書籍「[シューティングゲーム プログラミング](https://www.amazon.co.jp/シューティングゲーム-プログラミング-松浦-健一郎/dp/4797337214)」の付属C++プログラム(DirectX9使用)を一部改変して開発をしていた所、下記のような現象に遭遇しました。
8
-
8
+
9
- (1) ゲーム用のウィンドウのサイズは横800x縦600とソース中で指定されているにも関わらず、何故か1000x750と思しきサイズで起動される。「750」でソース中を検索してもヒットしないので、このサイズになる理由は不明。
9
+ (1) ゲーム用のウィンドウのサイズは横800x縦600とソース中で指定されているにも関わらず、何故か1000x750と思しきサイズで起動される。「1000」「750」でソース中を検索してもウィンドウサイズを制御ているよう箇所は見つからず、このサイズになる理由は不明。
10
10
 
11
11
  (2) 本プログラムにはウィンドウをAlt+Enterでフルスクリーンモードにする機能が実装されている。フルスクリーンモードにしてからウィンドウモードに戻すと、ウィンドウサイズは何故かソース中で指定されている800x600になる。1000x750になるのがバグであり、これが本来のウィンドウサイズである可能性あり(でも小さくて見づらい…)。
12
12
 
@@ -23,6 +23,307 @@
23
23
 
24
24
  具体的なソースの提示もしたいところなのですが、著作権上の問題がないように該当部分だけを切り出して実行可能なものに仕立てるのはなかなか大変なので、一旦このような形で質問させて頂くことにしました。
25
25
 
26
+ [追記]
27
+ やはりソースを提示すべきとのご指摘を頂いたので提示します。
28
+ 挙げていくとキリがなさそうですが、関係のありそうな箇所を抜粋してみました。
29
+
30
+ ゲームクラスの定義部:
31
+ ```C++
32
+ // ゲーム本体のクラス
33
+ class CGame
34
+ {
35
+ protected:
36
+
37
+ // アクセラレータキー
38
+ HACCEL HAccel;
39
+
40
+ // ウィンドウハンドル
41
+ HWND HWnd;
42
+
43
+ // グラフィックス
44
+ CGraphics* Graphics;
45
+
46
+ // 入力
47
+ CInput* Input;
48
+ MOUSE_STATE Mouse;
49
+
50
+ // 実行ファイルのパス、アプリケーション名、ヘルプのURL
51
+ string ExePath, HelpURL;
52
+ wstring AppName;
53
+
54
+ // 速度調整
55
+ LARGE_INTEGER LastPerfCounter;
56
+ DWORD LastTickCount;
57
+ double Elapsed;
58
+ void ResetTime();
59
+
60
+ // 一時停止
61
+ bool Pause, MenuPause;
62
+
63
+ // メニュー
64
+ bool UseMenu;
65
+ HMENU MenuBar;
66
+
67
+ // 終了確認
68
+ bool ConfirmExit;
69
+
70
+ // 画面サイズ、リフレッシュレート
71
+ int WindowWidth, WindowHeight, FullScreenWidth, FullScreenHeight,
72
+ RefreshRate;
73
+ bool FullScreen;
74
+
75
+ void DrawScene();
76
+
77
+ public:
78
+
79
+ // コンストラクタ,デストラクタ
80
+ CGame( const wchar_t* app_name, bool zbuffer, bool use_menu, bool fixed_size );
81
+ ~CGame();
82
+
83
+ // メッセージハンドラ
84
+ virtual LRESULT WINAPI WndProc( UINT msg, WPARAM wparam, LPARAM lparam );
85
+
86
+ // ゲームの実行
87
+ void Run();
88
+
89
+ // 各種設定
90
+ double FPS;
91
+ bool DropFrames, PauseInTheBackground;
92
+
93
+ // 移動と描画:
94
+ // サブクラスでオーバーライドする
95
+ virtual void Move() {}
96
+ virtual void Draw() {}
97
+
98
+ // Direct3Dリソースの管理
99
+ virtual void OnLostDevice() {}
100
+ virtual void OnResetDevice() {}
101
+
102
+ // メニュー
103
+ HMENU GetMenuBar() { return MenuBar; }
104
+ HMENU AddMenu( string text );
105
+ HMENU AddSubMenu( HMENU menu, string text );
106
+ void AddMenuItem( HMENU menu, string text, int id );
107
+ void AddMenuSeparator( HMENU menu );
108
+ void CheckMenuItem( HMENU menu, int id, bool check );
109
+
110
+ // 各種情報の取得
111
+ CGraphics* GetGraphics() { return Graphics; }
112
+ CInput* GetInput() { return Input; }
113
+ const MOUSE_STATE& GetMouseState() { return Mouse; }
114
+
115
+ // 終了確認
116
+ void SetConfirmExit( bool ce ) { ConfirmExit = ce; }
117
+
118
+ // 画面モードの切り替え
119
+ void ResetScreen();
120
+ void ToggleFullScreen();
121
+ };
122
+ ```
123
+ ゲームクラスのコンストラクタ:
124
+ ```C++
125
+
126
+ //==============================================================
127
+ // <CGame>コンストラクタ
128
+ CGame::CGame( const wchar_t* app_name, bool zbuffer, bool use_menu, bool fixed_size )
129
+ : Pause( false ), MenuPause( false ), UseMenu( use_menu ), ConfirmExit( true ),
130
+ FPS( 60 ), DropFrames( true ), PauseInTheBackground( true ),
131
+ WindowWidth( 800 ), WindowHeight( 600 ),
132
+ FullScreenWidth( 800 ), FullScreenHeight( 600 ),
133
+ FullScreen( false ), RefreshRate( 60 )
134
+ {
135
+ // アプリケーション名,実行ファイルのパス、ヘルプのURL
136
+ AppName = app_name;
137
+ ExePath = GetExePath();
138
+ HelpURL = "";
139
+
140
+ // アイコンの読み込み
141
+ HINSTANCE hinst = GetModuleHandle( NULL );
142
+ HICON icon;
143
+ string icon_file = ExePath + "game.ico";
144
+ if ( FileExists( icon_file ) )
145
+ {
146
+ icon = (HICON) LoadImage(
147
+ hinst, CStringW( icon_file.c_str() ),
148
+ IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
149
+ }
150
+ else
151
+ {
152
+ icon = LoadIcon( hinst, MAKEINTRESOURCE( 1 ) );
153
+ }
154
+
155
+ // ウィンドウクラスの登録:
156
+ // ここではダミーのメッセージハンドラを登録する
157
+ WNDCLASSEX wc = {
158
+ sizeof( WNDCLASSEX ),
159
+ CS_CLASSDC,
160
+ DummyWndProc,
161
+ 0L,
162
+ 0L,
163
+ hinst,
164
+ icon,
165
+ LoadCursor( NULL, IDC_ARROW ),
166
+ NULL,
167
+ NULL,
168
+ app_name,
169
+ NULL
170
+ };
171
+ RegisterClassEx( &wc );
172
+
173
+ // アクセラレータキーの設定:
174
+ // [ESC] : 終了
175
+ // [Alt]+[Enter] : 画面モード切り替え
176
+ // [F1] : ヘルプ
177
+ // [Shift]+[F1]:バージョン表示
178
+ ACCEL accel [] = {
179
+ {FVIRTKEY, VK_ESCAPE, IDC_EXIT},
180
+ {FALT | FVIRTKEY, VK_RETURN, IDC_TOGGLEFULLSCREEN},
181
+ {FVIRTKEY, VK_F1, IDC_HELPURL},
182
+ {FSHIFT | FVIRTKEY, VK_F1, IDC_VERSION}
183
+ };
184
+ HAccel = CreateAcceleratorTable(
185
+ accel, sizeof( accel ) / sizeof( ACCEL ) );
186
+
187
+ // コマンドラインオプションの解釈
188
+ for ( int i = 1; i < __argc; i++ )
189
+ {
190
+ char* s = __argv[ i ];
191
+ if ( strcmp( "-w", s ) == 0 && ++i < __argc )
192
+ {
193
+ WindowWidth = FullScreenWidth = atoi( __argv[ i ] );
194
+ }
195
+ else
196
+ if ( strcmp( "-h", s ) == 0 && ++i < __argc )
197
+ {
198
+ WindowHeight = FullScreenHeight = atoi( __argv[ i ] );
199
+ }
200
+ else
201
+ if ( strcmp( "-ww", s ) == 0 && ++i < __argc )
202
+ {
203
+ WindowWidth = atoi( __argv[ i ] );
204
+ }
205
+ else
206
+ if ( strcmp( "-wh", s ) == 0 && ++i < __argc )
207
+ {
208
+ WindowHeight = atoi( __argv[ i ] );
209
+ }
210
+ else
211
+ if ( strcmp( "-fw", s ) == 0 && ++i < __argc )
212
+ {
213
+ FullScreenWidth = atoi( __argv[ i ] );
214
+ }
215
+ else
216
+ if ( strcmp( "-fh", s ) == 0 && ++i < __argc )
217
+ {
218
+ FullScreenHeight = atoi( __argv[ i ] );
219
+ }
220
+ if ( strcmp( "-r", s ) == 0 && ++i < __argc )
221
+ {
222
+ RefreshRate = atoi( __argv[ i ] );
223
+ }
224
+ if ( strcmp( "-f", s ) == 0 )
225
+ {
226
+ FullScreen = true;
227
+ }
228
+ if ( strcmp( "-nce", s ) == 0 )
229
+ {
230
+ ConfirmExit = false;
231
+ }
232
+ }
233
+
234
+ // ウィンドウの作成
235
+ long style = WS_CAPTION | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
236
+ RECT r = { 0, 0, WindowWidth, WindowHeight };
237
+ AdjustWindowRect( &r, style, false );
238
+
239
+ HWnd = CreateWindow(
240
+ CStringW( app_name ),
241
+ CStringW( app_name ),
242
+ style,
243
+ 0,
244
+ 0,
245
+ r.right - r.left,
246
+ r.bottom - r.top,
247
+ GetDesktopWindow(),
248
+ NULL,
249
+ wc.hInstance,
250
+ NULL
251
+ );
252
+
253
+ HWndCGameMap.insert(
254
+ THWndCGameMap::value_type( HWnd, this ) );
255
+
256
+ // グラフィックスの作成
257
+ Graphics = new CGraphics( HWnd );
258
+ if ( !Graphics )
259
+ {
260
+ string s =
261
+ "このプログラムにはDirectX 9.0以上が必要です。\n"
262
+ "DirectXの最新版、および最新のドライバが\n"
263
+ "インストールされているかどうかご確認ください。\n";
264
+ if ( !fixed_size )
265
+ {
266
+ s +=
267
+ "また、起動時のオプションで解像度を変更してみてください。\n\n"
268
+ "ウィンドウ時800x600、フルスクリーン1024x768の場合:\n"
269
+ "-w 800 -h 600 -fw 1024 -fh 768";
270
+ }
271
+ MessageBox( HWnd, CStringW( s.c_str() ), CStringW( app_name ), MB_OK );
272
+ exit( 1 );
273
+ }
274
+ Graphics->Clear();
275
+ Graphics->Present();
276
+ if ( FullScreen ) ResetScreen();
277
+
278
+ // 入力の初期化
279
+ Input = new CInput( HWnd );
280
+ Mouse.X = Mouse.Y = 0;
281
+ Mouse.LButton = Mouse.MButton = Mouse.RButton = false;
282
+
283
+ // 時間
284
+ LastPerfCounter.QuadPart = 0;
285
+ LastTickCount = 0;
286
+ Elapsed = 0;
287
+
288
+ // メニュー
289
+ if ( UseMenu )
290
+ {
291
+ MenuBar = CreateMenu();
292
+ SetMenu( HWnd, MenuBar );
293
+ }
294
+ }
295
+ ```
296
+ ウィンドウモード/フルスクリーンモード切り替えに関する箇所:
297
+ ```C++
298
+ // 画面のリセット
299
+ void CGame::ResetScreen()
300
+ {
301
+ if ( FullScreen )
302
+ {
303
+ Graphics->SetWidth( FullScreenWidth );
304
+ Graphics->SetHeight( FullScreenHeight );
305
+ Graphics->SetRefreshRate( RefreshRate );
306
+ }
307
+ else
308
+ {
309
+ Graphics->SetWidth( WindowWidth );
310
+ Graphics->SetHeight( WindowHeight );
311
+ Graphics->SetRefreshRate( 0 );
312
+ }
313
+ Graphics->SetFullScreen( FullScreen );
314
+ OnLostDevice();
315
+ if ( Graphics->ResetDevice() ) OnResetDevice();
316
+ }
317
+
318
+ // ウィンドウモードとフルスクリーンモードの切り替え
319
+ void CGame::ToggleFullScreen()
320
+ {
321
+ FullScreen = !Graphics->IsFullScreen();
322
+ ResetScreen();
323
+ }
324
+
325
+ ```
326
+
26
327
  よろしくお願い致します。
27
328
 
28
329
  ### 補足