2023/11/30(木) [n年前の日記]
#2 [hsp] hsp3dishでスクリーンセーバを作れないか再度挑戦したがダメだった
HSP の hsp3dish を使ってスクリーンセーバを作れないものかと考えていたけれど、名案(?)が閃いたので、再度試してみた。
結果を先に書くと、やっぱりダメだった。
環境は、Windows10 x64 22H2 + HSP 3.7 beta 7。
結果を先に書くと、やっぱりダメだった。
環境は、Windows10 x64 22H2 + HSP 3.7 beta 7。
◎ 経緯 :
以前、hsp3dish を使ってスクリーンセーバが作れるのか実験してみたけれど、その時の実験は失敗に終わった。
HSPの標準機能を使ってスクリーンセーバを作成する場合、フルスクリーン表示モードにおいては、以下のような状態で作ることになっている。
しかし、hsp3dish は、表示ウインドウが必ず1つであることを強制する上に、必ずウインドウID0に描画するという制限がある。ウインドウID2が作れないし、ウインドウID2に描画していくこともできない…。
hsp3dishを使って、ウインドウID0をデスクトップサイズに変更して描画してみたが、一見それらしく表示されたものの、通常のスクリーンセーバのようには動作してくれなかった。マウスを動かしても、キーボードを叩いても、終了してくれない。これではスクリーンセーバにならない。
と、ここまでが前回の実験結果だった。
そこでふと、自前でキー押しやマウスカーソル移動を判定して、自分で勝手に終了してしまえばいいのではないかと思いついた。
また、多重起動禁止も盛り込んでおいた。と言うのも、Windowsのスクリーンセーバは多重起動されてしまう時があるらしいので…。このあたりも、HSP側がイイ感じに処理してくれないだろうから、自前で処理しなければならない可能性がある。
そんなわけで、それで上手くいくのか、実験をしてみたのだけど…。
HSPの標準機能を使ってスクリーンセーバを作成する場合、フルスクリーン表示モードにおいては、以下のような状態で作ることになっている。
- HSP起動時に作られるウインドウID0には一切手を触れない。
- 表示ウインドウID2を新規作成して、そのウインドウID2に描画していく。
しかし、hsp3dish は、表示ウインドウが必ず1つであることを強制する上に、必ずウインドウID0に描画するという制限がある。ウインドウID2が作れないし、ウインドウID2に描画していくこともできない…。
hsp3dishを使って、ウインドウID0をデスクトップサイズに変更して描画してみたが、一見それらしく表示されたものの、通常のスクリーンセーバのようには動作してくれなかった。マウスを動かしても、キーボードを叩いても、終了してくれない。これではスクリーンセーバにならない。
と、ここまでが前回の実験結果だった。
そこでふと、自前でキー押しやマウスカーソル移動を判定して、自分で勝手に終了してしまえばいいのではないかと思いついた。
また、多重起動禁止も盛り込んでおいた。と言うのも、Windowsのスクリーンセーバは多重起動されてしまう時があるらしいので…。このあたりも、HSP側がイイ感じに処理してくれないだろうから、自前で処理しなければならない可能性がある。
そんなわけで、それで上手くいくのか、実験をしてみたのだけど…。
◎ ソース :
実験に使ったソースは以下。
_ssstarh3d.hsp
使用画像は以下。
_star.png
_preview.png
動作させると以下のような画面になる。昔のWindowsに標準で入ってた「宇宙飛行」みたいなソレ。
_ssstarh3d.hsp
使用画像は以下。
_star.png
_preview.png
動作させると以下のような画面になる。昔のWindowsに標準で入ってた「宇宙飛行」みたいなソレ。
◎ 結果 :
この実験も失敗に終わった。
フルスクリーン表示モードは、一見それらしくなってるし、何かのキーを押すか、マウスを動かせば終了するようになったのだけど。
Windows10の、「スクリーンセーバーの変更」ウインドウで、hsp3dish を使って作ったスクリーンセーバを選んだところ、ウインドウ内の小さな窓に収まるようにプレビュー画像を表示することができなかった。別ウインドウが表示されてしまって、その中にプレビューが表示されてしまう。
HSPの標準機能を使ってスクリーンセーバを作る場合は、「スクリーンセーバーの変更」から与えられたウインドウハンドルに従って、ウインドウID0が小さな窓に収まるようにサイズその他が調整されるのだけど…。
hsp3dish を使った場合は、与えられたウインドウハンドルも、ウインドウハンドルから得られる情報もガン無視して、いつものように通常ウインドウを表示してしまうのだろう…。
そんなわけで、HSp 3.7 beta 7 の時点では、hsp3dish を使ってWindows用のスクリーンセーバは作れない ―― そう断言してもいいのかもしれない。無念。
フルスクリーン表示モードは、一見それらしくなってるし、何かのキーを押すか、マウスを動かせば終了するようになったのだけど。
Windows10の、「スクリーンセーバーの変更」ウインドウで、hsp3dish を使って作ったスクリーンセーバを選んだところ、ウインドウ内の小さな窓に収まるようにプレビュー画像を表示することができなかった。別ウインドウが表示されてしまって、その中にプレビューが表示されてしまう。
HSPの標準機能を使ってスクリーンセーバを作る場合は、「スクリーンセーバーの変更」から与えられたウインドウハンドルに従って、ウインドウID0が小さな窓に収まるようにサイズその他が調整されるのだけど…。
hsp3dish を使った場合は、与えられたウインドウハンドルも、ウインドウハンドルから得られる情報もガン無視して、いつものように通常ウインドウを表示してしまうのだろう…。
そんなわけで、HSp 3.7 beta 7 の時点では、hsp3dish を使ってWindows用のスクリーンセーバは作れない ―― そう断言してもいいのかもしれない。無念。
◎ 多重起動禁止について :
多重起動禁止処理については、以下のページが参考になった。
_二重起動の防止(1) - Advanced HSP
_HSP講座 - プログラ広場 (mutex.as)
Windows の kernel32.dll が持っている、CreateMutex関数を利用することで、多重起動しているかどうかを判別できるので、ソレを使って多重起動禁止処理が作れるらしい。
紹介されているソースをコピペさせてもらって、手元でも動作確認してみた。
_test_createmutex_b.hsp
生成された .exe を最初に実行すると以下のような表示になる。
その状態で、同じ .exe をまた実行すると、以下のような表示になる。OKボタンをクリックすれば終了する。
たしかに、多重起動禁止が実現できた。
_二重起動の防止(1) - Advanced HSP
_HSP講座 - プログラ広場 (mutex.as)
Windows の kernel32.dll が持っている、CreateMutex関数を利用することで、多重起動しているかどうかを判別できるので、ソレを使って多重起動禁止処理が作れるらしい。
紹介されているソースをコピペさせてもらって、手元でも動作確認してみた。
_test_createmutex_b.hsp
; 多重起動禁止テストその2 ; ; 二重起動の防止(1) - Advanced HSP ; http://chokuto.ifdef.jp/advanced/singleton1.html ; ; 2023/11/30, Windows10 x64 22H2 + HSP 3.7 beta 7 #packopt name "test_createmutex_b" ; filename #packopt type 0 ; generate ".exe" ; 多重起動をチェックするためのミューテックスオブジェクト名を定義。 ; アプリ固有の名前であること。 #define MUTEX_NAME "HSP_WinAPI_Test_Mutex" ; ---------------------------------------- ; アプリケーションの起動チェックを行うモジュール #module #uselib "kernel32.dll" #cfunc CreateMutex "CreateMutexA" int, int, sptr #cfunc GetLastError "GetLastError" #func CloseHandle "CloseHandle" int #define ERROR_ALREADY_EXISTS 183 ; アプリがすでに起動されているか取得する関数 #defcfunc AlreadyAppRunning str name if (hMutex == 0) { ; 名前付きミューテックスオブジェクトの作成 hMutex = CreateMutex(0, 0, name) ; オブジェクトがすでに作成されていたかどうかの判別 if (GetLastError() == ERROR_ALREADY_EXISTS) { ; すでに同じ名前のオブジェクトが存在する alreadyRunning = 1 } else { ; オブジェクトが新しく作成された alreadyRunning = 0 } } return alreadyRunning ; クリーンアップ処理(終了時に自動実行) #deffunc CleanupAppRunChecker onexit if (hMutex != 0) { ; ミューテックスオブジェクトハンドルのクローズ CloseHandle hMutex hMutex = 0 } return ; ---------------------------------------- #global *start if (AlreadyAppRunning(MUTEX_NAME)) { dialog "すでに起動されています。" end } mes "二重起動してしません。" stop
生成された .exe を最初に実行すると以下のような表示になる。
その状態で、同じ .exe をまた実行すると、以下のような表示になる。OKボタンをクリックすれば終了する。
たしかに、多重起動禁止が実現できた。
◎ マウスカーソル座標の取得 :
デスクトップ上のマウスカーソル座標の取得でちょっとハマったのでメモ。
HSP の場合、ginfo_mx, ginfo_my で、デスクトップ上のマウスカーソル座標が得られる。
当初、mousex, mousey でマウスカーソル座標を取得しようとしたのだけど。これはアプリウインドウ内にマウスカーソルがある場合に、アプリウインドウ内のマウスカーソル座標を取得できる変数だった。アプリウインドウの外でマウスカーソルを動かして、反応しないな、おかしいなと悩んでしまった…。
HSP の場合、ginfo_mx, ginfo_my で、デスクトップ上のマウスカーソル座標が得られる。
当初、mousex, mousey でマウスカーソル座標を取得しようとしたのだけど。これはアプリウインドウ内にマウスカーソルがある場合に、アプリウインドウ内のマウスカーソル座標を取得できる変数だった。アプリウインドウの外でマウスカーソルを動かして、反応しないな、おかしいなと悩んでしまった…。
[ ツッコむ ]
以上です。