0
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?

Python で Win32 API (win32more)

Last updated at Posted at 2025-09-14

win32metadata は Microsoft 公式のプロジェクトで、Win32 API のメタデータを提供している。Rust では Microsoft が開発している windows-rs が 広く使われており、このプロジェクトのデータを利用している。
その Python 版にあたるのが win32more で、こちらはコミュニティによって開発されている。実際に使ってみた内容を簡単にまとめる。

インストール

pip install win32more

コード例

Microsoft の Win32 API サンプルプログラム を Python で書き直した。エントリポイントについては、MinGW-w64 の crtexewin.c を参考にした。

import sys

from win32more.Windows.Win32.Graphics.Gdi import (
    COLOR_WINDOW,
    PAINTSTRUCT,
    BeginPaint,
    EndPaint,
    FillRect,
)
from win32more.Windows.Win32.System.Environment import GetCommandLineW
from win32more.Windows.Win32.System.LibraryLoader import GetModuleHandleW
from win32more.Windows.Win32.System.Threading import (
    STARTF_USESHOWWINDOW,
    STARTUPINFOW,
    GetStartupInfoW,
)
from win32more.Windows.Win32.UI.WindowsAndMessaging import (
    CW_USEDEFAULT,
    MSG,
    SW_SHOWDEFAULT,
    WM_DESTROY,
    WM_PAINT,
    WNDCLASSW,
    WNDPROC,
    WS_OVERLAPPEDWINDOW,
    CreateWindowExW,
    DefWindowProcW,
    DispatchMessageW,
    GetMessageW,
    PostQuitMessage,
    RegisterClassW,
    ShowWindow,
    TranslateMessage,
)


@WNDPROC
def WindowProc(hwnd, uMsg, wParam, lParam):
    if uMsg == WM_DESTROY:
        PostQuitMessage(0)
        return 0

    elif uMsg == WM_PAINT:
        ps = PAINTSTRUCT()
        hdc = BeginPaint(hwnd, ps)

        # All painting occurs here, between BeginPaint and EndPaint.

        FillRect(hdc, ps.rcPaint, COLOR_WINDOW + 1)
        EndPaint(hwnd, ps)
        return 0

    return DefWindowProcW(hwnd, uMsg, wParam, lParam)


def wWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow):
    # Register the window class.
    CLASS_NAME = "Sample Window Class"

    wc = WNDCLASSW()
    wc.lpfnWndProc = WindowProc
    wc.hInstance = hInstance
    wc.lpszClassName = CLASS_NAME

    RegisterClassW(wc)

    # Create the window.

    hwnd = CreateWindowExW(
        0,  # Optional window styles.
        CLASS_NAME,  # Window class
        "Learn to Program Windows",  # Window text
        WS_OVERLAPPEDWINDOW,  # Window style
        # Size and position
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        None,  # Parent window
        None,  # Menu
        hInstance,  # Instance handle
        None,  # Additional application data
    )

    if hwnd == None:
        return 0

    ShowWindow(hwnd, nCmdShow)

    # Run the message loop.

    msg = MSG()
    while GetMessageW(msg, None, 0, 0) > 0:
        TranslateMessage(msg)
        DispatchMessageW(msg)

    return 0


if __name__ == "__main__":
    hInstance = GetModuleHandleW(None)

    pCmdLine = GetCommandLineW()
    if pCmdLine != None:
        in_double_quote = False
        i = 0
        while i < len(pCmdLine) and (pCmdLine[i] > " " or in_double_quote):
            if pCmdLine[i] == '"':
                in_double_quote = not in_double_quote
            i += 1
        while i < len(pCmdLine) and pCmdLine[i] <= " ":
            i += 1
        pCmdLine = pCmdLine[i:]
    else:
        pCmdLine = ""

    startup_info = STARTUPINFOW()
    GetStartupInfoW(startup_info)
    if startup_info.dwFlags & STARTF_USESHOWWINDOW:
        nCmdShow = startup_info.wShowWindow
    else:
        nCmdShow = SW_SHOWDEFAULT

    sys.exit(wWinMain(hInstance, None, pCmdLine, nCmdShow))

API がどの階層にあるか調べる方法

Win32 API の公式ドキュメントには win32metadata における階層は記載されていないため、自分で調べる必要がある。

win32metadata の README には次のように記載されている。

If you'd like to browse the metadata to see what we're emitting, extract Windows.Win32.winmd from the Microsoft.Windows.SDK.Win32Metadata NuGet package and load Windows.Win32.winmd in ILSpy. Download the package and rename it to .zip to browse and extract its content.

つまり、NuGet パッケージから Windows.Win32.winmd を取り出し、ILSpy で読み込んで検索できるという意味である。手順を整理すると以下のとおり。

  1. ILSpy を入手する (Zip 版で十分なので解凍して使用する)
  2. win32metadata の NuGet パッケージをダウンロードする。右側 「About」 の 「Download package (X.XX MiB)」リンクからダウンロードできる
  3. ダウンロードした microsoft.windows.sdk.win32metadata.~.nupkg の拡張子を .zip に変更する
  4. 中にある Windows.Win32.winmd を解凍する。(他のファイルは不要)
  5. ILSpy を起動し、「Assemblies」ウィンドウに Windows.Win32.winmd をドラッグ&ドロップする
  6. ツールバーの 「Window」 → 「Search (Ctrl + Shift + F)」を開く
  7. 検索対象 (Search for:) を「Types and Members」に設定し、検索欄に「=検索したい名前」と入力して検索する
    • 例1: =CreateWindowExW
    • 例2: =WS_OVERLAPPEDWINDOW
  8. 検索結果をダブルクリックすると、「Assemblies」ウィンドウ内でハイライトされる
  9. 右クリックで「Copy FQ Name」を実行すると、フルネームがクリップボードにコピーされる
  10. 関数や定数の場合、コピーした名前に .Apis.型名 の階層が含まれるため、必要に応じて削除する
  • 例1: Windows.Win32.UI.WindowsAndMessaging.Apis.CreateWindowExW.Apis を削除
  • 例2: Windows.Win32.UI.WindowsAndMessaging.WINDOW_STYLE.WS_OVERLAPPEDWINDOW.WINDOW_STYLE を削除
0
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
0
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?