2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wallpaper EngineをPythonで再現?Pygameで作るアニメーション壁紙

Posted at

はじめに

Wallpaper Engineの自作について記事を書きます。

現状同じようなことが書かれた記事はないため、後輩のために書きます。
自分は2024年に入学をした大学1年生です。
今回が初めての記事のため、至らない点があると思いますがご了承ください。

言語

  • Python

仕様技術

  • Pygame

    アニメーションフレームや動く画像を簡単に描画できるPygameを利用

  • Ctypes

    WindowsAPIをpython側で利用するためのもの

Windowsのデスクトップウィンドウの仕組み

  • デスクトップの構造

    • Taskbarウィンドウ
      • 最上層のウィンドウであり、下に表示されているタスクバーを管理している

    • Progmanウィンドウ
      • 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オブジェクトの操作
  • 画像を高速更新することで、リアルタイムにアニメーションを反映させる
  • 動画の表示
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?