トップページ > 記事閲覧
仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる
名前:ドル 日時: 2020/07/27 17:35

こんにちは。 お世話になっております。 ここの掲示板の以下のスレッドを参考にして、キーからでもウィンドウ最大化ボタンからでも仮想フルスクリーンが可能なコードを書きました。 https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=3421 https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4179 キー入力によるフルスクリーンの切り替えは特に問題はありませんでした。 しかしウィンドウ最大化ボタンの方は、1回目のフルスクリーンの時のみ描画領域の下の方が僅かに短くなっており、その後キー入力でウィンドウモードに戻してから再び最大化ボタンを押すと問題なくフルスクリーンになります。 ちなみに短くなっている部分の幅が何となくですがウィンドウのタイトルバーぐらいのサイズに近い気もします。 以下がソースコードです。 #include "DxLib.h" #define SCREEN_SIZE_X (640) #define SCREEN_SIZE_Y (480) int NowWindowSizeX ; int NowWindowSizeY ; int WindowPositionX ; int WindowPositionY ; // 初期状態では仮想フルスクリーンモードはOFF int VirtualFullScreenMode = FALSE ; // ウインドウのアクティブ状態が変化したら呼ばれるコールバック関数 int ActiveStateChangeCallbackFunction( int ActiveState, void *UserData ) { // 仮想フルスクリーンモードが OFF の場合は特に何もしない if( VirtualVirtualFullScreenMode == FALSE ) { return 0 ; } // アクティブになったのかどうかで処理を分岐 if( ActiveState ) { // アクティブになったらウインドウの表示優先順位を最前面に表示する設定に変更 SetWindowZOrder( DX_WIN_ZTYPE_TOPMOST, TRUE ) ; } else { // 非アクティブになったらウインドウの表示優先順位を標準に戻す SetWindowZOrder( DX_WIN_ZTYPE_NORMAL, FALSE ) ; } return 0 ; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int DesktopSizeX ; int DesktopSizeY ; int GameScreen ; int x, add ; int AltPlusEnter ; // デスクトップの情報を取得する GetDefaultState( &DesktopSizeX, &DesktopSizeY, NULL ) ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // 最大化ボタン付きウインドウにする SetWindowStyleMode( 7 ) ; // ウインドウサイズにソフトの画面をフィットさせない設定にする SetWindowSizeChangeEnableFlag( FALSE, FALSE ) ; // ソフト画面のサイズはデスクトップと同じにする SetGraphMode( DesktopSizeX, DesktopSizeY, 32 ) ; // ウインドウのサイズはソフト画面のサイズにする SetWindowSize( SCREEN_SIZE_X, SCREEN_SIZE_Y ) ; // ウインドウの初期位置はデスクトップ画面の中心にする SetWindowPosition( ( DesktopSizeX - SCREEN_SIZE_X ) / 2, ( DesktopSizeY - SCREEN_SIZE_Y ) / 2 ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { return -1 ; } // アクティブ状態が変化したときに呼ばれるコールバック関数の登録 SetActiveStateChangeCallBackFunction( ActiveStateChangeCallbackFunction, NULL ) ; // ソフト画面描画用の描画対象に出来る画像を作成 GameScreen = MakeScreen( SCREEN_SIZE_X, SCREEN_SIZE_Y, FALSE ) ; // メインループ x = 0 ; add = 8 ; while( ProcessMessage() == 0 ) { // 現在のウインドウのサイズを取得する GetWindowSize( &NowWindowSizeX, &NowWindowSizeY ) ; // ALT + ENTER が押されたかどうかを取得しておく AltPlusEnter = GetInputSystemChar( TRUE ) == CTRL_CODE_CR ; // ウインドウモードで、且つウインドウのサイズがソフト画面のサイズではなくなった場合( 最大化ボタンが押された場合 )か、 // 又は ALT + ENTER が押されたら擬似フルスクリーンモードにする if( VirtualFullScreenMode == FALSE && ( ( NowWindowSizeX != SCREEN_SIZE_X && NowWindowSizeY != SCREEN_SIZE_Y ) || AltPlusEnter ) ) { // 擬似フルスクリーンモードかどうかのフラグを立てる VirtualFullScreenMode = TRUE ; // ウインドウをクライアント領域以外何も無いタイプにする SetWindowStyleMode( 4 ) ; // ウインドウの表示優先順位を最前面に表示する設定に変更 SetWindowZOrder( DX_WIN_ZTYPE_TOPMOST ) ; // ウインドウの位置をデスクトップの一番左上に移動 SetWindowPosition( 0, 0 ) ; // ウインドウサイズをデスクトップと同じにする SetWindowSize( DesktopSizeX, DesktopSizeY ) ; } else // 擬似フルスクリーンモードで、且つ ALT + ENTER が押されたらウインドウモードにする if( VirtualFullScreenMode == TRUE && AltPlusEnter ) { // 擬似フルスクリーンモードかどうかのフラグを倒す VirtualFullScreenMode = FALSE ; // 最大化ボタン付きウインドウにする SetWindowStyleMode( 7 ) ; // ウインドウの表示優先順位を標準に戻す SetWindowZOrder( DX_WIN_ZTYPE_NORMAL ) ; // ウインドウの位置を元に戻す SetWindowPosition( WindowPositionX, WindowPositionY ) ; // ウインドウのサイズをソフト画面と等しくする SetWindowSize( SCREEN_SIZE_X, SCREEN_SIZE_Y ) ; } // ウインドウモードの場合はウインドウの座標を取得しておく if( VirtualFullScreenMode == FALSE ) { GetWindowPosition( &WindowPositionX, &WindowPositionY ) ; } // 描画先をソフト画面描画用のグラフィックハンドルにする SetDrawScreen( GameScreen ) ; // 画面のクリア ClearDrawScreen() ; // 移動 x += add ; if( x < 0 || x > 640 ) add = -add ; // 四角形の描画 DrawBox( x, 0, x + 64, 0 + 64, GetColor( 255,255,255 ), TRUE ) ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // 擬似フルスクリーンモードかどうかで処理を分岐 if( VirtualFullScreenMode == TRUE ) { // 仮想フルスクリーンモードの場合 int ScalingSizeX, ScalingSizeY ; // ゲーム画面の拡大描画のサイズを算出 ScalingSizeX = DesktopSizeY * GAME_SCREEN_SIZE_X / GAME_SCREEN_SIZE_Y ; if( ScalingSizeX < DesktopSizeX ) { ScalingSizeY = DesktopSizeY ; } else { ScalingSizeX = DesktopSizeX ; ScalingSizeY = DesktopSizeX * GAME_SCREEN_SIZE_Y / GAME_SCREEN_SIZE_X ; } // 余りの部分を塗りつぶし if( ScalingSizeX != DesktopSizeX || ScalingSizeY != DesktopSizeY ) { if( ScalingSizeX < DesktopSizeX ) { DrawBox( 0, 0, ( DesktopSizeX - ScalingSizeX ) / 2, DesktopSizeY, GetColor( 0, 0, 0 ), TRUE ) ; DrawBox( DesktopSizeX - ( DesktopSizeX - ScalingSizeX ) / 2, 0, DesktopSizeX, DesktopSizeY, GetColor( 0, 0, 0 ), TRUE ) ; } else { DrawBox( 0, 0, DesktopSizeX, ( DesktopSizeY - ScalingSizeY ) / 2, GetColor( 0, 0, 0 ), TRUE ) ; DrawBox( 0, DesktopSizeY - ( DesktopSizeY - ScalingSizeY ) / 2, DesktopSizeX, DesktopSizeY, GetColor( 0, 0, 0 ), TRUE ) ; } } // ゲーム画面を拡大描画 SetDrawMode( DX_DRAWMODE_BILINEAR ) ; DrawExtendGraph( ( DesktopSizeX - ScalingSizeX ) / 2, ( DesktopSizeY - ScalingSizeY ) / 2, DesktopSizeX - ( DesktopSizeX - ScalingSizeX ) / 2, DesktopSizeY - ( DesktopSizeY - ScalingSizeY ) / 2, GameScreen, FALSE ) ; } else { // ウインドウモードの場合は等倍でソフト画面描画用のグラフィックハンドルを描画 DrawGraph( 0, 0, GameScreen, FALSE ) ; } // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }
メンテ

Page: 1 |

Re: 仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる ( No.1 )
名前:管理人 日時:2020/07/29 01:00

載せていただいたソースコードで現象を確認できました ウィンドウ最大化ボタン自体がウィンドウの形状を変更する動作を行うため、 プログラムでの仮想フルスクリーンの処理と動作が被ってしまって正常な 処理が行われないようです ウィンドウ最大化ボタンを押したら ALT + ENTER が押されたことにするための関数を 追加しましたので、よろしければこちらの関数を追加したバージョンをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 以下の関数を追加しました // メインウインドウの最大化ボタンが押されたときの挙動を設定する // BehaviorType 最大化ボタンが押されたときの動作タイプ //     0 = 標準動作 //     1 = 標準動作は行わず、ALTキー+ENTERキーが押されたことにする int SetWindowMaximizeButtonBehavior( int BehaviorType ) ; こちらの関数に 1 を渡して呼ぶと最大化ボタンが押されると ALT + ENTER が押された ことになりますので、載せていただいたソースコードで正常な仮想フルスクリーン動作が 行われるようになります よろしければお試しください m(_ _)m
メンテ
Re: 仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる ( No.2 )
名前:ドル 日時:2020/07/29 10:26

対応、ありがとうございます。 問題が解決したことを確認いたしました。 ただ、ALTキー+ENTERキーをフルスクリーン切り替えに使っていたのは参考元のソースから一時的に同じにしただけであり、今後は別のキーにしたいと考えておりました。 そこで非常に申し訳ないのですが、押されたことにするキーを固定せずに、汎用性も兼ねて自由にキーを設定できる様に出来ませんか? 例えば今回新規追加して頂いた SetWindowMaximizeButtonBehavior の第2引数(デフォルト引数でALT + ENTER)と言う様な形というのはどうでしょうか。 お手数ですが、もし可能なら対応のほどよろしくお願いします。
メンテ
Re: 仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる ( No.3 )
名前:管理人 日時:2020/07/29 23:12

> 押されたことにするキーを固定せずに、汎用性も兼ねて自由にキーを設定できる様に出来ませんか? > 例えば今回新規追加して頂いた SetWindowMaximizeButtonBehavior の第2引数(デフォルト引数でALT + ENTER)と言う様な形というのはどうでしょうか。 可能ですが、それは『ALT + 何かのキー』ということでしょうか? それとも『何かのキー一つだけ』ということでしょうか? それとも『ALT ではなく、CTRL + 何かのキーや、SHIFT + 何かのキー』でしょうか? 組み合わせによって処理が変わってきますので、よろしければドルさんが使用されたい キー押下の形態を教えてください m(_ _)m
メンテ
Re: 仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる ( No.4 )
名前:ドル 日時:2020/07/30 08:27

単純にDXライブラリでマクロ定義されている『キー定義』と『アスキーコントロールキーコード』を引数で渡せばいいのではと思いましたが、こちらの2つは値が重複しているものもあるみたいですね。 一つの関数の中でこれらのキーの判別が難しそうであれば、例えばキー定義バージョンとアスキーコントロールキーコードバージョン(他にもSHIFTキー同時押しバージョン等)、キー押下の形態によって複数の関数に別けることで汎用性が増すと思います。 私は個人的にはファンクションキーを使用しようと思っているので、キー定義を引数として渡せるものがあれば良いですが。
メンテ
Re: 仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる ( No.5 )
名前:管理人 日時:2020/07/31 01:52

ご返答ありがとうございます すみません、あの後『最大化ボタンが押されたかどうか』を取得できるようにすれば、キー入力に 置き換える処理は必要が無いということに気付きました なので、SetWindowMaximizeButtonBehavior( 1 ); を設定した場合は、最大化ボタンが押されたかどうかを CheckWindowMaximizeButtonInput という新たに追加した関数で確認するように処理を変更しました その変更を加えたバージョンをアップしましたので、何度も申し訳ありませんが よろしければダウンロードしてください m(_ _;m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 以下の関数を追加しました // メインウインドウの最大化ボタンが押されたかどうかを取得する // ( SetWindowMaximizeButtonBehavior( 1 ); が実行されている場合のみ有効な関数 ) // StateResetFlag TRUE = 押された状態をリセットする FALSE = 押された状態をリセットしない int CheckWindowMaximizeButtonInput( int StateResetFlag ) ; そして SetWindowMaximizeButtonBehavior の注釈が以下のように変更となりました // メインウインドウの最大化ボタンが押されたときの挙動を設定する // BehaviorType // 0 = 標準動作 // 1 = 標準動作は行わず、最大化ボタンが押されたかどうかは CheckWindowMaximizeButtonInput で判定する int SetWindowMaximizeButtonBehavior( int BehaviorType ) ; そして最初に載せていただいたソースコードで CheckWindowMaximizeButtonInput を使う場合は、DxLib_Init の前か後に SetWindowMaximizeButtonBehavior( 1 ); を書いて、加えて // ALT + ENTER が押されたかどうかを取得しておく AltPlusEnter = GetInputSystemChar( TRUE ) == CTRL_CODE_CR ; こちらの部分を // ALT + ENTER か、最大化ボタンが押されたかどうかを取得しておく AltPlusEnter = GetInputSystemChar( TRUE ) == CTRL_CODE_CR || CheckWindowMaximizeButtonInput( TRUE ) ; このように変更します というわけで、SetWindowMaximizeButtonBehavior の機能ではキー入力に置き換えをしなくなりましたので、 キーによるフルスクリーンへの変更はドルさんのお好みの形で実装してください m(_ _;m
メンテ
Re: 仮想フルスクリーンにてウィンドウ最大化ボタンによる1回目のフルスクリーンの時のみ不具合が起こる ( No.6 )
名前:ドル(解決) 日時:2020/07/31 08:47

無事目的の処理が可能になった事を確認しました。 重ね重ねの対応ありがとうございました。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存