質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VC++

VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

ウィンドウ

コンピューター用語において、ウィンドウとはユーザとプログラムのやり取りを可能にするGUIの枠組みのことをいいます。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

Q&A

1回答

386閲覧

起動時のウィンドウサイズが変わってしまったのを元に戻したい

kamozaka

総合スコア12

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

VC++

VC++ (Visual C++) とは、Microsoft製のC++のための統合開発環境です。

ウィンドウ

コンピューター用語において、ウィンドウとはユーザとプログラムのやり取りを可能にするGUIの枠組みのことをいいます。

DirectX

DirectX(ダイレクトエックス)は、 マイクロソフトが開発したゲーム・マルチメディア処理用のAPIの集合です。

0グッド

0クリップ

投稿2023/05/31 10:52

編集2023/05/31 23:26

実現したいこと

開発中のゲームプログラムのウィンドウのサイズが詳細不明な原因で変化してしまった。Windows10が記憶していると思われるウィンドウサイズの設定をリセットし、元のサイズで起動する状態に戻したい。

詳細

Windows 10でVisual Studio Community 2022を使用し、書籍「シューティングゲーム プログラミング」の付属C++プログラム(DirectX9使用)を一部改変して開発をしていた所、下記のような現象に遭遇しました。

(1) ゲーム用のウィンドウのサイズは横800x縦600とソース中で指定されているにも関わらず、何故か1000x750と思しきサイズで起動される。「1000」「750」でソース中を検索してもウィンドウサイズを制御しているような箇所は見つからず、このサイズになる理由は不明。

(2) 本プログラムにはウィンドウをAlt+Enterでフルスクリーンモードにする機能が実装されている。フルスクリーンモードにしてからウィンドウモードに戻すと、ウィンドウサイズは何故かソース中で指定されている800x600になる。1000x750になるのがバグであり、これが本来のウィンドウサイズである可能性あり(でも小さくて見づらい…)。

(3) 一度でもフルスクリーンモードにしたことのある実行ファイルは、以降は元のサイズである1000x750で起動することができなくなり、ずっと800x600で起動されるようになってしまう。
但し、実行ファイルのファイルパスが少しでも違えば、また1000x750で起動される。例えばフォルダ名や実行ファイル名を変更すればそうなる。

(4) ウィンドウが小さいと見づらいと考え、ソース中のウィンドウサイズ指定部分を800x600から1000x750に変更すると、ウィンドウサイズはその通りになるものの、ウィンドウ内のレイアウト(キャラクタや文字などがどこに配置されるか)が崩れてしまう。従ってこれだけでは解決にならない。

実行ファイルパスが変化すると元に戻ることから、エクスプローラなどのウィンドウと同じように、OSが実行ファイルパスごとに起動時のウィンドウサイズを記憶しているのではないか?と推測しました。

だとすれば、その記憶をリセットするなりして、「既に800x600で起動されるようになってしまった実行ファイルパスで、また1000x750で起動される」ようにしたいのですが、そのようなことは可能でしょうか?

本来なら、ソースにあると思われるバグを修正し、根本的解決を図りたいところなのですが、それには時間がかかりそうなので、とりあえずウィンドウサイズを元に戻すことで、開発しにくい環境から脱したいと考えました。

具体的なソースの提示もしたいところなのですが、著作権上の問題がないように該当部分だけを切り出して実行可能なものに仕立てるのはなかなか大変なので、一旦このような形で質問させて頂くことにしました。

[追記]
やはりソースを提示すべきとのご指摘を頂いたので提示します。
挙げていくとキリがなさそうですが、関係のありそうな箇所を抜粋してみました。

ゲームクラスの定義部:

C++

1// ゲーム本体のクラス 2class CGame 3{ 4protected: 5 6 // アクセラレータキー 7 HACCEL HAccel; 8 9 // ウィンドウハンドル 10 HWND HWnd; 11 12 // グラフィックス 13 CGraphics* Graphics; 14 15 // 入力 16 CInput* Input; 17 MOUSE_STATE Mouse; 18 19 // 実行ファイルのパス、アプリケーション名、ヘルプのURL 20 string ExePath, HelpURL; 21 wstring AppName; 22 23 // 速度調整 24 LARGE_INTEGER LastPerfCounter; 25 DWORD LastTickCount; 26 double Elapsed; 27 void ResetTime(); 28 29 // 一時停止 30 bool Pause, MenuPause; 31 32 // メニュー 33 bool UseMenu; 34 HMENU MenuBar; 35 36 // 終了確認 37 bool ConfirmExit; 38 39 // 画面サイズ、リフレッシュレート 40 int WindowWidth, WindowHeight, FullScreenWidth, FullScreenHeight, 41 RefreshRate; 42 bool FullScreen; 43 44 void DrawScene(); 45 46public: 47 48 // コンストラクタ,デストラクタ 49 CGame( const wchar_t* app_name, bool zbuffer, bool use_menu, bool fixed_size ); 50 ~CGame(); 51 52 // メッセージハンドラ 53 virtual LRESULT WINAPI WndProc( UINT msg, WPARAM wparam, LPARAM lparam ); 54 55 // ゲームの実行 56 void Run(); 57 58 // 各種設定 59 double FPS; 60 bool DropFrames, PauseInTheBackground; 61 62 // 移動と描画: 63 // サブクラスでオーバーライドする 64 virtual void Move() {} 65 virtual void Draw() {} 66 67 // Direct3Dリソースの管理 68 virtual void OnLostDevice() {} 69 virtual void OnResetDevice() {} 70 71 // メニュー 72 HMENU GetMenuBar() { return MenuBar; } 73 HMENU AddMenu( string text ); 74 HMENU AddSubMenu( HMENU menu, string text ); 75 void AddMenuItem( HMENU menu, string text, int id ); 76 void AddMenuSeparator( HMENU menu ); 77 void CheckMenuItem( HMENU menu, int id, bool check ); 78 79 // 各種情報の取得 80 CGraphics* GetGraphics() { return Graphics; } 81 CInput* GetInput() { return Input; } 82 const MOUSE_STATE& GetMouseState() { return Mouse; } 83 84 // 終了確認 85 void SetConfirmExit( bool ce ) { ConfirmExit = ce; } 86 87 // 画面モードの切り替え 88 void ResetScreen(); 89 void ToggleFullScreen(); 90};

ゲームクラスのコンストラクタ:

C++

1 2//============================================================== 3// <CGame>コンストラクタ 4CGame::CGame( const wchar_t* app_name, bool zbuffer, bool use_menu, bool fixed_size ) 5 : Pause( false ), MenuPause( false ), UseMenu( use_menu ), ConfirmExit( true ), 6 FPS( 60 ), DropFrames( true ), PauseInTheBackground( true ), 7 WindowWidth( 800 ), WindowHeight( 600 ), 8 FullScreenWidth( 800 ), FullScreenHeight( 600 ), 9 FullScreen( false ), RefreshRate( 60 ) 10{ 11 // アプリケーション名,実行ファイルのパス、ヘルプのURL 12 AppName = app_name; 13 ExePath = GetExePath(); 14 HelpURL = ""; 15 16 // アイコンの読み込み 17 HINSTANCE hinst = GetModuleHandle( NULL ); 18 HICON icon; 19 string icon_file = ExePath + "game.ico"; 20 if ( FileExists( icon_file ) ) 21 { 22 icon = (HICON) LoadImage( 23 hinst, CStringW( icon_file.c_str() ), 24 IMAGE_ICON, 0, 0, LR_LOADFROMFILE ); 25 } 26 else 27 { 28 icon = LoadIcon( hinst, MAKEINTRESOURCE( 1 ) ); 29 } 30 31 // ウィンドウクラスの登録: 32 // ここではダミーのメッセージハンドラを登録する 33 WNDCLASSEX wc = { 34 sizeof( WNDCLASSEX ), 35 CS_CLASSDC, 36 DummyWndProc, 37 0L, 38 0L, 39 hinst, 40 icon, 41 LoadCursor( NULL, IDC_ARROW ), 42 NULL, 43 NULL, 44 app_name, 45 NULL 46 }; 47 RegisterClassEx( &wc ); 48 49 // アクセラレータキーの設定: 50 // [ESC] : 終了 51 // [Alt]+[Enter] : 画面モード切り替え 52 // [F1] : ヘルプ 53 // [Shift]+[F1]:バージョン表示 54 ACCEL accel [] = { 55 {FVIRTKEY, VK_ESCAPE, IDC_EXIT}, 56 {FALT | FVIRTKEY, VK_RETURN, IDC_TOGGLEFULLSCREEN}, 57 {FVIRTKEY, VK_F1, IDC_HELPURL}, 58 {FSHIFT | FVIRTKEY, VK_F1, IDC_VERSION} 59 }; 60 HAccel = CreateAcceleratorTable( 61 accel, sizeof( accel ) / sizeof( ACCEL ) ); 62 63 // コマンドラインオプションの解釈 64 for ( int i = 1; i < __argc; i++ ) 65 { 66 char* s = __argv[ i ]; 67 if ( strcmp( "-w", s ) == 0 && ++i < __argc ) 68 { 69 WindowWidth = FullScreenWidth = atoi( __argv[ i ] ); 70 } 71 else 72 if ( strcmp( "-h", s ) == 0 && ++i < __argc ) 73 { 74 WindowHeight = FullScreenHeight = atoi( __argv[ i ] ); 75 } 76 else 77 if ( strcmp( "-ww", s ) == 0 && ++i < __argc ) 78 { 79 WindowWidth = atoi( __argv[ i ] ); 80 } 81 else 82 if ( strcmp( "-wh", s ) == 0 && ++i < __argc ) 83 { 84 WindowHeight = atoi( __argv[ i ] ); 85 } 86 else 87 if ( strcmp( "-fw", s ) == 0 && ++i < __argc ) 88 { 89 FullScreenWidth = atoi( __argv[ i ] ); 90 } 91 else 92 if ( strcmp( "-fh", s ) == 0 && ++i < __argc ) 93 { 94 FullScreenHeight = atoi( __argv[ i ] ); 95 } 96 if ( strcmp( "-r", s ) == 0 && ++i < __argc ) 97 { 98 RefreshRate = atoi( __argv[ i ] ); 99 } 100 if ( strcmp( "-f", s ) == 0 ) 101 { 102 FullScreen = true; 103 } 104 if ( strcmp( "-nce", s ) == 0 ) 105 { 106 ConfirmExit = false; 107 } 108 } 109 110 // ウィンドウの作成 111 long style = WS_CAPTION | WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; 112 RECT r = { 0, 0, WindowWidth, WindowHeight }; 113 AdjustWindowRect( &r, style, false ); 114 115 HWnd = CreateWindow( 116 CStringW( app_name ), 117 CStringW( app_name ), 118 style, 119 0, 120 0, 121 r.right - r.left, 122 r.bottom - r.top, 123 GetDesktopWindow(), 124 NULL, 125 wc.hInstance, 126 NULL 127 ); 128 129 HWndCGameMap.insert( 130 THWndCGameMap::value_type( HWnd, this ) ); 131 132 // グラフィックスの作成 133 Graphics = new CGraphics( HWnd ); 134 if ( !Graphics ) 135 { 136 string s = 137 "このプログラムにはDirectX 9.0以上が必要です。\n" 138 "DirectXの最新版、および最新のドライバが\n" 139 "インストールされているかどうかご確認ください。\n"; 140 if ( !fixed_size ) 141 { 142 s += 143 "また、起動時のオプションで解像度を変更してみてください。\n\n" 144 "ウィンドウ時800x600、フルスクリーン1024x768の場合:\n" 145 "-w 800 -h 600 -fw 1024 -fh 768"; 146 } 147 MessageBox( HWnd, CStringW( s.c_str() ), CStringW( app_name ), MB_OK ); 148 exit( 1 ); 149 } 150 Graphics->Clear(); 151 Graphics->Present(); 152 if ( FullScreen ) ResetScreen(); 153 154 // 入力の初期化 155 Input = new CInput( HWnd ); 156 Mouse.X = Mouse.Y = 0; 157 Mouse.LButton = Mouse.MButton = Mouse.RButton = false; 158 159 // 時間 160 LastPerfCounter.QuadPart = 0; 161 LastTickCount = 0; 162 Elapsed = 0; 163 164 // メニュー 165 if ( UseMenu ) 166 { 167 MenuBar = CreateMenu(); 168 SetMenu( HWnd, MenuBar ); 169 } 170}

ウィンドウモード/フルスクリーンモード切り替えに関する箇所:

C++

1// 画面のリセット 2void CGame::ResetScreen() 3{ 4 if ( FullScreen ) 5 { 6 Graphics->SetWidth( FullScreenWidth ); 7 Graphics->SetHeight( FullScreenHeight ); 8 Graphics->SetRefreshRate( RefreshRate ); 9 } 10 else 11 { 12 Graphics->SetWidth( WindowWidth ); 13 Graphics->SetHeight( WindowHeight ); 14 Graphics->SetRefreshRate( 0 ); 15 } 16 Graphics->SetFullScreen( FullScreen ); 17 OnLostDevice(); 18 if ( Graphics->ResetDevice() ) OnResetDevice(); 19} 20 21// ウィンドウモードとフルスクリーンモードの切り替え 22void CGame::ToggleFullScreen() 23{ 24 FullScreen = !Graphics->IsFullScreen(); 25 ResetScreen(); 26} 27

よろしくお願い致します。

補足

本プログラムは、今となっては古いプログラムではありますが、上記の現象についてはバグらしき挙動であるものの、他の部分に関しては概ね正常に動作しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2023/05/31 18:00

「ある書籍」とは具体的に何でしょうか? 書籍名を明示して、ウィンドウのサイズを指定している部分のコードを貼るのは、引用の基準を充分満たすと思います。
kamozaka

2023/05/31 23:27

コメントありがとうございます。 書籍名を明示し、ソースのうち関係のありそうな箇所を追記しました。
fana

2023/06/07 09:03

数値からだけの憶測ですが,1000x750 というのは 800x600 の 1.25 倍であることから, ディスプレイの設定が 125% になってるとかそういう方向の話なのかな? とか. (高DPI対応とかなんとかいうやつ.1000x750になるとき,表示内容がきたなくぼけた感じに引き伸ばされてたりしません?)
guest

回答1

0

[香車]東上☆あらし☆海美「
まず、質問へのコメントにもあるように『ある書籍』を明示するべきだと考えるみみ。
DirectX 9 や 32bit Windows のサポートは、次々と終了しているようなので、
DirectX 9 のプログラムはあきらめて、
DirectX 12 on 64 bit Windows での開発に切り替えては ?

投稿2023/05/31 21:31

umimi

総合スコア231

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamozaka

2023/05/31 23:29

回答ありがとうございます。 書籍名を明示し、ソースのうち関係のありそうな箇所を追記しました。 > DirectX 9 や 32bit Windows のサポートは、次々と終了しているようなので、 > DirectX 9 のプログラムはあきらめて、 > DirectX 12 on 64 bit Windows での開発に切り替えては ? なるほど、もうサポートが終了しているんですね。 今のところは概ね大丈夫そうなのですが、サポート外のものを使い続けると「新しめのWindowsではまともに動かない」みたいなことが起こるのでしょうか。 必要に応じて最新版への移行は検討したいと思います。 ただ、現状で私が頼りにしている主な教材が ・書籍『シューティングゲーム プログラミング』 https://www.amazon.co.jp/シューティングゲーム-プログラミング-松浦-健一郎/dp/4797337214 ・書籍『ゲームプログラマになる前に覚えておきたい技術』 https://www.amazon.co.jp/ゲームプログラマになる前に覚えておきたい技術-平山-尚/dp/4798021180 ・Webサイト『ゲームつくろー!』 http://marupeke296.com/GameMain.html 辺りであり、いずれもDirectX9がメインなのですよね。 これは、私が昔から着目している教材で、長年かけて断続的に学習をしていることが理由です。 DirectXのバージョンの古さに目を瞑れば、いずれも普遍性のある優れた教材だと思いますので、 少なくともDirectXにある程度習熟するまでは使い続けたいと考えています。 (あ、でも新しいDirectXに関する良い教材があれば、教えて頂けると大変ありがたいです。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問