トップページ > 記事閲覧
ウィンドウサイズ変更の制限方法
名前:むち 日時: 2016/02/06 23:05

初めて質問を投稿させて頂きます。 WindowsOS、DXライブラリを利用したVC++2015の環境で、 メインウィンドウのサイズを変更できる様にする関数を用いた際、 その最小・最大(上限・下限)のサイズを設定したいのですが、 方法が分からず、その方法を教えて頂けないでしょうか。 関数はSetWindowSizeChangeEnableFlagを用いて居ます。 自分の求める最小・最大のサイズを超えて居た際に、サイズを変更する事で、 擬似的に実装する事はできるのですが、 それはプレイヤーがサイズを変更した後であって、もっと何と言うか、基本的な方法があると思うのですが、 中々どうして分からず、意地を張らずに、素直に質問させて頂く事にしました。 そもそも、自分なりに調べてみて、 MINMAXINFOやthisポインタを使った方法がある様だと分かったのですが、 WINメッセージを受け取るとか、非静的メンバ関数について等、全然分かりません…。 やはりこう、制限を設けるだけなら、難しい話では無いと思うのですが、 恥を忍んで、質問させて頂きます。 長文駄文、御手数を御掛けして申し訳ないです。 また、コメントを頂けた際の返信は、早くても明朝になってしまいます。すみません。 どうぞ、よろしくお願いします。
メンテ

Page: 1 |

Re: ウィンドウサイズ変更の制限方法 ( No.1 )
名前:管理人 日時:2016/02/07 03:40

メインウインドウのサイズ変更に制限ですか… ちょっとご質問なのですが、ウインドウのサイズ変更のタイプはどちらでしょうか? 1.ウインドウのサイズに応じてゲーム画面が拡大・縮小されるのみで、表示される内容は変化しない(情報量は増減しない)タイプ 2.ウインドウのサイズに応じてゲーム画面が拡大・縮小されず、大きくすればそれだけゲーム画面の表示面積が増え(情報量が増え)、  小さくすればそれだけゲーム画面の表示面積が減る(情報量が減る)タイプ
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.2 )
名前:むち 日時:2016/02/07 15:24

返信が遅くなり申し訳ないです。 ずばり、2 です。 SetWindowSizeChangeEnableFlagの第2引数に、 FALSEを指定して、 ディスプレイ(複数画面?は考えて居ません)の、 タスクバーを除いた画面サイズで、 SetGraphModeを用いて、描画領域?を指定してから、 ソフト画面右上の縮小(元に戻す)ボタン用として、 それより小さな画面(DXライブラリの標準サイズ?である640*480) にサイズを戻した上で、 先述の画面サイズに変更し、 ソフトを立ち上げた段階では画面いっぱいの最大サイズ、 右上の縮小ボタンで最小サイズ(640*480)にできるようにして居ます。 この掲示板等で拝見した情報を基にして居ます。 この程度では継ぎ接ぎの様で、少し悪気を感じます。 ちなみに、プレイヤーへの情報量は増減しますが、 描画する量は、見えないだけで、同じ…と言う認識をして居ます。 制限したい理由としては、予期せぬ動作を防ぐためです。 今は、自分用に、ちょっとしたツールとして、こう言う、 ウィンドウサイズを自由に変更できる機能を 持たせようとして居ます。 そのため、一般的なツール系のソフトの様に、 2の様にして居ます。1では困ってしまいます。 ですが、ゆくゆくは、次にゲームを作る際にも、 これは利用したい、と考えて居ます。 端的に言って、あったら便利だなと思います。
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.3 )
名前:管理人 日時:2016/02/08 03:53

ご返答ありがとうございます ご事情は理解できた・・・と思います 早速ユーザーが操作できるウインドウのサイズを制限する為の機能を追加してみましたので、 よろしければこちらのバージョンをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_DevCppTest.exe // Dev-C++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) 上記のバージョンでは以下の関数を追加しました // メインウインドウのクライアント領域の最大サイズを設定する // ( SetWindowSizeChangeEnableFlag の第一引数を TRUE で呼び出して、 // ウインドウのサイズが変更できる状態でのみ使用されるパラメータです ) int SetWindowMaxSize( int MaxWidth, int MaxHeight ) ; 注釈の通り引数で指定されたサイズ以上にメインウインドウのクライアント領域を広げられないようにします 因みに今のところユーザーがウインドウサイズを操作した場合のサイズ変更に制限を加える為のものなので、 例えば既にメインウインドウのクライアント領域が 1280x768 のサイズになっている状態で SetWindowMaxSize( 640, 480 ) ; を実行しても、メインウインドウのサイズが縮むことはありません ( 関数が呼ばれた後、ユーザーがウインドウのサイズを変更しようとしたときに縮みます ) なので、もしそのような使用の仕方をされたい場合は SetWindowSize と併用するようにしてください m(_ _)m
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.4 )
名前:むち 日時:2016/02/08 11:55

こちらこそ、御早い返答を頂き、ありがとうございます。 すみません。 まだ、機能を追加して頂いたバージョンを試しても居ないのですが、 文面から察するに、最大サイズに対してのみ、制限を加えられる関数を 用意して頂いた…と言うことでしょうか。 実は、私が主に制限したいのは、 小さくする方での下限です…。 640*480よりも小さくして欲しく無い、と言う事です。 私の言葉が、手探りと言いますか、的確で無かったのだと思います。 もしかすると、小さくする方で制限を設けると言うのは、 何かこう、ソフト関係では可笑しな発想なのでしょうか…。 確かに、よくよく考えてみれば、際限無く大きく成る方が、困りますよね…。 サイズを制限する為の機能と言う事で、 小さくする方にも何か追加して頂いて居るのかも知れません。 先述の通り、まだ試しても居ないのに、 この様な不躾な言葉を返し、ごめんなさい。 主に小さくする方に制限を設けたい理由としては、 メインウィンドウのクライアント領域のサイズに対して、 一つ一つの内容のサイズを設定して描画して居るのですが、 その画面が小さく成って行く際に、 どの内容を残して、画面に映るように描画するか、 設定していく事になるかと思うのですが、 殆どの内容をプレイヤーが視認できない様な、小さな画面にする事、 それへの対応をする事が、何と言いますか、 不毛だなと思いまして、下限を設けたいと考えました。 因みに、大きくする方に対しては、 その下限を標準として、内容が見易く成る程度で、 形を変形させたり、特殊な事をする予定はありません。 際限無く大きく出来れば、内容量が増えて、 いつかはメモリ等?を圧迫するかと思います。 しかし、巨大なディスプレイや、 ディスプレイよりもサイズを大きくすると言う事が、 小さくする事よりは、そうそう無い事かなと思って居ます。 また、小さくする方に制限を加えられる様にすると言う事は、 自然と、大きくする方にも制限を加えるものだろうと考え、 最初に投稿した際、最小・最大と、最小を先に記した上で、 最大を付け加える形で、質問させて頂きました。 今思えば、どっちつかずと言いますか、幅広く捉えられる様にしてしまい、 誤解かどうかは分かりませんが、 理解できたかどうか困惑させてしまうぐらい、 分かり辛い文章だったと思います。 貴重な御時間を割いて頂いて居るのに、 本当に申し訳無いです…。
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.5 )
名前:むち 日時:2016/02/08 12:40

早速、SetWindowMaxSizeを試させて頂きました。 正に、この通りです。 ドラッグして大きくする際に、設定したサイズよりも、 大きくできない様にできて、とても嬉しいです。 可能であれば、直前に投稿させて頂いた通り、 小さくする方に対しても、 この関数と同じ様に、制限を加えられる関数を用意して頂ければ、 この上無く、想定通りの事が行えます。 管理人様の例えにつきましては、 元から、同じ様に、制限を加えたいと考えて居ただけで、 それを用いてリサイズする様な事は考えて居りませんでした。 DXライブラリユーザー向けの例えだとは思いますが、 一応、私の方では全く問題無い事を、伝えさせて頂きます。 殆ど蛇足の様な言葉ばかりで申し訳無いのですが、 最初の投稿では、方法を教えて頂ければ是幸いとばかりに考えて居たのですが、 過去の掲示板の流れを見れば、掲示板に投稿する事、 是即ち、新しい関数を提案する、追加して頂くと言う事だと分かる筈です。 全く考えて居無かった訳ではありませんが、 こうして関数を追加して頂いて、本当に嬉しいです。 余分な言葉ばかりで、分かり辛いかと思いますが、 要するに、本当に嬉しく、感謝の気持ちで一杯です。 ありがとうございます。
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.6 )
名前:管理人 日時:2016/02/11 14:00

すみません、最初のお書き込みにある「最小・最大(上限・下限)のサイズを設定したい」 という部分を失念していました 最小サイズを設定する為の関数も追加しましたので、何度もお手数で申し訳ありませんが よろしければこちらをダウンロードしてください m(_ _;m https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_DevCppTest.exe // Dev-C++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) 以下の関数を追加しました // メインウインドウのクライアント領域の最小サイズを設定する // ( SetWindowSizeChangeEnableFlag の第一引数を TRUE で呼び出して、 // ウインドウのサイズが変更できる状態でのみ使用されるパラメータです ) int SetWindowMinSize( int MinWidth, int MinHeight ) ; よろしければお試しください > こうして関数を追加して頂いて、本当に嬉しいです。 私も要望をいただいてはじめて「あ、そういえば何で今までその機能無かったんだろう…」と 思うようなことも多々あるので( 本件もそのケースです )利用して頂いている方からご意見・ ご要望を頂けると私も嬉しいです ( 常にご要望にお応えできる訳ではありませんが… (・・;; )
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.7 )
名前:むち 日時:2016/02/12 21:56

> 「あ、そういえば何で今までその機能無かったんだろう…」 やはり、そうですよね! 「私の発想が変なのかな…。誰も言って居ないみたいだから、やっぱり変なのかな…。」と 質問するべきか、とても悩んだのですが、 勇気…を出して良かったです! 返信、遅れてしまい、すみません。 恐らく、月曜ぐらいまで、 私用で、追加して居た内容を試す事が出来ません。 来週、改めて、きちんと返事を返させて頂き、 解決とさせて頂こうと思います。 また後日となりますが、どうぞよろしくお願いします。
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.8 )
名前:むち 日時:2016/02/18 06:14

約一週間、返信が遅れてしまい、ごめんなさい。 私事ですが、遠出したり、警察に通報されたり…、 中々に心の折れる一週間でした…。 それは捨て置き、追加して頂いた関数を試させて頂きました。 私が望んで居た通りの挙動で、とても満足です! ありがとうございます! 本当にこう、これを活用させて頂き、色んな作品を作りたいなと、 胸が躍ります! 今回、最初は質問と言う形から始まった話としては、 これで解決と言う事に成るのですが、 DXライブラリの、ウィンドウサイズを変更する際の挙動としては、 私は、もう一つ、気掛かりな事があります。 それは、ドラッグしてサイズを変更中の際、 画面が止まる?プログラムが一時停止する…何と言ったら良いか分かりませんが、 サイズ変更中も、内容の描画を更新し続ける事を選択できたら、 とても良いなと思います。 これは何か制約があっての事かも知れませんが、 これが叶うと、例えば、 ウィンドウの大きさに合わせてリサイズされて表示される、 オリジナルのスクロールバーと言ったものが、 プレイヤー、ユーザーから見て、綺麗に滑らかに、自然に見えると思います。 改めて別のスレッド?として投稿させて頂くべきか悩んだのですが、 こちらで続けさせて頂いた方が良いかなと思いました。 クライアント領域リサイズ中の描画更新一時停止の解除 を選択する事は可能なのか、 また、こうして話を拡大させてしまって良かったのか…。 更に質問、要望と、忙しくさせてしまい、すみません…。 再びとなりますが、どうぞ、よろしくお願い致しします。
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.9 )
名前:むち 日時:2016/02/18 06:28

すみません。付け加えさせて下さい。 リサイズの例えが、分かり辛い様に思いましたので、 改めて例えさせて下さい。 先の例えとは少し違いますが、 クライアント領域のサイズに合わせて表示したい、 枠等の、下地の上に、別のレイヤーとして、上の層に表示する様な、 そんな感じの場合が多々あると思うのです。 画面を舞う花弁の様なものなら、最大化した画面に合わせて、 最初から全体に描画して置けば良いと思うのですが、 ウィンドウの中に、枠を設ける様な際は、 ウィンドウのリサイズ中に、 枠が、リサイズを始めた瞬間の大きさのまま、 ドラッグ中は表示されてしまうので、 やはり、プレイヤー、ユーザーからは不自然に見えると思います。 ゲーム風に例えれば、 常に、ウィンドウの四隅の定位置に、 スコアやアイテム等の名称を、 表示して置きたいと思うのですが、 それがリサイズ中、短い間とは言え、 四隅では無く、画面の中途半端な位置に残されて描画されてしまうのは、 やはり気になると思います。 長文なだけで、分かり辛いかと思いますが、 思いが伝わったら幸いです。
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.10 )
名前:管理人 日時:2016/02/21 04:46

ウインドウのサイズを変更している途中もプログラムが一時停止しないようにするためには 時間経過処理や描画処理をメインスレッドとは別のスレッドで行う必要があります ( ウインドウのサイズを変更している間、ProcessMessage 関数から処理が戻ってこないため ) ただ、手元で試したところそれだけではエラーが発生してしまったので、 エラーが発生しないようにするための関数を追加しました よろしければその関数を追加したこちらのバージョンをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_DevCppTest.exe // Dev-C++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) とりあえず『描画を別のスレッドで行い、ウインドウのクライアント領域のサイズより 16ピクセル小さい四角形を描画する、ウインドウのサイズが変更されている間も、その動作は止まらない』 という処理を実行するプログラムを組んでみましたので、よろしければご覧ください #include "DxLib.h" volatile int EndFlag ; volatile int EndCompFlag ; // 描画処理スレッド用関数 DWORD WINAPI DrawThread( LPVOID ) { int Width, Height ; // EndFlag が 0 の間はループ while( EndFlag == 0 ) { // 画面の初期化 ClearDrawScreen() ; // ウインドウのサイズを取得 GetWindowSize( &Width, &Height ) ; // ウインドウのサイズより 16ピクセル小さい矩形を描画 DrawBox( 16, 16, Width - 16, Height - 16, GetColor( 255,255,255 ), TRUE ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; // 少し待つ Sleep( 1 ) ; } // EndCompFlag を 1 にする EndCompFlag = 1 ; return 0 ; } // WinMain 関数 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { HANDLE ThreadHandle ; DWORD ThreadID ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // サイズ可変ウインドウの設定 SetWindowSizeChangeEnableFlag( TRUE, FALSE ) ; // ウインドウサイズをセット SetGraphMode( 1280, 480, 32 ) ; // 非アクティブ時も処理を止めないようにする SetAlwaysRunFlag( TRUE ) ; // DXライブラリの WM_PAINT メッセージの処理を行わないようにする SetUseDxLibWM_PAINTProcess( FALSE ) ; // DXライブラリ初期化 if( DxLib_Init() == -1 ) { return -1 ; } // 描画対象を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // 描画用スレッドを起動 ThreadHandle = CreateThread( NULL, 0, DrawThread, 0, 0, &ThreadID ); // メインループ while( ProcessMessage() == 0 ) { Sleep( 16 ) ; } // EndFlag を 1 にする EndFlag = 1 ; // EndCompFlag が 1 になるまで待つ while( EndCompFlag == 0 ) { Sleep( 16 ) ; } // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0 ; } 『ウインドウのサイズを変更している最中もプログラムを止めない』を実現するための方法は 以下の通りです  1.SetAlwaysRunFlag( TRUE ) ; を実行して、『ウインドウが非アクティブでもプログラムを止めない』設定にする  2.SetUseDxLibWM_PAINTProcess( FALSE ) ; を実行してDXライブラリの WM_PAINT の処理を実行しないようにする    ( SetUseDxLibWM_PAINTProcess が今回追加した関数です )  3.時間経過処理や描画処理をメインスレッドとは別のスレッドで行う ただ、DXライブラリは複数のスレッドからDXライブラリの関数が呼ばれることを想定していないので、 時間経過処理や描画処理をメインスレッドとは別のスレッドで行う場合は以下のことも守る必要があります  1.非同期読み込み機能を使ってのファイル読み込み( SetUseASyncLoadFlag( TRUE ) ; 設定での読み込み )は   必ずメインスレッドで実行する  2.ストリーミングタイプ( SetCreateSoundDataType( DX_SOUNDDATATYPE_MEMNOPRESS ) ; 以外のタイプ )の   サウンドを使った再生・停止の処理は必ずメインスレッドで実行する  3.メインスレッドとメインスレッド以外のスレッドで同時に描画関連の関数を使用したり、同時にサウンド関連の   関数を使用するとクラッシュするので、絶対同時に実行することの無いようにする 『ウインドウサイズを変更している際もプログラムを止めない』為にはメインスレッド以外で描画処理や時間経過の 処理を行わなければならないのに、ファイル読み込みやサウンド処理の一部はメインスレッドで行わなければ ならないという制限がありますが、現状で『ウインドウサイズを変更している際もプログラムを止めない』を 実現するには上記の方法しかありません… 因みにサンプルのプログラムを実行して頂ければわかりますが、今回の方法を使用してもウインドウのサイズを 変更した際は内部の描画が1フレーム遅れます( サンプルプログラムでは『ウインドウのクライアント領域の サイズより16ピクセル小さい四角形』がウインドウの枠に完璧には付いて来ないことで確認できます )が、 この1フレームの遅れについては今のところ解決策はありません…
メンテ
Re: ウィンドウサイズ変更の制限方法 ( No.11 )
名前:むち(解決) 日時:2016/02/26 16:00

一週間近く返信が遅れてしまい、すみません。 何と返信すれば良いか悩んで居ました。 実は、管理人さんが他のスレッドを含め、 一つずつ返信されていらっしゃる時に、 丁度、こちらの掲示板を見て居まして、 直ぐに、提示して頂いた方法を試してみて居ました。 サンプルの方の挙動を確認し、 1フレームの遅れなんて、素早く動かせば一般のウィンドウでも起こる事だから、 これで完璧だ!と思い、とても感激しました。 しかし、自分の作り掛けのプログラムに導入しようとすると、 沢山のエラー、管理人さんの述べて居るクラッシュが起こりまして、 多くのDXライブラリの関数を、これも述べられて居る通り、 制限の下に構築し直さなければいけないのだと気付きました。 私が先に投稿させて頂いた様に、 ちょっと気になる程度の事でしか無いので、 そのために、その制限に合わせ無ければいけないのは、 何と言いますか、憂鬱な気持ちに陥りそうになります。 今まで、このウィンドウサイズを変更する関連の質問が無かったのは、 DXライブラリで行うべきでは無い事だったからなのでは無いか、 そう言う風に思い至りました。 私は、一応、それなりに長い期間、DXライブラリを用いて、 趣味程度ですが、独学でプログラミングをして来ました。 何か基本的な事が行えて居ないのかも知れませんが、 自分が作ろうとして居たものは、一度、諦めようかなと思います。 また、これも何か私の早とちりかも知れませんが、 KeyInputStringでも、ウィンドウサイズを変更して居る時の様に、 描画が止まると言いますか、プログラムが止まるのですね…。 親身に話に付き合って頂き、ありがとうございます。 一応、質問させて頂いた内容は、全て解決に導いて頂き、 無事、解決しましたので、これで解決とさせて頂きます。 また何か返信を頂ければ、きちんと返事をさせて頂きます。 先述の通り、自分の方で、色々と悩んでしまって居ますので、 少し色々と考えを纏めたい次第です。 何と言いますか、歯切れの悪い解決になってしまい、 こんな冗長な文の私にも、親身に付き合って頂いたのに、 とても申し訳ないです…。 しかし、私としては、ここで投稿できた事、 管理人さんと話をできた事が、とても嬉しいです。 何と言いますかばかりですが、何と言いますか、 掲示板にそぐわない文章の様にも思え、 本当に申し訳ないです…。 自分勝手な独り善がりなコメントで、これまた申し訳ないですが、 これにて、解決とさせて頂きます。 本当に、ありがとうございます。
メンテ

Page: 1 |

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

   クッキー保存