Archive for 7月 15th, 2012

  1. Hello, Win32 GUI(Python) World!

    Posted on 7月 15th, 2012 by cx20

    Win32 GUI(Python)

    Win32 アプリケーションは Windows 標準 API である Win32 API を使用した Windows アプリケーションである。
    以下は Python にて ctypes ライブラリを使用した Win32 GUI アプリケーション の例となっている。

    ソースコード

    import win32con
    import sys
    from ctypes import *
     
    WNDPROC = WINFUNCTYPE(c_long, c_int, c_uint, c_int, c_int)
     
    NULL            = c_int(0)
     
    WM_PAINT        = win32con.WM_PAINT
    WM_DESTROY      = win32con.WM_DESTROY
    CS_HREDRAW      = win32con.CS_HREDRAW
    CS_VREDRAW      = win32con.CS_VREDRAW
    IDI_APPLICATION = win32con.IDI_APPLICATION
    IDC_ARROW       = win32con.IDC_ARROW
    WHITE_BRUSH     = win32con.WHITE_BRUSH
    WS_OVERLAPPEDWINDOW = win32con.WS_OVERLAPPEDWINDOW
    CW_USEDEFAULT   = win32con.CW_USEDEFAULT
    SW_SHOWNORMAL   = win32con.SW_SHOWNORMAL
    SW_SHOW         = win32con.SW_SHOW
    SW_SHOWDEFAULT  = win32con.SW_SHOWDEFAULT
     
    GetModuleHandle = windll.kernel32.GetModuleHandleA
    BeginPaint      = windll.user32.BeginPaint
    EndPaint        = windll.user32.EndPaint
    PostQuitMessage = windll.user32.PostQuitMessage
    DefWindowProc   = windll.user32.DefWindowProcA
    CreateWindowEx  = windll.user32.CreateWindowExA
    CreateWindowEx.argtypes = [c_int, c_char_p, c_char_p, c_int, c_int, c_int, c_int, c_int, c_int, c_int, c_int, c_int]
    LoadIcon        = windll.user32.LoadIconA
    LoadCursor      = windll.user32.LoadCursorA
    RegisterClass   = windll.user32.RegisterClassA
    ShowWindow      = windll.user32.ShowWindow
    UpdateWindow    = windll.user32.UpdateWindow
    GetMessage      = windll.user32.GetMessageA
    TranslateMessage = windll.user32.TranslateMessage
    DispatchMessage = windll.user32.DispatchMessageA
    TextOut         = windll.gdi32.TextOutA
    GetStockObject  = windll.gdi32.GetStockObject
     
    class POINT(Structure):
        _fields_ = [('x', c_long),
                    ('y', c_long)]
     
    class MSG(Structure):
        _fields_ = [('hwnd', c_int),
                    ('message', c_uint),
                    ('wParam', c_int),
                    ('lParam', c_int),
                    ('time', c_int),
                    ('pt', POINT)]
     
    class WNDCLASS(Structure):
        _fields_ = [('style', c_uint),
                    ('lpfnWndProc', WNDPROC),
                    ('cbClsExtra', c_int),
                    ('cbWndExtra', c_int),
                    ('hInstance', c_int),
                    ('hIcon', c_int),
                    ('hCursor', c_int),
                    ('hbrBackground', c_int),
                    ('lpszMenuName', c_char_p),
                    ('lpszClassName', c_char_p)]
     
    class RECT(Structure):
        _fields_ = [('left', c_long),
                    ('top', c_long),
                    ('right', c_long),
                    ('bottom', c_long)]
     
    class PAINTSTRUCT(Structure):
        _fields_ = [('hdc', c_int),
                    ('fErase', c_int),
                    ('rcPaint', RECT),
                    ('fRestore', c_int),
                    ('fIncUpdate', c_int),
                    ('rgbReserved', c_char * 32)]
     
    def WndProc(hwnd, message, wParam, lParam):
        strMessage = "Hello, Win32 GUI(Python) World!"
        if message == WM_PAINT:
            ps = PAINTSTRUCT()
            hdc = BeginPaint( hwnd, byref(ps) )
            TextOut( hdc, 0, 0, strMessage, len(strMessage) )
            EndPaint( hwnd, byref(ps) )
            return 0
        elif message == WM_DESTROY:
            PostQuitMessage(0)
            return 0
     
        return DefWindowProc(hwnd, message, wParam, lParam)
     
    def WinMain():
        wndclass               = WNDCLASS()
        wndclass.style         = CS_HREDRAW | CS_VREDRAW
        wndclass.lpfnWndProc   = WNDPROC(WndProc)
        wndclass.cbClsExtra    = 0
        wndclass.cbWndExtra    = 0
        wndclass.hInstance     = GetModuleHandle(0)
        wndclass.hIcon         = LoadIcon(0, IDI_APPLICATION)
        wndclass.hCursor       = LoadCursor(0, IDC_ARROW)
        wndclass.hbrBackground = GetStockObject(WHITE_BRUSH)
        wndclass.lpszMenuName  = 0
        wndclass.lpszClassName = "helloWindow"
     
        RegisterClass(byref(wndclass))
     
        hwnd = CreateWindowEx(
            0,
            wndclass.lpszClassName,
            "Hello, World!",
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            640,
            480,
            0,
            0,
            wndclass.hInstance,
            0)
     
        ShowWindow(hwnd, SW_SHOWDEFAULT)
        UpdateWindow(hwnd)
     
        msg = MSG()
        pMsg = pointer(msg)
     
        while GetMessage( pMsg, NULL, 0, 0 ) != 0:
            TranslateMessage(pMsg)
            DispatchMessage(pMsg)
     
        return msg.wParam
     
    if __name__=='__main__':
        sys.exit(WinMain())

    実行方法

    C:¥> python hello.py

    実行結果

    +------------------------------------------+
    |Hello, World!                    [_][~][X]|
    +------------------------------------------+
    |Hello, Win32 GUI(Python) World!           |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    |                                          |
    +------------------------------------------+