HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2023
0922
ゆっくりXPダークモードについて17解決


ゆっくりXP

リンク

2023/9/22(Fri) 06:37:07|NO.100064

こちらのサイトを参考し、HSPのダークモードを対応させたのですが、ライトモードかダークモードかどうかを取得する方法はありますか?
https://super-string37.com/entry/2023/01/04/155404
あと、HSPのウィンドウ全体をダークモードすることはできないのでしょうか。

#uselib "dwmapi.dll" #func DwmSetWindowAttribute "DwmSetWindowAttribute" sptr,sptr,var,sptr #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 value = 1 DwmSetWindowAttribute hwnd,DWMWA_USE_IMMERSIVE_DARK_MODE,value,4



この記事に返信する


ゆっくりXP

リンク

2023/9/22(Fri) 17:29:53|NO.100066

あと、メニューバーやコンテキストメニューやボタンをダークモードにすることはできないですかね?



nennneko5787

リンク

2023/9/22(Fri) 20:37:17|NO.100067




沢渡

リンク

2023/9/23(Sat) 16:42:45|NO.100073

ダークモードかどうかの判定は以下のサイトが参考になるかと思います。
https://wp.waiei.net/2022/11/16/darkmode-titlebar/
以下、上記のサイトを参考にオブジェクトのダーク化をやってみました。
(ダークモードかどうかの判定は行っていません)

#include "user32.as" #uselib "dwmapi.dll" #func DwmSetWindowAttribute "DwmSetWindowAttribute" sptr,sptr,var,sptr #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #module #uselib "uxtheme" #func SetWindowTheme "SetWindowTheme" int, wptr, nullptr #deffunc obj_dark int obj //オブジェクトをダークモード化する(オブジェクトIDを指定する版) obj_dark_h objinfo(obj,2) return #deffunc obj_dark_h int han //オブジェクトをダークモード化する(オブジェクトのハンドルを指定する版) SetWindowTheme han,"DarkMode_Explorer" return #global value = 1 DwmSetWindowAttribute hwnd,DWMWA_USE_IMMERSIVE_DARK_MODE,value,4 SetWindowPos hwnd,0,0,0,0,0,7 //ダークモードへの変更を反映させる //以下、オブジェクトをダークモード化 button gosub "テスト",*hoge obj_dark stat s="" : mesbox s,400,300 obj_dark stat stop *hoge return



ゆっくりXP

リンク

2023/9/23(Sat) 20:18:08|NO.100074

沢渡さんありがとうございます。そのサイトを参考にして、ダークモードを対応させたところでした。
ダークモードのWindows APIについていろいろ調べてみたら、このサイトによると、SetWindowTheme関数で指定するのは、DarkMode_Explorerだけでなくコンボボックスもダークモード化する場合、
DarkMode_CFDも指定するらしいですが、メニューバーや右クリックメニューやmesboxやinputの入力ボックスの場合、どのようにすればいいのでしょうか?
https://www.haijin-boys.com/wiki/%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89%E5%AF%BE%E5%BF%9C

//SetWindowTheme関数がUnicodeを使用しているため、hsp3utf.asをインクルードしておく #include "hsp3utf.as" #uselib "dwmapi.dll" #func DwmGetWindowAttribute "DwmGetWindowAttribute" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #uselib "uxtheme.dll" #func SetWindowTheme "SetWindowTheme" int, wptr,int #define dark_obj(%1) SetWindowTheme %1,"DarkMode_Explorer",0 #define dark_com_obj(%1) SetWindowTheme %1,"DarkMode_CFD",0 #define dark_list_obj(%1) SetWindowTheme %1,"DarkMode_ItemsView",0 #define right_obj(%1) SetWindowTheme %1,"",0 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #define WM_WININICHANGE 0x001A #module #uselib "advapi32.dll" #func RegOpenKeyEx "RegOpenKeyExW" int, wptr, int, int,var #func RegQueryValueEx "RegQueryValueExW" int, wptr, int,int,int,int #func RegCloseKey "RegCloseKey" int #define KEY_READ 0x20019 #define HKEY_CURRENT_USER 0x80000001 /** * レジストリの取得 */ #defcfunc get_regedit int h, str key, str name RegOpenKeyEx h, key, 0,KEY_READ,hkey RegQueryValueEx hkey, name, 0, 0, 0, varptr(sz) if stat == 0 { sdim data, sz RegQueryValueEx hkey, name, 0, 0, varptr(data), varptr(sz) } else { data = -1 } RegCloseKey hkey return data /** * システムがダークカラーかどうかをレジストリから取得 * ダークカラーが有効なら1、無効なら0 * そもそもダークカラー設定が存在しない場合は -1 を返す */ #defcfunc get_dark_color_type dark = 0 key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" name = "AppsUseLightTheme" ret = get_regedit(HKEY_CURRENT_USER, key, name) tmpText = "" if ret != -1 { // ライトカラー設定 if peek(ret, 0) == 0 { dark = 1 } else { dark = 0 } } else { dark = -1 } return dark #global font "meiryo",16 objmode 2 cmb_dummy=0 objsize 120,32 combox cmb_dummy,120,"ダーク\nモード\nテスト" cmx = objinfo_hwnd(stat) objsize 120,24 pos 0,33 button "ダーク",*dummy btn = objinfo_hwnd(stat) // システムの設定が変わったときに呼び出される oncmd gosub *lWM_WININICHANGE,WM_WININICHANGE // 起動時に一回呼び出しておく gosub *lWM_WININICHANGE stop // システムの設定が変更された *lWM_WININICHANGE // 他の部分はレジストリの変更検出なので、必要なのは実質ここだけ dim size dim opt //ウィンドウの属性状態を取得 DwmGetWindowAttribute hwnd, 0, 0, varptr(size) if get_dark_color_type() == 1 : opt(0) = 1 : else : opt(0) = 0 //タイトルバーをダークモードに変更 DwmSetWindowAttribute hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, varptr(opt), varptr(size) if opt { //オブジェクトをダークモードに変更 color 0,0,0:boxf dark_com_obj cmx dark_obj btn }else{ //オブジェクトをライトモードに変更 color 255,255,255:boxf right_obj cmx right_obj btn } return *dummy



沢渡

リンク

2023/9/24(Sun) 00:02:23|NO.100075

inputやmesboxについては、こんな感じでWM_CTLCOLOREDITを捕まえて
自前で色変更を行う形にするしかないのかな、と思いました。
メニューについてはすみません、ちょっとまだわかりかねます。

//SetWindowTheme関数がUnicodeを使用しているため、hsp3utf.asをインクルードしておく #include "hsp3utf.as" #include "gdi32.as" #include "user32.as" #uselib "dwmapi.dll" #func DwmGetWindowAttribute "DwmGetWindowAttribute" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #uselib "uxtheme.dll" #func SetWindowTheme "SetWindowTheme" int, wptr,int #define dark_obj(%1) SetWindowTheme %1,"DarkMode_Explorer",0 #define dark_com_obj(%1) SetWindowTheme %1,"DarkMode_CFD",0 #define dark_list_obj(%1) SetWindowTheme %1,"DarkMode_ItemsView",0 #define right_obj(%1) SetWindowTheme %1,"",0 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #define WM_WININICHANGE 0x001A #define WM_CTLCOLOREDIT 0x0133 #define RDW_UPDATENOW 1 #module #uselib "advapi32.dll" #func RegOpenKeyEx "RegOpenKeyExW" int, wptr, int, int,var #func RegQueryValueEx "RegQueryValueExW" int, wptr, int,int,int,int #func RegCloseKey "RegCloseKey" int #define KEY_READ 0x20019 #define HKEY_CURRENT_USER 0x80000001 /** * レジストリの取得 */ #defcfunc get_regedit int h, str key, str name RegOpenKeyEx h, key, 0,KEY_READ,hkey RegQueryValueEx hkey, name, 0, 0, 0, varptr(sz) if stat == 0 { sdim data, sz RegQueryValueEx hkey, name, 0, 0, varptr(data), varptr(sz) } else { data = -1 } RegCloseKey hkey return data /** * システムがダークカラーかどうかをレジストリから取得 * ダークカラーが有効なら1、無効なら0 * そもそもダークカラー設定が存在しない場合は -1 を返す */ #defcfunc get_dark_color_type dark = 0 key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" name = "AppsUseLightTheme" ret = get_regedit(HKEY_CURRENT_USER, key, name) tmpText = "" if ret != -1 { // ライトカラー設定 if peek(ret, 0) == 0 { dark = 1 } else { dark = 0 } } else { dark = -1 } return dark #global font "meiryo",16 objmode 2 cmb_dummy=0 objsize 120,32 combox cmb_dummy,120,"ダーク\nモード\nテスト" cmx = objinfo_hwnd(stat) objsize 120,24 pos 0,33 button "ダーク",*dummy btn = objinfo_hwnd(stat) CreateSolidBrush 0x202020 : br_h=stat //テキストボックスの背景色のブラシ CreateSolidBrush 0xFFFFFF : br_h2=stat //テキストボックスの背景色のブラシ input a inp = objinfo_hwnd(stat) s="" mesbox s,400,100 mbox = objinfo_hwnd(stat) // システムの設定が変わったときに呼び出される oncmd gosub *lWM_WININICHANGE,WM_WININICHANGE // 起動時に一回呼び出しておく gosub *lWM_WININICHANGE onexit *exit stop // システムの設定が変更された *lWM_WININICHANGE // 他の部分はレジストリの変更検出なので、必要なのは実質ここだけ dim size dim opt //ウィンドウの属性状態を取得 DwmGetWindowAttribute hwnd, 0, 0, varptr(size) if get_dark_color_type() == 1 : opt(0) = 1 : else : opt(0) = 0 //タイトルバーをダークモードに変更 DwmSetWindowAttribute hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, varptr(opt), varptr(size) if opt { //オブジェクトをダークモードに変更 color 0,0,0:boxf dark_com_obj cmx dark_obj btn oncmd gosub *edit_d,WM_CTLCOLOREDIT }else{ //オブジェクトをライトモードに変更 color 255,255,255:boxf right_obj cmx right_obj btn oncmd gosub *edit_l,WM_CTLCOLOREDIT } RedrawWindow inp,0,0,RDW_UPDATENOW //強制再描画 RedrawWindow mbox,0,0,RDW_UPDATENOW return *dummy stop //ダークモード時のエディットボックス描画 *edit_d if lparam=inp | lparam=mbox { //lparamがエディットボックスのハンドルかどうかを調べ、そうならば処理を行う。 SetTextColor wparam,0xFFFFFF //文字の色 SetBkColor wparam,0x202020 //背景色 return br_h //ブラシを返す必要がある } return //ライトモード時のエディットボックス描画 *edit_l if lparam=inp | lparam=mbox { SetTextColor wparam,0x000000 //文字の色 SetBkColor wparam,0xFFFFFF //背景色 return br_h2 //ブラシを返す必要がある } return *exit DeleteObject br_h //終了時にブラシを削除 DeleteObject br_h2 end



ゆっくりXP

リンク

2023/9/24(Sun) 13:04:39|NO.100076

沢渡さんありがとうございます。GUIアプリを作るのに参考になりそうです。
あとinputやmesboxの入力オブジェクトのダークモード化は、Windows 7以前でも動作するのでしょうか?
Windows 10の古いバージョンやWindows 8でDWMWA_USE_IMMERSIVE_DARK_MODEを指定した場合は、エラーが出るのでしょうか?
よろしくお願いします。

あとrightとlightのスペルをミスっていました。
誤 right 正 light


//SetWindowTheme関数がUnicodeを使用しているため、hsp3utf.asをインクルードしておく #include "hsp3utf.as" #include "gdi32.as" #include "user32.as" #uselib "dwmapi.dll" #func DwmGetWindowAttribute "DwmGetWindowAttribute" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #uselib "uxtheme.dll" #func SetWindowTheme "SetWindowTheme" int, wptr,int #define dark_obj(%1) SetWindowTheme %1,"DarkMode_Explorer",0 #define dark_com_obj(%1) SetWindowTheme %1,"DarkMode_CFD",0 #define dark_list_obj(%1) SetWindowTheme %1,"DarkMode_ItemsView",0 #define light_obj(%1) SetWindowTheme %1,"",0 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #define WM_WININICHANGE 0x001A #define WM_CTLCOLOREDIT 0x0133 #define RDW_UPDATENOW 1 #module #uselib "advapi32.dll" #func RegOpenKeyEx "RegOpenKeyExW" int, wptr, int, int,var #func RegQueryValueEx "RegQueryValueExW" int, wptr, int,int,int,int #func RegCloseKey "RegCloseKey" int #define KEY_READ 0x20019 #define HKEY_CURRENT_USER 0x80000001 /** * レジストリの取得 */ #defcfunc get_regedit int h, str key, str name RegOpenKeyEx h, key, 0,KEY_READ,hkey RegQueryValueEx hkey, name, 0, 0, 0, varptr(sz) if stat == 0 { sdim data, sz RegQueryValueEx hkey, name, 0, 0, varptr(data), varptr(sz) } else { data = -1 } RegCloseKey hkey return data /** * システムがダークカラーかどうかをレジストリから取得 * ダークカラーが有効なら1、無効なら0 * そもそもダークカラー設定が存在しない場合は -1 を返す */ #defcfunc get_dark_color_type dark = 0 key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" name = "AppsUseLightTheme" ret = get_regedit(HKEY_CURRENT_USER, key, name) tmpText = "" if ret != -1 { // ライトカラー設定 if peek(ret, 0) == 0 { dark = 1 } else { dark = 0 } } else { dark = -1 } return dark #global font "meiryo",16 objmode 2 cmb_dummy=0 objsize 120,32 combox cmb_dummy,120,"ダーク\nモード\nテスト" cmx = objinfo_hwnd(stat) objsize 120,24 pos 0,33 button "ダーク",*dummy btn = objinfo_hwnd(stat) CreateSolidBrush 0x202020 : br_h=stat //テキストボックスの背景色のブラシ CreateSolidBrush 0xFFFFFF : br_h2=stat //テキストボックスの背景色のブラシ input a inp = objinfo_hwnd(stat) s="" mesbox s,400,100 mbox = objinfo_hwnd(stat) // システムの設定が変わったときに呼び出される oncmd gosub *lWM_WININICHANGE,WM_WININICHANGE // 起動時に一回呼び出しておく gosub *lWM_WININICHANGE onexit *exit stop // システムの設定が変更された *lWM_WININICHANGE // 他の部分はレジストリの変更検出なので、必要なのは実質ここだけ dim size dim opt //ウィンドウの属性状態を取得 DwmGetWindowAttribute hwnd, 0, 0, varptr(size) if get_dark_color_type() == 1 : opt(0) = 1 : else : opt(0) = 0 //タイトルバーをダークモードに変更 DwmSetWindowAttribute hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, varptr(opt), varptr(size) if opt { //オブジェクトをダークモードに変更 color 0,0,0:boxf dark_com_obj cmx dark_obj mbox//スクロールバーをダークモード化 dark_obj btn oncmd gosub *edit_d,WM_CTLCOLOREDIT }else{ //オブジェクトをライトモードに変更 color 255,255,255:boxf light_obj cmx light_obj mbox light_obj btn oncmd gosub *edit_l,WM_CTLCOLOREDIT } RedrawWindow inp,0,0,RDW_UPDATENOW //強制再描画 RedrawWindow mbox,0,0,RDW_UPDATENOW return *dummy stop //ダークモード時のエディットボックス描画 *edit_d if lparam=inp | lparam=mbox { //lparamがエディットボックスのハンドルかどうかを調べ、そうならば処理を行う。 SetTextColor wparam,0xFFFFFF //文字の色 SetBkColor wparam,0x202020 //背景色 return br_h //ブラシを返す必要がある } return //ライトモード時のエディットボックス描画 *edit_l if lparam=inp | lparam=mbox { SetTextColor wparam,0x000000 //文字の色 SetBkColor wparam,0xFFFFFF //背景色 return br_h2 //ブラシを返す必要がある } return *exit DeleteObject br_h //終了時にブラシを削除 DeleteObject br_h2 end



沢渡

リンク

2023/9/24(Sun) 16:18:46|NO.100077

追記です。
ポップアップメニューについてはSetPreferredAppModeと
RefreshImmersiveColorPolicyStateを使えばできたのですが、
ウィンドウの上に貼り付くメニューについてはそれも効きませんでした。
色々調べてみてもよくわからなかったので、通常のメニューの代わりに
「ボタンを配置し、それ以外の部分はスタティックコントロールで穴埋め」
したもので代用してみましたが、このような形でどうでしょうか?
(本当はボタンの境界線も消したかったのですが、Windows10以降では
 ウィンドウスタイルにBS_FLATを指定してもダメな様子……?)

//SetWindowTheme関数がUnicodeを使用しているため、hsp3utf.asをインクルードしておく #include "hsp3utf.as" #include "gdi32.as" #include "user32.as" #include "kernel32.as" #uselib "dwmapi.dll" #func DwmGetWindowAttribute "DwmGetWindowAttribute" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #uselib "uxtheme.dll" #func SetWindowTheme "SetWindowTheme" int, wptr,int #define dark_obj(%1) SetWindowTheme %1,"DarkMode_Explorer",0 #define dark_com_obj(%1) SetWindowTheme %1,"DarkMode_CFD",0 #define dark_list_obj(%1) SetWindowTheme %1,"DarkMode_ItemsView",0 #define right_obj(%1) SetWindowTheme %1,"",0 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #define WM_WININICHANGE 0x001A #define WM_CTLCOLOREDIT 0x0133 #define WM_CTLCOLORSTATIC 0x0138 #define RDW_UPDATENOW 1 #module #uselib "advapi32.dll" #func RegOpenKeyEx "RegOpenKeyExW" int, wptr, int, int,var #func RegQueryValueEx "RegQueryValueExW" int, wptr, int,int,int,int #func RegCloseKey "RegCloseKey" int #define KEY_READ 0x20019 #define HKEY_CURRENT_USER 0x80000001 /** * レジストリの取得 */ #defcfunc get_regedit int h, str key, str name RegOpenKeyEx h, key, 0,KEY_READ,hkey RegQueryValueEx hkey, name, 0, 0, 0, varptr(sz) if stat == 0 { sdim data, sz RegQueryValueEx hkey, name, 0, 0, varptr(data), varptr(sz) } else { data = -1 } RegCloseKey hkey return data /** * システムがダークカラーかどうかをレジストリから取得 * ダークカラーが有効なら1、無効なら0 * そもそもダークカラー設定が存在しない場合は -1 を返す */ #defcfunc get_dark_color_type dark = 0 key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" name = "AppsUseLightTheme" ret = get_regedit(HKEY_CURRENT_USER, key, name) tmpText = "" if ret != -1 { // ライトカラー設定 if peek(ret, 0) == 0 { dark = 1 } else { dark = 0 } } else { dark = -1 } return dark #global font "meiryo",16 objmode 2 cmb_dummy=0 pos 0,30 objsize 120,32 combox cmb_dummy,120,"ダーク\nモード\nテスト" cmx = objinfo_hwnd(stat) objsize 120,24 pos 0,63 button "ダーク",*dummy btn = objinfo_hwnd(stat) CreateSolidBrush 0x202020 : br_h=stat //テキストボックスの背景色のブラシ CreateSolidBrush 0xFFFFFF : br_h2=stat CreateSolidBrush 0xE1E1E1 : br_h3=stat //スタティックコントロールの背景色のブラシ input a inp = objinfo_hwnd(stat) s="" mesbox s,400,100 mbox = objinfo_hwnd(stat) //メニュー代わりのボタン pos 0,0 objsize 160,30 button gosub "ポップアップ",*popup menubtn1=objinfo_hwnd(stat) GetWindowLong menubtn1,-16 SetWindowLong menubtn1,-16,stat|0x8100 //穴埋め用のスタティックコントロール objsize 480,30 : pos 160,0 winobj "static","",,0x50000000 static=objinfo_hwnd(stat) //ポップアップメニュー関連 CreatePopupMenu : pmenu=stat AppendMenuW pmenu,0,0,"ポップアップしました" LoadLibraryW "uxtheme.dll" : lib_h=stat //SetPreferredAppModeとRefreshImmersiveColorPolicyStateを呼ぶための準備 //これらのAPIは非公開のためか、一寸迂遠な方法で呼ぶしかなさそう? // システムの設定が変わったときに呼び出される oncmd gosub *lWM_WININICHANGE,WM_WININICHANGE // 起動時に一回呼び出しておく gosub *lWM_WININICHANGE onexit *exit stop // システムの設定が変更された *lWM_WININICHANGE // 他の部分はレジストリの変更検出なので、必要なのは実質ここだけ dim size dim opt dim prm,2 GetProcAddress lib_h,135 : add=stat //SetPreferredAppModeのアドレスを取得 prm=2 : dum=callfunc(prm,add,1) //SetPreferredAppModeを実行 //ウィンドウの属性状態を取得 //DwmGetWindowAttribute hwnd, 0, 0, 4 if get_dark_color_type() == 1 : opt(0) = 1 : else : opt(0) = 0 //タイトルバーをダークモードに変更 DwmSetWindowAttribute hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, varptr(opt), 4 if opt { //オブジェクトをダークモードに変更 color 0,0,0:boxf dark_com_obj cmx dark_obj btn dark_obj menubtn1 oncmd gosub *edit_d,WM_CTLCOLOREDIT oncmd gosub *edit_d,WM_CTLCOLORSTATIC }else{ //オブジェクトをライトモードに変更 GetProcAddress lib_h,135 : add=stat //SetPreferredAppModeのアドレスを取得 prm=3 : dum=callfunc(prm,add,1) //SetPreferredAppModeを実行 color 255,255,255:boxf right_obj cmx right_obj btn right_obj menubtn1 oncmd gosub *edit_l,WM_CTLCOLOREDIT oncmd gosub *edit_l,WM_CTLCOLORSTATIC } GetProcAddress lib_h,104 : add=stat //RefreshImmersiveColorPolicyStateのアドレスを取得 dum=callfunc(prm,add,0) //RefreshImmersiveColorPolicyStateを実行 RedrawWindow inp,0,0,RDW_UPDATENOW //強制再描画 RedrawWindow mbox,0,0,RDW_UPDATENOW RedrawWindow static,0,0,RDW_UPDATENOW return *dummy stop //ダークモード時のエディットボックス描画 *edit_d if lparam=inp | lparam=mbox | lparam=static { //lparamがエディットボックスのハンドルかどうかを調べ、そうならば処理を行う。 SetTextColor wparam,0xFFFFFF //文字の色 SetBkColor wparam,0x202020 //背景色 return br_h //ブラシを返す必要がある } return //ライトモード時のエディットボックス描画 *edit_l if lparam=inp | lparam=mbox | lparam=static { SetTextColor wparam,0x000000 //文字の色 if lparam=static { SetBkColor wparam,0xE1E1E1 //背景色 return br_h3 } else { SetBkColor wparam,0xFFFFFF //背景色 return br_h2 } } return *popup TrackPopupMenu pmenu,0,ginfo_mx,ginfo_my,0,hwnd,0 return *exit DeleteObject br_h //終了時にブラシを削除 DeleteObject br_h2 DeleteObject br_h3 DestroyMenu pmenu //メニューを削除 FreeLibrary lib_h //読み込んだライブラリを解放 end

>あとinputやmesboxの入力オブジェクトのダークモード化は、
>Windows 7以前でも動作するのでしょうか?
WM_WININICHANGEやSetTextColor等はWindows2000以降で使えるようなので、
おそらく大丈夫だと思います。

>Windows 10の古いバージョンやWindows 8でDWMWA_USE_IMMERSIVE_DARK_MODEを
>指定した場合は、エラーが出るのでしょうか?
試せる環境がないので断言はできませんが、
DwmSetWindowAttribute自体はWindowsVistaからサポートされているようなので、
HSPがエラーで落ちるようなことは無いとは思います。



ゆっくりXP

リンク

2023/9/24(Sun) 23:45:49|NO.100082

おお、そんな方法でダークモードにできたんですね。
uselibのfuncからuxtheme.dllのSetPreferredAppModeを呼び出そうとしても、dllの呼び出しエラーが出たのでできないと思っていたのですが。

//SetWindowTheme関数がUnicodeを使用しているため、hsp3utf.asをインクルードしておく #include "hsp3utf.as" #uselib "gdi32.dll" #cfunc CreateSolidBrush "CreateSolidBrush" int #func DeleteObject "DeleteObject" int #func SetTextColor "SetTextColor" int,int #func SetBkColor "SetBkColor" int,int #uselib "user32.dll" #func GetWindowLong "GetWindowLongW" int,int #func SetWindowLong "SetWindowLongW" int,int,int #cfunc CreatePopupMenu "CreatePopupMenu" #func AppendMenu "AppendMenuW" int,int,int,wstr #func RedrawWindow "RedrawWindow" int,int,int,int #func TrackPopupMenu "TrackPopupMenu" int, int, int, int, int, int, int #func DestroyMenu "DestroyMenu" int #uselib "kernel32.dll" #cfunc LoadLibrary "LoadLibraryW" wstr #cfunc GetProcAddress "GetProcAddress" int,int #func FreeLibrary "FreeLibrary" int #uselib "dwmapi.dll" #func DwmGetWindowAttribute "DwmGetWindowAttribute" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #uselib "uxtheme.dll" #func SetWindowTheme "SetWindowTheme" int, wptr,wptr #define dark_obj(%1) SetWindowTheme %1,"DarkMode_Explorer",0 #define dark_com_obj(%1) SetWindowTheme %1,"DarkMode_CFD",0 #define dark_list_obj(%1) SetWindowTheme %1,"DarkMode_ItemsView",0 #define light_obj(%1) SetWindowTheme %1,"",0 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #define WM_WININICHANGE 0x001A #define WM_CTLCOLOREDIT 0x0133 #define WM_CTLCOLORSTATIC 0x0138 #define RDW_UPDATENOW 1 #module #uselib "advapi32.dll" #func RegOpenKeyEx "RegOpenKeyExW" int, wptr, int, int,var #func RegQueryValueEx "RegQueryValueExW" int, wptr, int,int,int,int #func RegCloseKey "RegCloseKey" int #define KEY_READ 0x20019 #define HKEY_CURRENT_USER 0x80000001 /** * レジストリの取得 */ #defcfunc get_regedit int h, str key, str name RegOpenKeyEx h, key, 0,KEY_READ,hkey RegQueryValueEx hkey, name, 0, 0, 0, varptr(sz) if stat == 0 { sdim data, sz RegQueryValueEx hkey, name, 0, 0, varptr(data), varptr(sz) } else { data = -1 } RegCloseKey hkey return data /** * システムがダークカラーかどうかをレジストリから取得 * ダークカラーが有効なら1、無効なら0 * そもそもダークカラー設定が存在しない場合は -1 を返す */ #defcfunc get_dark_color_type dark = 0 key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" name = "AppsUseLightTheme" ret = get_regedit(HKEY_CURRENT_USER, key, name) tmpText = "" if ret != -1 { // ライトカラー設定 if peek(ret, 0) == 0 { dark = 1 } else { dark = 0 } } else { dark = -1 } return dark #global font "meiryo",16 objmode 2 cmb_dummy=0 pos 0,30 objsize 120,32 combox cmb_dummy,120,"ダーク\nモード\nテスト" cmx = objinfo_hwnd(stat) objsize 120,32 pos 120,30 button "ダーク",*dummy btn = objinfo_hwnd(stat) br_h = CreateSolidBrush(0x202020) //テキストボックスの背景色のブラシ br_h2 = CreateSolidBrush(0xFFFFFF) br_h3 = CreateSolidBrush(0xE1E1E1)//スタティックコントロールの背景色のブラシ pos 0 a = "ダークモードテスト" input a,ginfo_winx inp = objinfo_hwnd(stat) sdim s mesbox s,ginfo_winx,ginfo_winy-94 mbox = objinfo_hwnd(stat) //メニュー代わりのボタン pos 0,0 objsize 160,30 button gosub "ポップアップ",*popup menubtn1=objinfo_hwnd(stat) GetWindowLong menubtn1,-16 SetWindowLong menubtn1,-16,stat|0x8100 //穴埋め用のスタティックコントロール objsize 480,30 : pos 160,0 winobj "static","",,0x50000000 static=objinfo_hwnd(stat) //ポップアップメニュー関連 pmenu=CreatePopupMenu() AppendMenu pmenu,0,0,"ポップアップメニュー" lib_h = LoadLibrary("uxtheme.dll") //SetPreferredAppModeとRefreshImmersiveColorPolicyStateを呼ぶための準備 //これらのAPIは非公開のためか、一寸迂遠な方法で呼ぶしかなさそう? // システムの設定が変わったときに呼び出される oncmd gosub *lWM_WININICHANGE,WM_WININICHANGE // 起動時に一回呼び出しておく gosub *lWM_WININICHANGE onexit *exit stop // システムの設定が変更された *lWM_WININICHANGE // 他の部分はレジストリの変更検出なので、必要なのは実質ここだけ dim size dim opt dim prm,2 //ウィンドウの属性状態を取得 //DwmGetWindowAttribute hwnd, 0, 0, 4 if get_dark_color_type() == 1 : opt(0) = 1 : else : opt(0) = 0 //タイトルバーをダークモードに変更 DwmSetWindowAttribute hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, varptr(opt), 4 add = GetProcAddress(lib_h,135) //SetPreferredAppModeのアドレスを取得 prm=2 : dum=callfunc(prm,add,1) //SetPreferredAppModeを実行 if opt { //オブジェクトをダークモードに変更 color 0,0,0:boxf dark_com_obj cmx dark_obj btn dark_obj menubtn1 dark_obj mbox oncmd gosub *edit_d,WM_CTLCOLOREDIT oncmd gosub *edit_d,WM_CTLCOLORSTATIC }else{ //オブジェクトをライトモードに変更 add = GetProcAddress(lib_h,135) //SetPreferredAppModeのアドレスを取得 prm=3 : dum=callfunc(prm,add,1) //SetPreferredAppModeを実行 color 255,255,255:boxf light_obj cmx light_obj btn light_obj menubtn1 light_obj mbox oncmd gosub *edit_l,WM_CTLCOLOREDIT oncmd gosub *edit_l,WM_CTLCOLORSTATIC } add=GetProcAddress(lib_h,104) //RefreshImmersiveColorPolicyStateのアドレスを取得 dum=callfunc(prm,add,0) //RefreshImmersiveColorPolicyStateを実行 RedrawWindow inp,0,0,RDW_UPDATENOW //強制再描画 RedrawWindow mbox,0,0,RDW_UPDATENOW RedrawWindow static,0,0,RDW_UPDATENOW return *dummy stop //ダークモード時のエディットボックス描画 *edit_d if lparam=inp | lparam=mbox | lparam=static { //lparamがエディットボックスのハンドルかどうかを調べ、そうならば処理を行う。 SetTextColor wparam,0xFFFFFF //文字の色 SetBkColor wparam,0x202020 //背景色 return br_h //ブラシを返す必要がある } return //ライトモード時のエディットボックス描画 *edit_l if lparam=inp | lparam=mbox | lparam=static { SetTextColor wparam,0x000000 //文字の色 if lparam=static { SetBkColor wparam,0xE1E1E1 //背景色 return br_h3 } else { SetBkColor wparam,0xFFFFFF //背景色 return br_h2 } } return *popup TrackPopupMenu pmenu,0,ginfo_mx,ginfo_my,0,hwnd,0 return *exit DeleteObject br_h //終了時にブラシを削除 DeleteObject br_h2 DeleteObject br_h3 DestroyMenu pmenu //メニューを削除 FreeLibrary lib_h //読み込んだライブラリを解放 end
少しスクリプトを改造してみましたが、実行中にWindowsの設定からライトモードに切り替えた際に、ポップアップメニューだけライトモードにならないのですが、これは仕様なのでしょうか?



名無し

リンク

2023/9/25(Mon) 00:56:33|NO.100083

横からですが、ご報告という事で。
Windows10 Home 22H2にて、
設定をライト→ダークに変更時、ダーク→ライトに変更時どちらとも、
ポップアップメニューも含め設定どおりに変更されている為、
環境的な問題だと思います。



nennneko5787

リンク

2023/9/26(Tue) 17:19:20|NO.100085

>No.100067
がちですみませんでした、つぎからはしっかりとおしえたいとおもいます



ゆっくりXP

リンク

2023/9/28(Thu) 06:57:09|NO.100095

右クリックメニューがなぜか変わらないです。
一応ポップアップメニューが反映されたということで解決チェック入れておきます。



沢渡

リンク

2023/9/28(Thu) 10:49:44|NO.100096

すみません、もしかしたらこれで上手くいくかもしれません。
ライト/ダークの切り替えのたびにSetPreferredAppModeを呼ぶのではなく、
SetPreferredAppModeのオプションを1(APPMODE_ALLOWDARK)にして
最初に1回だけ呼ぶようにするだけで、当方の環境(Windows10)では
ライト/ダークの切り替えがポップアップメニューに反映されました。
訳あって現在Windows11が使えないので、Windows11ではどうなるかわかりません。
これで上手くいけばいいのですが。

//SetWindowTheme関数がUnicodeを使用しているため、hsp3utf.asをインクルードしておく #include "hsp3utf.as" #uselib "gdi32.dll" #cfunc CreateSolidBrush "CreateSolidBrush" int #func DeleteObject "DeleteObject" int #func SetTextColor "SetTextColor" int,int #func SetBkColor "SetBkColor" int,int #uselib "user32.dll" #func GetWindowLong "GetWindowLongW" int,int #func SetWindowLong "SetWindowLongW" int,int,int #cfunc CreatePopupMenu "CreatePopupMenu" #func AppendMenu "AppendMenuW" int,int,int,wstr #func RedrawWindow "RedrawWindow" int,int,int,int #func TrackPopupMenu "TrackPopupMenu" int, int, int, int, int, int, int #func DestroyMenu "DestroyMenu" int #uselib "kernel32.dll" #cfunc LoadLibrary "LoadLibraryW" wstr #cfunc GetProcAddress "GetProcAddress" int,int #func FreeLibrary "FreeLibrary" int #uselib "dwmapi.dll" #func DwmGetWindowAttribute "DwmGetWindowAttribute" int, int, int, int #func DwmSetWindowAttribute "DwmSetWindowAttribute" int, int, int, int #uselib "uxtheme.dll" #func SetWindowTheme "SetWindowTheme" int, wptr,wptr #define dark_obj(%1) SetWindowTheme %1,"DarkMode_Explorer",0 #define dark_com_obj(%1) SetWindowTheme %1,"DarkMode_CFD",0 #define dark_list_obj(%1) SetWindowTheme %1,"DarkMode_ItemsView",0 #define light_obj(%1) SetWindowTheme %1,"",0 #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #define WM_WININICHANGE 0x001A #define WM_CTLCOLOREDIT 0x0133 #define WM_CTLCOLORSTATIC 0x0138 #define RDW_UPDATENOW 1 #module #uselib "advapi32.dll" #func RegOpenKeyEx "RegOpenKeyExW" int, wptr, int, int,var #func RegQueryValueEx "RegQueryValueExW" int, wptr, int,int,int,int #func RegCloseKey "RegCloseKey" int #define KEY_READ 0x20019 #define HKEY_CURRENT_USER 0x80000001 /** * レジストリの取得 */ #defcfunc get_regedit int h, str key, str name RegOpenKeyEx h, key, 0,KEY_READ,hkey RegQueryValueEx hkey, name, 0, 0, 0, varptr(sz) if stat == 0 { sdim data, sz RegQueryValueEx hkey, name, 0, 0, varptr(data), varptr(sz) } else { data = -1 } RegCloseKey hkey return data /** * システムがダークカラーかどうかをレジストリから取得 * ダークカラーが有効なら1、無効なら0 * そもそもダークカラー設定が存在しない場合は -1 を返す */ #defcfunc get_dark_color_type dark = 0 key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize" name = "AppsUseLightTheme" ret = get_regedit(HKEY_CURRENT_USER, key, name) tmpText = "" if ret != -1 { // ライトカラー設定 if peek(ret, 0) == 0 { dark = 1 } else { dark = 0 } } else { dark = -1 } return dark #global font "meiryo",16 objmode 2 cmb_dummy=0 pos 0,30 objsize 120,32 combox cmb_dummy,120,"ダーク\nモード\nテスト" cmx = objinfo_hwnd(stat) objsize 120,32 pos 120,30 button "ダーク",*dummy btn = objinfo_hwnd(stat) br_h = CreateSolidBrush(0x202020) //テキストボックスの背景色のブラシ br_h2 = CreateSolidBrush(0xFFFFFF) br_h3 = CreateSolidBrush(0xE1E1E1)//スタティックコントロールの背景色のブラシ pos 0 a = "ダークモードテスト" input a,ginfo_winx inp = objinfo_hwnd(stat) sdim s mesbox s,ginfo_winx,ginfo_winy-94 mbox = objinfo_hwnd(stat) //メニュー代わりのボタン pos 0,0 objsize 160,30 button gosub "ポップアップ",*popup menubtn1=objinfo_hwnd(stat) GetWindowLong menubtn1,-16 SetWindowLong menubtn1,-16,stat|0x8100 //穴埋め用のスタティックコントロール objsize 480,30 : pos 160,0 winobj "static","",,0x50000000 static=objinfo_hwnd(stat) //ポップアップメニュー関連 pmenu=CreatePopupMenu() AppendMenu pmenu,0,0,"ポップアップメニュー" //これらのAPIは非公開のためか、一寸迂遠な方法で呼ぶしかなさそう? lib_h = LoadLibrary("uxtheme.dll") //SetPreferredAppModeとRefreshImmersiveColorPolicyStateを呼ぶための準備 add = GetProcAddress(lib_h,135) //SetPreferredAppModeのアドレスを取得 prm=1 : dum=callfunc(prm,add,1) //SetPreferredAppModeを実行 add=GetProcAddress(lib_h,104) //RefreshImmersiveColorPolicyStateのアドレスを取得 dum=callfunc(prm,add,0) //RefreshImmersiveColorPolicyStateを実行 // システムの設定が変わったときに呼び出される oncmd gosub *lWM_WININICHANGE,WM_WININICHANGE // 起動時に一回呼び出しておく gosub *lWM_WININICHANGE onexit *exit stop // システムの設定が変更された *lWM_WININICHANGE // 他の部分はレジストリの変更検出なので、必要なのは実質ここだけ dim size dim opt dim prm,2 //ウィンドウの属性状態を取得 //DwmGetWindowAttribute hwnd, 0, 0, 4 if get_dark_color_type() == 1 : opt = 1 : else : opt = 0 //タイトルバーをダークモードに変更 DwmSetWindowAttribute hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, varptr(opt), 4 if opt { //オブジェクトをダークモードに変更 color 0,0,0:boxf dark_com_obj cmx dark_obj btn dark_obj menubtn1 dark_obj mbox oncmd gosub *edit_d,WM_CTLCOLOREDIT oncmd gosub *edit_d,WM_CTLCOLORSTATIC }else{ color 255,255,255:boxf light_obj cmx light_obj btn light_obj menubtn1 light_obj mbox oncmd gosub *edit_l,WM_CTLCOLOREDIT oncmd gosub *edit_l,WM_CTLCOLORSTATIC } RedrawWindow inp,0,0,RDW_UPDATENOW //強制再描画 RedrawWindow mbox,0,0,RDW_UPDATENOW RedrawWindow static,0,0,RDW_UPDATENOW return *dummy stop //ダークモード時のエディットボックス描画 *edit_d if lparam=inp | lparam=mbox | lparam=static { //lparamがエディットボックスのハンドルかどうかを調べ、そうならば処理を行う。 SetTextColor wparam,0xFFFFFF //文字の色 SetBkColor wparam,0x202020 //背景色 return br_h //ブラシを返す必要がある } return //ライトモード時のエディットボックス描画 *edit_l if lparam=inp | lparam=mbox | lparam=static { SetTextColor wparam,0x000000 //文字の色 if lparam=static { SetBkColor wparam,0xE1E1E1 //背景色 return br_h3 } else { SetBkColor wparam,0xFFFFFF //背景色 return br_h2 } } return *popup TrackPopupMenu pmenu,0,ginfo_mx,ginfo_my,0,hwnd,0 return *exit DeleteObject br_h //終了時にブラシを削除 DeleteObject br_h2 DeleteObject br_h3 DestroyMenu pmenu //メニューを削除 FreeLibrary lib_h //読み込んだライブラリを解放 end



名無し

リンク

2023/9/28(Thu) 14:18:03|NO.100097

あれ、右クリックメニューも含めてしっかり切り替わってたんですが、
沢渡さんの書き方を見る感じそちらも反映されてなかったっぽいので
何方かというとこちらの環境が特殊な感じだったのかな?
>>100096のコードも確認しましたがこちらではしっかり切り替わってました。



沢渡

リンク

2023/9/28(Thu) 15:24:46|NO.100098

すみません、言い足りませんでした。
NO.100077、NO.100082、NO.100096、いずれのコードも当方のWindows10環境では
想定通りの動作になりますが、ゆっくりXPさんの環境ではNO.100096のようにすれば
上手く行くかなと思っての投稿でした。



名無し

リンク

2023/9/28(Thu) 19:08:46|NO.100102

>>100098
なるほど、理解しました。
Windows10と11で仕様が微妙に変わったとか、この辺の違いなのかもですね。
横からのお目汚し失礼しました。



沢渡

リンク

2023/9/29(Fri) 10:48:31|NO.100104

追記です。Windows11での動作確認ができるようになったので確認しました。
私が先に挙げたNO.100077のコードですと、確かに
「実行中にWindowsの設定からライトモードに切り替えた際に、
 ポップアップメニューだけライトモードにならない」
という現象が発生しましたが、NO.100096の場合だと上手く行くようです。



ゆっくりXP

リンク

2023/9/29(Fri) 23:07:15|NO.100105

おお、Windows11でもわざわざ検証ありがとうございます!
自分の環境はWindows 11ですが、コンテストメニューも問題なく反映されたようです。
メニューバーは結構難しそうな感じですかね…?
とりあえず解決済みです。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.100064への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2023(c) All rights reserved.