DXライブラリのウィンドウ関係で
-
L'z
DXライブラリのウィンドウ関係で
ウィンドウ関係のことで質問が3つあります
1.ウィンドウモードをタイトルバーなしの1または2にしたいと思っています
数字はSetWindowStyleMode関数の引数です
しかし、このモードでは最小化ができません
タスクバーの右クリックでも最小化が使えないようになっていました
ウィンドウモードでタイトルバーなしを使って最小化を許可するにはどうすればいいのでしょうか?
2.タイトルバーなしにするとウィンドウの移動もできなくなります
つくろうとしているものはマウス操作を使わないのでゲーム内でマウスをクリックしたまま動かせば
ウィンドウも動くようにしたいです
ゲームではないですがGOM Playerのような感じです
これを可能にする方法が知りたいです
調べてみましたが具体的な方法がみつからなかったのでプログラム例も書いていただけると幸いです
3.ウィンドウサイズを640x360と960x540で作成しています
これは縦横倍にするとHD,FullHDになりフルモードにしたときになめらかになると思ったからなのですが
モニターにこの解像度の設定がなくフルモードにしてもウィンドウモードで実行されてしまいます
なのでフルモードにした場合は1280x720または1920x1080のウィンドウサイズしてフル画面になるように
したいと思っています
ゲーム中のオプションから切り替えるようにしたいと思っています
実行中に画面サイズの変更とウィンドウからフル画面の切り替えを行うときに特殊な操作がいるのでしょうか?
普通に ChangeWindowMode 関数とSetGraphMode 関数を実行するだけでいいのか
それとも変更後に DxLib_Init 関数などを呼ぶ必要があるのか
もし呼ぶならそのときにゲームの開始時点に戻す必要があるのか
ウィンドウサイズを変えると出力するときに2倍にするためにいったんMakeScreenして
それをDrawExtendGraphで2倍にするというような操作が増えるのか
などを教えていただきたいです
以上です
いつもながくてすみません
1.ウィンドウモードをタイトルバーなしの1または2にしたいと思っています
数字はSetWindowStyleMode関数の引数です
しかし、このモードでは最小化ができません
タスクバーの右クリックでも最小化が使えないようになっていました
ウィンドウモードでタイトルバーなしを使って最小化を許可するにはどうすればいいのでしょうか?
2.タイトルバーなしにするとウィンドウの移動もできなくなります
つくろうとしているものはマウス操作を使わないのでゲーム内でマウスをクリックしたまま動かせば
ウィンドウも動くようにしたいです
ゲームではないですがGOM Playerのような感じです
これを可能にする方法が知りたいです
調べてみましたが具体的な方法がみつからなかったのでプログラム例も書いていただけると幸いです
3.ウィンドウサイズを640x360と960x540で作成しています
これは縦横倍にするとHD,FullHDになりフルモードにしたときになめらかになると思ったからなのですが
モニターにこの解像度の設定がなくフルモードにしてもウィンドウモードで実行されてしまいます
なのでフルモードにした場合は1280x720または1920x1080のウィンドウサイズしてフル画面になるように
したいと思っています
ゲーム中のオプションから切り替えるようにしたいと思っています
実行中に画面サイズの変更とウィンドウからフル画面の切り替えを行うときに特殊な操作がいるのでしょうか?
普通に ChangeWindowMode 関数とSetGraphMode 関数を実行するだけでいいのか
それとも変更後に DxLib_Init 関数などを呼ぶ必要があるのか
もし呼ぶならそのときにゲームの開始時点に戻す必要があるのか
ウィンドウサイズを変えると出力するときに2倍にするためにいったんMakeScreenして
それをDrawExtendGraphで2倍にするというような操作が増えるのか
などを教えていただきたいです
以上です
いつもながくてすみません
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: DXライブラリのウィンドウ関係で
本家掲示板より。あちらの掲示板も検索されたほうが良いでしょう。L'z さんが書きました:1.ウィンドウモードをタイトルバーなしの1または2にしたいと思っています
数字はSetWindowStyleMode関数の引数です
しかし、このモードでは最小化ができません
タスクバーの右クリックでも最小化が使えないようになっていました
ウィンドウモードでタイトルバーなしを使って最小化を許可するにはどうすればいいのでしょうか?
「縁無しウィンドウ」
http://hpcgi2.nifty.com/natupaji/bbs/pa ... ast&no=578
どちらかと言うとウィンドウの処理なんですよね。L'z さんが書きました:2.タイトルバーなしにするとウィンドウの移動もできなくなります
つくろうとしているものはマウス操作を使わないのでゲーム内でマウスをクリックしたまま動かせば
ウィンドウも動くようにしたいです
ゲームではないですがGOM Playerのような感じです
これを可能にする方法が知りたいです
調べてみましたが具体的な方法がみつからなかったのでプログラム例も書いていただけると幸いです
これだとDXライブラリの処理は逸脱するのでSetHookWinProc などでWin32APIを自分で処理しないといけないと思います。
本家掲示板の方が詳しい人がいるので質問してみて下さい。
SetGraphMode → ChangeWindowMode で切り替えられるはずです。L'z さんが書きました:3.ウィンドウサイズを640x360と960x540で作成しています
これは縦横倍にするとHD,FullHDになりフルモードにしたときになめらかになると思ったからなのですが
モニターにこの解像度の設定がなくフルモードにしてもウィンドウモードで実行されてしまいます
なのでフルモードにした場合は1280x720または1920x1080のウィンドウサイズしてフル画面になるように
したいと思っています
ゲーム中のオプションから切り替えるようにしたいと思っています
実行中に画面サイズの変更とウィンドウからフル画面の切り替えを行うときに特殊な操作がいるのでしょうか?
普通に ChangeWindowMode 関数とSetGraphMode 関数を実行するだけでいいのか
それとも変更後に DxLib_Init 関数などを呼ぶ必要があるのか
もし呼ぶならそのときにゲームの開始時点に戻す必要があるのか
ウィンドウサイズを変えると出力するときに2倍にするためにいったんMakeScreenして
それをDrawExtendGraphで2倍にするというような操作が増えるのか
などを教えていただきたいです
ただし、SetGraphMode でデータが全て破棄されるので注意して下さい。
「DXライブラリ置き場 リファレンスページ SetGraphMode 」
http://homepage2.nifty.com/natupaji/DxL ... .html#R4N1
あと描画時の2倍は自分で直接DrawExtendGraphするかMakeScreen先に描画してからDrawExtendGraphのどちらかとなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: DXライブラリのウィンドウ関係で
2.は、SetHookWinProcでは実現できないようです。
以下のように自前でサブクラス化すればできました。
以下のように自前でサブクラス化すればできました。
#include "DxLib.h"
static WNDPROC pPrevWndProc;
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_NCHITTEST:
// ウインドウの枠の上にカーソルがあることにする
return HTCAPTION;
}
return CallWindowProc(pPrevWndProc, hWnd ,uMsg ,wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE);
if (DxLib_Init() != 0) return 0;
// ウィンドウのサブクラス化(ウィンドウプロシージャのフック)
pPrevWndProc = (WNDPROC)GetWindowLongPtr(GetMainWindowHandle(), GWLP_WNDPROC);
SetWindowLongPtr(GetMainWindowHandle(), GWLP_WNDPROC , (LONG_PTR)WndProc);
while (ProcessMessage() == 0) {
}
DxLib_End();
return 0;
}
-
L'z
Re: DXライブラリのウィンドウ関係で
softya(ソフト屋) さん
Win32APIでやってみることにします
各処理ごとに2倍にするのはめんどうなのでMakeScreenしたものを最後に倍にする方法にしたいと思います
ありがとうございました
ISLe さん
教えていただいたコードでウィンドウを動かすことが出来ました
すごく助かりました
ありがとうございました
DXライブラリの範囲ではできないのですねsoftya(ソフト屋) さんが書きました: どちらかと言うとウィンドウの処理なんですよね。
これだとDXライブラリの処理は逸脱するのでSetHookWinProc などでWin32APIを自分で処理しないといけないと思います。
Win32APIでやってみることにします
画像やサウンドのロードをしなおせばいいのですねsoftya(ソフト屋) さんが書きました: SetGraphMode → ChangeWindowMode で切り替えられるはずです。
ただし、SetGraphMode でデータが全て破棄されるので注意して下さい。
「DXライブラリ置き場 リファレンスページ SetGraphMode 」
<a href="http://homepage2.nifty.com/natupaji/DxL ... .html#R4N1" target="_blank" rel="noreferrer" style="text-decoration:none;color:#009CE8;cursor:help;display:inline !important;">http://homepage2.nifty.com/natupaji/DxL ... ml#R4N1</a>
あと描画時の2倍は自分で直接DrawExtendGraphするかMakeScreen先に描画してからDrawExtendGraphのどちらかとなります。
各処理ごとに2倍にするのはめんどうなのでMakeScreenしたものを最後に倍にする方法にしたいと思います
ありがとうございました
ISLe さん
教えていただいたコードでウィンドウを動かすことが出来ました
すごく助かりました
ありがとうございました
-
L'z
Re: DXライブラリのウィンドウ関係で
前回「解決!」を押しましたが同じウィンドウのことでまた疑問がありましたのでここに書くことにします。
前回の回答でタイトルバーなし、縁なし、のウィンドウでウィンドウの移動と最小化ができるようになりました。
今回タイトルバーと縁のあり、なしをユーザーが設定で変更できるようにしたいと思いました。
前回はSetWindowStyleModeに2を設定し、SetWindowLongPtrで最小化ボタン(WS_MINIMIZEBOX)をつけていました。
これに縁をつけようとWS_BORDERを設定したのですが縁が出ません。拡張ウィンドウスタイルのWS_EX_DLGMODALFRAME
なども試してみましたがでませんでした。
SetWindowStyleModeを0にして縁ありのものから縁を消そうという方法も試したのですがタイトルバーは消えるのに
縁は消えません。それどころか縁の四隅で変なものが出たり出なかったりします。
SetWindowStyleModeではウィンドウスタイル以外にどこを変更してウィンドウのデザインを変えているのでしょうか?
DXライブラリのソースを読んでもよくわかりませんでした。
どこを変更しているからウィンドウスタイルを変えても縁のあり、なしが変更できないのか、どこを変えれば
ウィンドウスタイルの変更が反映されるようになるのかを教えて欲しいです。
よろしくおねがいします。
前回の回答でタイトルバーなし、縁なし、のウィンドウでウィンドウの移動と最小化ができるようになりました。
今回タイトルバーと縁のあり、なしをユーザーが設定で変更できるようにしたいと思いました。
前回はSetWindowStyleModeに2を設定し、SetWindowLongPtrで最小化ボタン(WS_MINIMIZEBOX)をつけていました。
これに縁をつけようとWS_BORDERを設定したのですが縁が出ません。拡張ウィンドウスタイルのWS_EX_DLGMODALFRAME
なども試してみましたがでませんでした。
SetWindowStyleModeを0にして縁ありのものから縁を消そうという方法も試したのですがタイトルバーは消えるのに
縁は消えません。それどころか縁の四隅で変なものが出たり出なかったりします。
SetWindowStyleModeではウィンドウスタイル以外にどこを変更してウィンドウのデザインを変えているのでしょうか?
DXライブラリのソースを読んでもよくわかりませんでした。
どこを変更しているからウィンドウスタイルを変えても縁のあり、なしが変更できないのか、どこを変えれば
ウィンドウスタイルの変更が反映されるようになるのかを教えて欲しいです。
よろしくおねがいします。
-
L'z
Re: DXライブラリのウィンドウ関係で
半分自己解決できました
一定時間ごとにウィンドウタイプ切り替えるようにしていたのですが
2つめ以降でSetWindowPosが抜けていました。初歩的なミスでした。
これでためしてみるとSetWindowStyleModeが2のときは縁、タイトルバーともに正しく動きました
しかしSetWindowStyleModeが0の場合は縁無し、タイトルバーなしにしたときに前の縁やタイトルバーが
一部残ったような状態になります。四隅に残った変なものというのは後ろのウィンドウの一部でした。
質問を
SetWindowStyleModeが2のときは縁とタイトルバーのあり、なしを切り替えても問題ないのに
SetWindowStyleModeが0になると縁とタイトルバーのあり、なしを切り替えると後ろのウィンドウの
一部や縁やタイトルバーの一部が残るのでしょうか?
に変更します。
よろしくおねがいします。
一定時間ごとにウィンドウタイプ切り替えるようにしていたのですが
2つめ以降でSetWindowPosが抜けていました。初歩的なミスでした。
これでためしてみるとSetWindowStyleModeが2のときは縁、タイトルバーともに正しく動きました
しかしSetWindowStyleModeが0の場合は縁無し、タイトルバーなしにしたときに前の縁やタイトルバーが
一部残ったような状態になります。四隅に残った変なものというのは後ろのウィンドウの一部でした。
質問を
SetWindowStyleModeが2のときは縁とタイトルバーのあり、なしを切り替えても問題ないのに
SetWindowStyleModeが0になると縁とタイトルバーのあり、なしを切り替えると後ろのウィンドウの
一部や縁やタイトルバーの一部が残るのでしょうか?
に変更します。
よろしくおねがいします。
Re: DXライブラリのウィンドウ関係で
SetWindowStyleModeって途中で切り替えられないのでしたっけ。L'z さんが書きました: SetWindowStyleModeが2のときは縁とタイトルバーのあり、なしを切り替えても問題ないのに
SetWindowStyleModeが0になると縁とタイトルバーのあり、なしを切り替えると後ろのウィンドウの
一部や縁やタイトルバーの一部が残るのでしょうか?
L'zさんがどのようにウィンドウスタイルを切り替えているのか分からないので回答のしようがありません。
再現可能な最低限のコードで書かれた、実行ファイルを作成できるソースコードを貼っていただくことはできないでしょうか。
-
L'z
Re: DXライブラリのウィンドウ関係で
途中で切り替えれるかではなくどうして0の場合にはおかしくなるのかが気になり質問しましたISLe さんが書きました: SetWindowStyleModeって途中で切り替えられないのでしたっけ。
SetWindowStyleModeを2にした場合の正しく動くときとISLe さんが書きました: L'zさんがどのようにウィンドウスタイルを切り替えているのか分からないので回答のしようがありません。
再現可能な最低限のコードで書かれた、実行ファイルを作成できるソースコードを貼っていただくことはできないでしょうか。
SetWindowStyleModeが0のおかしい場合の2種類のソースを載せます。
ソースの違いは
SetWindowStyleModeの引数と
else if( loopcount == 300 )内のSetWindowLongPtrの引数の2箇所です。
SetWindowStyleModeが0の場合はタイトルバーと境界線を消すように、
SetWindowStyleModeが2の場合はタイトルバーと境界線をつけるようにしています。
境界線とタイトルバーの「あり」から「なし」へのウィンドウ切替時におかしくなるので
SetWindowStyleModeで設定されたウィンドウスタイルと変更後(「あり」なら「なし」、「なし」なら「あり」)のウィンドウスタイルを時間で交互に切り替えるようにしています。
実行はXP SP3のVC++2010で行っています。
SetWindowStyleModeを2にした場合
問題なく動きます
#include "DxLib.h"
int Init(){
SetGraphMode( 960 , 540 , 32 );
ChangeWindowMode( TRUE );
SetWindowStyleMode( 2 );
if( DxLib_Init() ) return -1;
SetDrawScreen( DX_SCREEN_BACK );
return 0;
}
void MainLoop(){
HWND handle = GetMainWindowHandle();
int loopcount = 0;
LONG swsm = GetWindowLongPtr( handle, GWL_STYLE ); // SetWindowStyleModeの初期のウィンドウスタイル
while( !ScreenFlip() && !ClearDrawScreen() && !ProcessMessage() ){
// 5秒で交互にウィンドウモードを切り替える
if( loopcount == 0 ){
SetWindowLongPtr( handle, GWL_STYLE, swsm );
SetWindowPos( handle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
}else if( loopcount == 300 ){
SetWindowLongPtr( handle, GWL_STYLE, WS_SYSMENU | WS_MINIMIZEBOX | WS_BORDER | WS_DLGFRAME | WS_VISIBLE );
SetWindowPos( handle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
}
// 今どっちか表示
if( loopcount>=0 && loopcount<300 ){
DrawString( 0, 0, "SetWindowStyleMode2の初期のウィンドウスタイル", GetColor(255,255,255));
}else{
DrawString( 0, 0, "境界線あり", GetColor(255,255,255));
}
loopcount = (loopcount+1)%600;
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
if( Init() ) return -1;
MainLoop();
DxLib_End();
return 0;
}
境界線とタイトルバーが消えた時に右のほうにタイトルバーや×ボタンの赤いのなどが残ると思います
#include "DxLib.h"
int Init(){
SetGraphMode( 960 , 540 , 32 );
ChangeWindowMode( TRUE );
SetWindowStyleMode( 0 );
if( DxLib_Init() ) return -1;
SetDrawScreen( DX_SCREEN_BACK );
return 0;
}
void MainLoop(){
HWND handle = GetMainWindowHandle();
int loopcount = 0;
LONG swsm = GetWindowLongPtr( handle, GWL_STYLE ); // SetWindowStyleModeの初期のウィンドウスタイル
while( !ScreenFlip() && !ClearDrawScreen() && !ProcessMessage() ){
// 5秒で交互にウィンドウモードを切り替える
if( loopcount == 0 ){
SetWindowLongPtr( handle, GWL_STYLE, swsm );
SetWindowPos( handle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
}else if( loopcount == 300 ){
SetWindowLongPtr( handle, GWL_STYLE, WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE );
SetWindowPos( handle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );
}
// 今どっちか表示
if( loopcount>=0 && loopcount<300 ){
DrawString( 0, 0, "SetWindowStyleMode0の初期のウィンドウスタイル", GetColor(255,255,255));
}else{
DrawString( 0, 0, "境界線なし", GetColor(255,255,255));
}
loopcount = (loopcount+1)%600;
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
if( Init() ) return -1;
MainLoop();
DxLib_End();
return 0;
}
Re: DXライブラリのウィンドウ関係で
#ウィンドウスタイルの指定が滅茶苦茶ですけどそれは置いといて…
SetWindowStyleModeを0からはじめるほうがおかしい原因は2つありました。
なので枠を付けたり消したりするときは枠の分を考慮してウィンドウサイズを調整する必要があります。
というわけなので、SetWindowStyleModeを2から始めるほうもウィンドウサイズが期待どおりではないと思います。
SetWindowStyleModeを0からはじめるほうがおかしい原因は2つありました。
- WS_EX_CLIENTEDGE拡張スタイルが残っていて、ウィンドウ(正確にはクライアント領域)の周りにくぼみを付ける縁が描かれる。
- 最初に表示されたときの枠の分だけウィンドウサイズが大きいままなので、DXライブラリ(DirectX)の描画領域をはみ出した部分が見えてしまっている。
なので枠を付けたり消したりするときは枠の分を考慮してウィンドウサイズを調整する必要があります。
というわけなので、SetWindowStyleModeを2から始めるほうもウィンドウサイズが期待どおりではないと思います。
-
L'z
Re: DXライブラリのウィンドウ関係で
ウィンドウスタイルの指定は調べたのですが「WS_~~」がどういう意味かというのはISLe さんが書きました:#ウィンドウスタイルの指定が滅茶苦茶ですけどそれは置いといて…
たくさんあったのですが良い指定例というのは見つけられませんでした。
良い例を教えていただけませんか?
試してみたところSetWindowStyleModeが0のときは960x540の外に枠があり、枠を消したときにもともとタイトルバーがISLe さんが書きました: SetWindowStyleModeを0からはじめるほうがおかしい原因は2つありました。
SetGraphModeで指定するサイズはクライアント領域のサイズなので、枠の分は含まれません。
- WS_EX_CLIENTEDGE拡張スタイルが残っていて、ウィンドウ(正確にはクライアント領域)の周りにくぼみを付ける縁が描かれる。
- 最初に表示されたときの枠の分だけウィンドウサイズが大きいままなので、DXライブラリ(DirectX)の描画領域をはみ出した部分が見えてしまっている。
なので枠を付けたり消したりするときは枠の分を考慮してウィンドウサイズを調整する必要があります。
というわけなので、SetWindowStyleModeを2から始めるほうもウィンドウサイズが期待どおりではないと思います。
あった位置から960x540だけ更新され960x540を超えた部分が残っていました。
SetWindowStyleModeが2のときは960x540の中に枠ができ、ゲームを表示する部分が960x540よりも小さくなっていました。
枠を考えてウィンドウサイズを調節する必要がある分SetWindowStyleModeを途中で切り替える方法が楽なのですね。
SetWindowStyleModeを途中で切り替えるとウィンドウ位置がずれるのでそこを自分で調節する必要はありますけど。
SetWindowStyleModeの疑問がはれました。
ありがとうございました。
Re: DXライブラリのウィンドウ関係で
良い例というか実際にSetWindowStyleModeで設定されるスタイルを参照して、シンボルの意味合いを考慮して決めるのが良いと思います。L'z さんが書きました:ウィンドウスタイルの指定は調べたのですが「WS_~~」がどういう意味かというのは
たくさんあったのですが良い指定例というのは見つけられませんでした。
良い例を教えていただけませんか?
あとからコードを見たときに意味が分かるように。
WS_DLGFRAMEとか何がしたかったのか分からなくなる可能性大だと思います。
ウィンドウのスタイルを調べるツールがあります。
有償版のVisual StudioにはSpy++というツールが付属しています。
ライセンス上問題あるでしょうけど、試用版や古いWindowsSDKからぶっこ抜くこともできます。
Winspector Spyというフリーソフトもあります。
Winspector Spyは公式サイトが無くなっているのでミラーサイトを探してください。
-
L'z
Re: DXライブラリのウィンドウ関係で
SetWinowStyleModeを設定し、GetWindowLongPtrの値を16進表示してISLe さんが書きました: 良い例というか実際にSetWindowStyleModeで設定されるスタイルを参照して、シンボルの意味合いを考慮して決めるのが良いと思います。
あとからコードを見たときに意味が分かるように。
WS_DLGFRAMEとか何がしたかったのか分からなくなる可能性大だと思います。
その値からどれを使っているのかを調べて必要そうなものだけを書いたのですが…
WS_DLGFRAMEをつけることでタイトルバーが表示されるようになったので
タイトルバーをつけるために使いました。
しかし、
と書かれていることからタイトルバーをつけるために使うのではないようですね。ISLe さんが書きました:WS_DLGFRAMEとか何がしたかったのか分からなくなる可能性大
もう少し調べてみます。
便利なものがあるのですね。ISLe さんが書きました: ウィンドウのスタイルを調べるツールがあります。
有償版のVisual StudioにはSpy++というツールが付属しています。
ライセンス上問題あるでしょうけど、試用版や古いWindowsSDKからぶっこ抜くこともできます。
Winspector Spyというフリーソフトもあります。
Winspector Spyは公式サイトが無くなっているのでミラーサイトを探してください。
無料のVC++Expressを使っているのでフリーのものを使って見ることにします。
ありがとうございました。