ドキュメントのバグだと思います。;-)
Python 3 では、すべての文字列はデフォルトで Unicode ですが、例ではUnicode バージョンMessageBoxA
ではなく ANSI 関数を呼び出しています。16.17.1.2MessageBoxW
を参照してください。ドキュメント内の読み込まれた dll からの関数へのアクセス。ctypes
したがってMessageBoxA
、この例では、関数の入力文字列引数を必要なものにエンコードすることで機能させることができますlocale.getpreferredencoding()
。
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT
import locale
preferred_encoding = locale.getpreferredencoding(False)
prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags = ((1, "hwnd", 0), (1, "text", "Hi".encode(preferred_encoding)),
(1, "caption", None), (1, "flags", 0))
MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
MessageBox()
MessageBox(text="Spam, spam, spam".encode(preferred_encoding))
MessageBox(flags=2, text="foo bar".encode(preferred_encoding))
MessageBoxW
"ワイド" Unicode 文字列引数 (LPCWSTR
の代わりに) をサポートする Windows 関数を使用するとLPCSTR
、ほとんどすべての呼び出しでそれらの明示的なエンコードが不要になります。さらに、この例の「マジック ナンバー」のほとんどを名前付き定数に置き換えます。
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCWSTR, UINT
import win32con # contains Win32 constants pulled from the C header files
INPUT_PARM, OUTPUT_PARAM, INPUT_PARM_DEFAULT_ZERO = 1, 2, 4
prototype = WINFUNCTYPE(c_int, HWND, LPCWSTR, LPCWSTR, UINT)
paramflags = ((INPUT_PARM, "hwnd", 0),
(INPUT_PARM, "text", "Hi"),
(INPUT_PARM, "caption", None),
(INPUT_PARM, "flags", win32con.MB_HELP))
MessageBox = prototype(("MessageBoxW", windll.user32), paramflags)
MessageBox()
MessageBox(text="Spam, spam, spam")
MessageBox(flags=win32con.MB_ABORTRETRYIGNORE, text="foo bar")