ctypes.windllでメッセージボックスを表示する(Python)
先日、AIにPythonのコードを書いてもらったらメッセージボックスを表示するためにctypes.windll.user32.MessageBoxW(…)と書いてありました。
そこでctypes.windll…とはなんぞやと調べた内容を書き留めておきます。
■ コード
import ctypes
MB_ICONINFO = 0x00000040 # 情報アイコン
MB_ICONERROR = 0x00000010 # エラーアイコン
def msg(text: str, title: str, icon: int = MB_ICONINFO):
ctypes.windll.user32.MessageBoxW(0, text, title, icon)
msg(
f"ctypes.windllを使ってメッセージボックスを出すことができます。\n"
f"ここにはエラーメッセージなどを表示させられます。",
title="メッセージボックスのタイトル"
)メッセージボックス表示に関するコードはここ。
ctypes.windll.user32.MessageBoxW(0, text, title, icon)それぞれの意味について調べました。
ctypes
Pythonの標準ライブラリ。動的リンクライブラリ(Windowsの.dll / Linuxの.soなど)を直接呼び出すためのFFI。
参考:ctypes — Python 用の外部関数ライブラリ
.windll
呼び出したいdllがどの呼び出し規約でエクスポートされているかに応じて使い分ける。
呼び出し規約とは関数を呼び出す時の引数の渡し方、戻り値の受け取り方などの決め事、らしいです。詳細はWikipediaや呼び出し規約(Microsoft Learn)のほか下記ブログが参考になるかと思ったので載せておきます。
参考:呼出規約とは – 備忘録
呼び出し規約はいくつかあり、Windows標準の__stdcallとC言語標準の__cdeclが有名らしい。呼び出し規約が__stdcallの場合は「ctypes.windll.<dll>」、__cdeclの場合は「ctypes.cdll.<dll>」という形式になる。ほかにもctypes.oledll、ctypes.pydllなどもある。
もっというとWIndowsのdllを扱う方法は「ctypes.windll」のほかに「ctypes.WinDLL」もあるらしい。下記参考サイト等を見るときちんと設計するのならWinDLLの方が適切なケースもあるかもしれませんが、自分のように自作ツールを自分で使うだけなら「windll」で良さそうです。
参考:Python ctypesのwindll、WinDLL、LibraryLoader(WinDLL)の違いの調べごと
.user32
Windowsが提供しているWindows32 APIを使うという意味。
具体的には C:\Windows\System32 にあるuser32.dllの「user32」らしい。自作dllを使用する場合等はフルパスを指定する(またはカレントディレクトリに配置する、パスの通る場所に配置するなど)といった記載方法になるらしい。
.MessageBoxW
user32.dll内にあるMessageBoxW関数を使用するという指定です。
MessageBoxA(ANSI対応)だと文字化けすることがあるそうです。MessageBoxWのWはWide char(UTF-16)。
詳細は下記ページの通り。
参考:MessageBoxW 関数 (winuser.h) – Microsoft Learn
パラメーターの4つめを指定することでメッセージボックスのボタンの種類(はい、いいえ、キャンセル、OKなど)や表示させるアイコンなどを指定できます。
具体的な数字は上記にMicrosoftページに記載されています。下記ブログやサイトの方が分かりやすい時もあるかも。
参考:Pythonのwindllでメッセージボックスを使いこなす
参考:Python MessageBox with Icons using ctypes and windll
元々のコードでは常にボタンは「OK」のみで、アイコンは情報アイコンとエラーアイコンを使い分けるようにしているようです。
そんな感じでctypes.windllでメッセージボックスを表示するコードについて調べたメモでした。
dllに関する知識がなかったので勉強になりました。ちなみWin32 APIに関する関数の情報を集めたページがあったのでリンクを載せておきます。それぞれの関数で何ができるか調べたら面白そうです。
終わり。