• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:突然ですが、DirectX9について質問させて頂きます。)

DirectX9に関するウィンドウサイズの変化問題

このQ&Aのポイント
  • DirectX9を使用してウィンドウモードとフルスクリーンモードを切り替える際、画面サイズが変化する問題が発生しています。
  • 問題の関数であるSetWindowStyleとSetClientSizeを確認すると、ウィンドウのサイズ変更時に正しい値が設定されていないことが分かりました。
  • この問題を解決するためには、ウィンドウのサイズを変更する際に正確な値を指定する必要があります。

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

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.4

>クライアント領域のみをキャプチャ、サイズを測定しています。 キャプチャ画像からでは、デスクトップの解像度に よっては縦横比が変わった場合、正しいウィンドウサイズの 値が取得できないと思います。 #縦長になったり、横長になったりします。 >初期状態がどうあれ、後に値が変化することは想定外ですので。 >試しに、ウィンドウモードを変更する直前にスクリーン座標を退避、 >復帰時に退避した座標を適用、といった動作も試しましたが、結果はまったく >同じでした。 サイズを変更するAPIを呼び出している以上、設定した値が おかしいのだとは思いますが、スクリーン座標を補完する事に 意味があるのでしょうか?変更するまえの位置に表示したい などの場合以外では縦横のサイズの変化には、 あまり意味が無いような気がします。 >MoveWindow( hWnd, 0, 0, 0, 0, false ); >をコメントアウトしただけでも正しく表示されません。 原点に移動し、ウィンドウサイズを0,0に指定していますが、 実際にはウィンドウは0,0にならずにシステムメニューなどの サイズで最小サイズとしてデスクトップ上に残るため、 (本当にそうなのかは微妙ですが、私の環境ではそうなりました。) このサイズをGetWindowRect、GetClientRectで取得し この時おそらく、クライアント領域の高さは0に成ると思うので その状態で、タイトルやメニューのサイズを算出しているのでは?? もし、上記のコードで設定した値0,0,0,0が、 GetWindowRectで取得された場合は、 ウィンドウ全体のサイズが800x600となり システムメニュー分の高さがクライアント領域から 引かれる可能性は無きにしも在らずですが、 本来であれば、メニューのサイズやタイトルのサイズは GetSystemMetrics関数で取得するのが最も正確な値となると思うので、 そちらを使うというのも一つの手だとは思います。 ただ、ウィンドウサイズを調べる場合は、 きちんとAPIなどで取得した値を見たほうが良いと思います。 開発環境でのキャプチャ画像などから実測すると、 実行環境での誤差が出る可能性が高いです。

ClickHere
質問者

お礼

ご回答、ありがとうございます。 どうやら、 フルスクリーンから復帰(この時点でフレームは描画されていない)⇒ ウィンドウサイズを変更(この時点で、正しく動作していない)⇒ クライアント領域の上にフレームが描画される⇒ 結果、タイトルバーの分だけサイズが小さくなる、というものの様です。 原因はよく分かりませんが、引数は関係ないことだけは確認できました。

その他の回答 (3)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

机上だとわかり難かったので試してみました。 わたしの環境では試したころ、提示されたコードでは、 ウィンドウサイズは特に問題なく動作しているようで、 808x627という値が毎回設定されていました。 以下の補足をお願いします。 #少し大きくなっていますが、 #タイトルバーなどを考慮したサイズにはなっているようです。 >800x576と値がおかしくなります。 この値はどの様に確認されたのでしょうか? #わたしはデバッグウィンドウで確認しました。 また、この値は、Window領域のものでしょうか? それとも、DirectXのデバイスに与えているサイズでしょうか? DirectXにはスクリーンモードがありますので、 これを変更する場合には、デバイスの再作成が必要となりますが。。。 補足の内容からすると、 ウィンドウモード→フルスクリーンモード→ウィンドウモードの 時に値がおかしくなるということで良いでしょうか? DirectXのサイズを変更と成ると少し話が違ってくるので。。。

ClickHere
質問者

お礼

ご回答、ありがとうございます。 私は、ウィンドウキャプチャアプリケーションを使用して、 クライアント領域のみをキャプチャ、サイズを測定しています。 そのため、通常は800x600になるように計算してありますので、数値の 間違いは無いと思います。 そして、当面の問題はこのウィンドウサイズの矛盾ですね。 初期状態がどうあれ、後に値が変化することは想定外ですので。 試しに、ウィンドウモードを変更する直前にスクリーン座標を退避、 復帰時に退避した座標を適用、といった動作も試しましたが、結果はまったく 同じでした。 また、SetWindowStyle関数内6行目の MoveWindow( hWnd, 0, 0, 0, 0, false ); をコメントアウトしただけでも正しく表示されません。 SetClientSize関数内で同関数は実行されているのですが…。 気のせいか、メニューバーのサイズ分だけ、差し引かれているような気が…。 近々試してみる予定です(仮にそれで直ったところで、結局、原因は不明なままですが)。 度々ご迷惑をお掛けしますが、ご回答頂けると幸いです。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.2

No1です。 >ウィンドウサイズの変更を行っていませんので、 よく見たら、ウィンドウサイズは毎回変更されていますね。。。 ウィンドウモードの場合は、クライアント領域を800x600にするように ウィンドウモードに変更する際に、タイトルやメニューの高さを 考慮すれば正しく、調整されると思います。

ClickHere
質問者

お礼

ご回答、ありがとうございます。 最初の投稿へのご返答ですが、ウィンドウのサイズが…は、 クライアントサイズが…が正しい表現でしたね。御幣がありました。 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600 上記の定義も欠落していました。 ですが、タイトルバーの長さはSetClientSize関数で考慮されていると思うのですが…。 実際、アプリ起動時にこの関数を呼び出して、クライアントサイズは800x600となっていますので。 メニューバは最初から追加していないので、考慮する必要性はないと思うのですが…?

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

起動時はフルスクリーンモードで WINDOW_WIDTH = 800 WINDOW_HEIGHT = 600 ということでしょうか? まず、基本的なところですが、 ウィンドウ領域とクライアント領域の違いを理解されていますでしょうか? また、なぜウィンドウサイズの変更が必要なのかを理解されていますか? ウィンドウ領域とは、そのウィンドウの全体の領域を指します(タイトル領域や メニュー領域ステータスバー、サイズ変更バーやボーダの領域を含んだ領域) クライアント領域とは上記の、タイトルやボーダーを含まないサイズとなります。 通常、ポップアップウィンドウはタイトルバーなどが存在しないため、 ウィンドウ領域とクライアント領域は基本的に等しくなります。 オーバーラップウィンドウは、タイトルバーやボーダーなどが、 加味されるため、ウィンドウ領域とクライアント領域が等しくなりません。 この為、「ウィンドウスタイル」を切り替える場合は、 ウィンドウサイズの変更が必要に成るわけです。 #モードだけ変更するならば、そもそもウィンドウサイズを #変更する必要はありません。 #(まぁ、ウィンドウ自体にはモードという概念はありませんが。) 提示されたプログラムでは、ウィンドウモードに変更された時しか ウィンドウサイズの変更を行っていませんので、 フルスクリーンからウィンドウモードに切り替えると、 タイトル分ずれてウィンドウサイズが変更され、 ウィンドウモードからフルスクリーンに切り替えると、 変更されたウィンドサイズがそのまま使用されることになります。

ClickHere
質問者

お礼

ご回答、ありがとうございます。 ウィンドウのフレームのサイズは考慮してリサイズしています(多分)。 ややこしいソースになってしまいましたが、ご指摘お願いします。

関連するQ&A