はじめに
Wallpaper Engineの自作について記事を書きます。
現状同じようなことが書かれた記事はないため、後輩のために書きます。
自分は2024年に入学をした大学1年生です。
今回が初めての記事のため、至らない点があると思いますがご了承ください。
言語
仕様技術
Windowsのデスクトップウィンドウの仕組み
-
デスクトップの構造
-
Taskbarウィンドウ
- 最上層のウィンドウであり、下に表示されているタスクバーを管理している
- 最上層のウィンドウであり、下に表示されているタスクバーを管理している
-
Progmanウィンドウ
- Taskbarの一つ下の層であり、デスクトップのアイコンを管理している
- Taskbarの一つ下の層であり、デスクトップのアイコンを管理している
-
WorkerWウィンドウ
- Progmanの一つ下の層であり、普段は存在していないウィンドウ
- Progmanを再構築を行うと、WorkerWが作成される
-
Desktopウィンドウ
- デスクトップのファイル、ショートカットなどを管理している
Windowsのデスクトップはこれらの複数のレイヤーで構成されています。
主にWorkerWウィンドウを利用し、動的背景を実現していきます。 -
STEP1 - Pygameで動的背景ウィンドウの作成
-
画像の表示
左側で画像のpathを指定し、右側で画像の座標を指定する
screen.blit(image-path,(0,0))
-
ウィンドウの更新
ウィンドウを更新する
pygame.display.update()
-
ウィンドウの更新
FPSを指定する
clock.tick(60)
while True: screen.blit(back,(0,0)) pygame.display.update() clock.tick(60)
STEP2 - CtypesでWorkerWウィンドウの作成
-
Progmanのハンドルを取得
progman = ctypes.windll.user32.FindWindowW( "Progman" , None)
-
ウィンドウの更新
Progmanに再構築の命令を送る(0x052Cが再構築)
ctypes.windll.user32.SendMessageTimeoutW (progman,0x052C,0,0,0x0,1000,None)
-
ウィンドウの更新
生成されたWorkerWのハンドルを取得
workerw = ctypes.windll.user32.FindWindowExW(None,None,”WorkerW”,None)
progman = ctypes.windll.user32.FindWindowW( "Progman" , None) ctypes.windll.user32.SendMessageTimeoutW ( progman,0x052C,0,0,0x0,1000,None ) workerw = ctypes.windll.user32.FindWindowExW(None,None,”WorkerW”,None) return workerw
STEP3 - PygameウィンドウとWorkerWを繋げる
-
Pygameのハンドルを取得
window_info = pygame.display.get_wm_info()
-
その中のwindowハンドルを取得
hwnd = window_info["window"]
-
親子関係を設定
workerwを親、pygameを子として設定する
ctypes.windll.user32.SetParent( hwnd , workerw )
window_info = pygame.display.get_wm_info() hwnd = window_info["window"] ctypes.windll.user32.SetParent( hwnd , workerw )
まとめ
WallpaperEngineの自作方法をまとめました。
今回は、画像を表示する方法を中心にまとめましたが、以下のようなことも試したため、コメントがあれば記事にします。
- デスクトップでの3Dオブジェクトの操作
- 画像を高速更新することで、リアルタイムにアニメーションを反映させる
- 動画の表示