|
|
2019/11/9(Sat) 23:07:44|NO.88825
chgdisp命令を使わず、ChangeDisplaySettings関数で解像度を変更したいのですがうまくいきません。
どこか間違っているのでしょうか?
いろいろ調べてみてみたのですが、全然見つかりませんでした。
#uselib "user32.dll"
#cfunc EnumDisplaySettings "EnumDisplaySettingsA" int,int,var
#func ChangeDisplaySettings "ChangeDisplaySettingsA" var,int
#define ENUM_CURRENT_SETTINGS -1
#define CDS_FULLSCREEN 4
dim mode,2
res=EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,mode)
mode.0=640
mode.1=480
mes res
ChangeDisplaySettings mode,CDS_FULLSCREEN
|
|
2019/11/11(Mon) 17:15:34|NO.88838
EnumDisplaySettings の第3引数に指定する mode の配列要素数が足りていないです。
それと解像度を指定する配列のインデックスは 27 と 28 ですね。
#uselib "user32.dll"
#cfunc EnumDisplaySettings "EnumDisplaySettingsA" int,int,var
#func ChangeDisplaySettings "ChangeDisplaySettingsA" var,int
#define ENUM_CURRENT_SETTINGS -1
#define CDS_FULLSCREEN 4
dim mode,40 ; 40あればたぶん大丈夫…
res=EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,mode)
mode.27=640
mode.28=480
mes res
ChangeDisplaySettings mode,CDS_FULLSCREEN
mes stat ; 0 以外だと失敗しています
解像度などは環境によって指定できる値が決まっていてそれ以外の値を指定すると失敗します。
どんな値ならOKなのかは EnumDisplaySettings で調べることができるので下のページ参考にしてみてください。
https://blog.goo.ne.jp/hiro239415/e/06ae28612ce2f1dc2e6aff9afadc8ef9
|
|
2019/11/11(Mon) 19:56:05|NO.88841
>K-sさん
ありがとうございます。
この関数を使って、サブモニターの解像度を変更することはできないのでしょうか?
|
|
2019/11/13(Wed) 21:48:21|NO.88857
>K-sさん。
ありがとうございます。
ChangeDisplaySettingsEx関数を使う方法もあるんですね。
MonitorFromPoint関数を使わず、すべてのモニターのハンドルを取得する方法はないのでしょうか?
調べても出て来なかったので・・・。
|
|
2019/11/14(Thu) 13:25:41|NO.88862
すいません勘違いしてました、モニタのハンドルは必要ないです…
必要なのはデバイス名で EnumDisplayDevices という関数で取得できます。
一応モニタのハンドルは EnumDisplayMonitors でコールバック使って列挙できます。
デバイス名が分かれば EnumDisplaySettings や ChangeDisplaySettingsEx に渡せば
解像度変更できると思います。
解像度表示のだけのサンプルですが
EnumDisplayDevices 版
#include "user32.as"
#const DISPLAY_DEVICE_ACTIVE 1
#const DISPLAY_DEVICE_PRIMARY_DEVICE 4
#const ENUM_CURRENT_SETTINGS -1
dim dd, 106 ; DISPLAY_DEVICE
dd = 424 ; cb
p = varptr(dd)
dupptr name, p + 4, 32, 2 ; DeviceName
dupptr flag, p + 164, 4, 4 ; StateFlags
dim dm, 40 ; DEVMODE
p = varptr(dm)
dupptr resX, p + 108, 4, 4 ; dmPelsWidth
dupptr resY, p + 112, 4, 4 ; dmPelsHeight
repeat
if EnumDisplayDevices(0, cnt, varptr(dd), 0) == 0 : break
if flag & DISPLAY_DEVICE_ACTIVE {
mes name
if flag & DISPLAY_DEVICE_PRIMARY_DEVICE {
mes "メインディスプレイ"
}
EnumDisplaySettings name, ENUM_CURRENT_SETTINGS, varptr(dm)
mes strf("解像度 %d×%d\n", resX, resY)
}
loop
EnumDisplayMonitors 版
#include "user32.as"
#include "modclbk3.hsp"
#const ENUM_CURRENT_SETTINGS -1
dim mi, 18 ; MONITORINFOEX
mi = 72 ; cbSize
p = varptr(mi)
dupptr flag, p + 36, 4, 4 ; dwFlags
dupptr name, p + 40, 32, 2 ; szDevice
dim dm, 40 ; DEVMODE
p = varptr(dm)
dupptr resX, p + 108, 4, 4 ; dmPelsWidth
dupptr resY, p + 112, 4, 4 ; dmPelsHeight
newclbk3 clbk, 4, *MonitorEnumProc
EnumDisplayMonitors 0, 0, clbk, 0
stop
*MonitorEnumProc
clbkargprotect prm
GetMonitorInfo prm, varptr(mi)
mes name
if flag {
mes "メインディスプレイ"
}
EnumDisplaySettings name, ENUM_CURRENT_SETTINGS, varptr(dm)
mes strf("解像度 %d×%d\n", resX, resY)
return 1
| |
|
2019/11/16(Sat) 15:49:33|NO.88871
おお、ありがとうございます。
EnumDisplayDevicesやGetMonitorInfoでモニターの解像度を取得できるのはわかったのですが、
モニターの座標とか取得できないのでしょうか?
解像度の変更は、主に全画面のゲームを作りたいと考えているので・・・。
|
|
2019/11/17(Sun) 12:23:47|NO.88872
GetMonitorInfo で得られる MONITORINFO 構造体の rcMonitor、
EnumDisplaySettings で得られる DEVMODE 構造体の dmPosition にそれぞれ座標が入っています。
ただ MONITORINFO の方は DPI によって座標が変わり DEVMODE は DPI によらず一定という違いがあるので注意してください。
あとメインモニタ以外は解像度を変えるとそれに応じて座標も変わるので
1.モニタ解像度変更
2.モニタ座標取得
3.ウィンドウの移動・サイズやスタイル変更等
という順番になると思います。
|
|
2019/11/23(Sat) 17:51:53|NO.88911
こんな感じでいいのでしょうか?
#uselib "user32.dll"
#cfunc MonitorFromWindow "MonitorFromWindow" int,int
#func GetMonitorInfo "GetMonitorInfoA" int,var
#func EnumDisplaySettings "EnumDisplaySettingsA" sptr,int,var
#func ChangeDisplaySettings "ChangeDisplaySettingsA" int,int
#func ChangeDisplaySettingsEx "ChangeDisplaySettingsExA" sptr,int,int,int,int
#func ShowCursor "ShowCursor" int
#func SetCursorPos "SetCursorPos" int,int
;ここに全画面表示したいサイズを変える。パソコンの解像度には制約があり、失敗することもある。
#define sizex 1024
#define sizey 768
;一瞬だけウィンドウが表示されないようにする処理
#packopt hide 1
#define CDS_UPDATEREGISTRY 0x01
#define ENUM_CURRENT_SETTINGS -1
#define CDS_FULLSCREEN 4
#define DM_POSITION 0x00000020
screen 0,400,100
onkey *kettei
mes "全画面表示にしたいモニターにウィンドウを移動させ、\nEnterキーを押してください。"
stop
*kettei
if wparam!13:stop
dim mode,40
MainMoni = MonitorFromWindow(hwnd,0);ウィンドウ座標から、モニターのハンドルを取得する。
dim MonitorData,72/4
MonitorData(0) = 72
GetMonitorInfo MainMoni,MonitorData
if stat=0:dialog "モニター情報の取得に失敗しました。",1:end
sdim DispName,32
memcpy DispName,MonitorData,32,0,40
EnumDisplaySettings DispName,ENUM_CURRENT_SETTINGS,mode
if stat=0:dialog "モニターが見つかりませんでした。",1:end
;解像度を800x600に変更
mode.27=sizex
mode.28=sizey
ChangeDisplaySettingsEx DispName,varptr(mode),0,CDS_FULLSCREEN,0
if stat:dialog "解像度の変更に失敗しました。",1:end
dim MonitorData,72/4
MonitorData(0) = 72
GetMonitorInfo MainMoni,MonitorData
if stat=0:dialog "モニター情報の取得に失敗しました。",1:end
bgscr 0,sizex,sizey,2,MonitorData(1),MonitorData(2)
sdim DispName,32
memcpy DispName,MonitorData,32,0,40
mes "DisplayName = "+DispName
mes "モニター座標X(左基準)"+MonitorData(1)
mes "モニター座標Y(上基準)"+MonitorData(2)
mes "Alt + F4 で終了\n終了すると元に戻ります。"
gsel 0,2
;マルチモニター環境でmouse命令を使うとマウスカーソルが消えてしまうため、代わりにShowCursor関数を使うこと。
;マウスカーソルの移動は、mouse命令でマイナス位置に移動することができないため、代わりにSetCursorPos関数を使うこと。
;モニターの中央に指定
mx=MonitorData(1)+(sizex/2)
my=MonitorData(2)+(sizey/2)
repeat
SetCursorPos mx,my;マウスカーソルをモニターの中央に移動する。
if ginfo_mx=mx & ginfo_my=my:break
loop
wait 500
ShowCursor 0;カーソルの非表示
wait 1000
ShowCursor 1;カーソルの表示
/*
wait 1000
;解像度を元に戻す
ChangeDisplaySettingsEx DispName,0,0,CDS_FULLSCREEN,0
gsel 0,-1
*/
stop
| |
|
2019/11/24(Sun) 20:29:47|NO.88923
いいと思います。こちらの環境でもちゃんと解像度変更できました。
;モニターの中央に指定
mx=MonitorData(1)+(sizex/2)
my=MonitorData(2)+(sizey/2)
これは表示スケール(DPI)の大きいモニタだとズレるので
;モニターの中央に指定
mx=(MonitorData(1)+(MonitorData(3))/2
my=(MonitorData(2)+(MonitorData(4))/2
これでモニタの真ん中に来ます。
|
|
2019/11/27(Wed) 20:51:30|NO.88931
>K-sさん
ありがとうございます。
chgdisp命令だと、メインモニターでしか解像度の変更ができないみたいなので、Win32APIを使ってサブモニターの解像度を変更しようと考えてました。
わからないことがあれば、質問するかもしれませんが、その時はよろしくお願いします。
|
|