突然ですが、DirectX9について質問させて頂きます。
ウィンドウモードとフルスクリーンモードを切り替える
プログラムを組んでいますが、なぜか、フルスクリーンモード
からウィンドウモードに復帰すると画面サイズが変化してしまいます。
以下がその問題となる関数です。
void SetWindowStyle( HWND hWnd, bool g_WindowMode )
{
if( g_WindowMode )
{
SetWindowLong( hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE );
MoveWindow( hWnd, 0, 0, 0, 0, false );
SetClientSize( hWnd, WINDOW_WIDTH, WINDOW_HEIGHT );// 以下に記載
}
else
{
SetWindowLong( hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE );
MoveWindow( hWnd, 0, 0, 800, 600, true );
}
}
以下はウィンドウのサイズを再設定する関数です。
void SetClientSize( HWND hWnd, int width, int height )
{
RECT wnd_Rect, clt_Rect;
int WindowSize_Width, WindowSize_Height;
GetWindowRect( hWnd, &wnd_Rect );
GetClientRect( hWnd, &clt_Rect );
// ウィンドウのサイズを求める
WindowSize_Width = ( wnd_Rect.right - 1 ) - ( wnd_Rect.left - 1 );
WindowSize_Height = ( wnd_Rect.bottom - 1 ) - ( wnd_Rect.top - 1 );
// ウィンドウのサイズを変更
MoveWindow( hWnd,
wnd_Rect.left,
wnd_Rect.top,
width + (WindowSize_Width-clt_Rect.right),
height + (WindowSize_Height-clt_Rect.bottom),
true
);
}
SetClientSize関数はアプリ起動時に一度実行され、800x600に変更されます。
この時点では問題はありません。
しかし、フルスクリーンモード→ウィンドウモードと切り替えると、
800x576と値がおかしくなります。
結果的に800x600になる予定だったのですが…。
同じ関数を使用しているのに、なぜサイズが変化してしまうのでしょう?
どなたかこの問題を解決する方法をご存知ないでしょうか?
よろしくお願いします。
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などで取得した値を見たほうが良いと思います。
開発環境でのキャプチャ画像などから実測すると、
実行環境での誤差が出る可能性が高いです。
ご回答、ありがとうございます。
どうやら、
フルスクリーンから復帰(この時点でフレームは描画されていない)⇒
ウィンドウサイズを変更(この時点で、正しく動作していない)⇒
クライアント領域の上にフレームが描画される⇒
結果、タイトルバーの分だけサイズが小さくなる、というものの様です。
原因はよく分かりませんが、引数は関係ないことだけは確認できました。
No.3
- 回答日時:
机上だとわかり難かったので試してみました。
わたしの環境では試したころ、提示されたコードでは、
ウィンドウサイズは特に問題なく動作しているようで、
808x627という値が毎回設定されていました。
以下の補足をお願いします。
#少し大きくなっていますが、
#タイトルバーなどを考慮したサイズにはなっているようです。
>800x576と値がおかしくなります。
この値はどの様に確認されたのでしょうか?
#わたしはデバッグウィンドウで確認しました。
また、この値は、Window領域のものでしょうか?
それとも、DirectXのデバイスに与えているサイズでしょうか?
DirectXにはスクリーンモードがありますので、
これを変更する場合には、デバイスの再作成が必要となりますが。。。
補足の内容からすると、
ウィンドウモード→フルスクリーンモード→ウィンドウモードの
時に値がおかしくなるということで良いでしょうか?
DirectXのサイズを変更と成ると少し話が違ってくるので。。。
ご回答、ありがとうございます。
私は、ウィンドウキャプチャアプリケーションを使用して、
クライアント領域のみをキャプチャ、サイズを測定しています。
そのため、通常は800x600になるように計算してありますので、数値の
間違いは無いと思います。
そして、当面の問題はこのウィンドウサイズの矛盾ですね。
初期状態がどうあれ、後に値が変化することは想定外ですので。
試しに、ウィンドウモードを変更する直前にスクリーン座標を退避、
復帰時に退避した座標を適用、といった動作も試しましたが、結果はまったく
同じでした。
また、SetWindowStyle関数内6行目の
MoveWindow( hWnd, 0, 0, 0, 0, false );
をコメントアウトしただけでも正しく表示されません。
SetClientSize関数内で同関数は実行されているのですが…。
気のせいか、メニューバーのサイズ分だけ、差し引かれているような気が…。
近々試してみる予定です(仮にそれで直ったところで、結局、原因は不明なままですが)。
度々ご迷惑をお掛けしますが、ご回答頂けると幸いです。
No.2
- 回答日時:
No1です。
>ウィンドウサイズの変更を行っていませんので、
よく見たら、ウィンドウサイズは毎回変更されていますね。。。
ウィンドウモードの場合は、クライアント領域を800x600にするように
ウィンドウモードに変更する際に、タイトルやメニューの高さを
考慮すれば正しく、調整されると思います。
ご回答、ありがとうございます。
最初の投稿へのご返答ですが、ウィンドウのサイズが…は、
クライアントサイズが…が正しい表現でしたね。御幣がありました。
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
上記の定義も欠落していました。
ですが、タイトルバーの長さはSetClientSize関数で考慮されていると思うのですが…。
実際、アプリ起動時にこの関数を呼び出して、クライアントサイズは800x600となっていますので。
メニューバは最初から追加していないので、考慮する必要性はないと思うのですが…?
No.1
- 回答日時:
起動時はフルスクリーンモードで
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
ということでしょうか?
まず、基本的なところですが、
ウィンドウ領域とクライアント領域の違いを理解されていますでしょうか?
また、なぜウィンドウサイズの変更が必要なのかを理解されていますか?
ウィンドウ領域とは、そのウィンドウの全体の領域を指します(タイトル領域や
メニュー領域ステータスバー、サイズ変更バーやボーダの領域を含んだ領域)
クライアント領域とは上記の、タイトルやボーダーを含まないサイズとなります。
通常、ポップアップウィンドウはタイトルバーなどが存在しないため、
ウィンドウ領域とクライアント領域は基本的に等しくなります。
オーバーラップウィンドウは、タイトルバーやボーダーなどが、
加味されるため、ウィンドウ領域とクライアント領域が等しくなりません。
この為、「ウィンドウスタイル」を切り替える場合は、
ウィンドウサイズの変更が必要に成るわけです。
#モードだけ変更するならば、そもそもウィンドウサイズを
#変更する必要はありません。
#(まぁ、ウィンドウ自体にはモードという概念はありませんが。)
提示されたプログラムでは、ウィンドウモードに変更された時しか
ウィンドウサイズの変更を行っていませんので、
フルスクリーンからウィンドウモードに切り替えると、
タイトル分ずれてウィンドウサイズが変更され、
ウィンドウモードからフルスクリーンに切り替えると、
変更されたウィンドサイズがそのまま使用されることになります。
ご回答、ありがとうございます。
ウィンドウのフレームのサイズは考慮してリサイズしています(多分)。
ややこしいソースになってしまいましたが、ご指摘お願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「アイテムは収集されました」...
-
エクセルで作った新しいウイン...
-
ラジオボタンの初期指定
-
C言語でWin32APIを使い、子ウィ...
-
検索の画面がでなくなってしま...
-
勝手にウィンドウが開いて止ま...
-
他のアプリケーションの終了処理
-
作成したウインドウのサイズを...
-
BUTTON型のウィンドウに入力欄...
-
常に非アクティブなウィンドウ...
-
パソコン関連)何度消してもま...
-
DellノートPC購入で悩んでいま...
-
ゲームでは結局どっちが良いの?
-
ウィンドウハンドルの取得方法
-
[Windows API]隠れているWindow...
-
「&HFFFF」「&H1A」とは?
-
win32apiにおける終了処理について
-
[VBA] UserForm を Excel の W...
-
親ウインドウにあるOKボタンを...
-
最大化と最小化ボタン
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
検索の画面がでなくなってしま...
-
ゲームでは結局どっちが良いの?
-
ExcelのBOOKが消えた!
-
VBA .Value=.Value ?
-
[VBA] UserForm を Excel の W...
-
ラジオボタンの初期指定
-
勝手にウィンドウが開いて止ま...
-
Excelの上下を固定したい
-
【VB2008】 マウス操作の一時的...
-
「&HFFFF」「&H1A」とは?
-
作成したウインドウのサイズを...
-
親ウインドウにあるOKボタンを...
-
他のアプリケーションの終了処理
-
MFC ダイアログ上のID取得につ...
-
ExcelVBAでAPIを使って外部ウイ...
-
EnumChildWindowsの使い方(VBA)
-
Alt+P,Alt+NをPostmessageで送...
-
Vba LongPtrについて教えてくだ...
おすすめ情報