win32 api in python
Charles Petzold hello world
/*------------------------------------------------------------ HELLOWIN.C -- Displays "Hello, Windows 98!" in client area (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
Hello world in Python using ctypes
- reference : http://blog-of-darius.blogspot.com/2011/03/programing-win32-with-python-2x-version.html
- win32 sdk api의 각종 상수나 구조체 등이 정의가 되어 있지않으므로 직접 정의하여 사용하여야 한다. 불편함
- user32.dll 등을 직접 사용하는데 unicode 관련하여 RegisterClass 등이 export 되어 있지 않고 직접 RegisterClassExW and CreateWindowExW 등을 가져다 써야 한다.
# -*- coding: utf-8 -*- from sys import platform, exit from ctypes import (windll, Structure, sizeof, WINFUNCTYPE, pointer, byref, c_uint, c_int, c_char) from ctypes.wintypes import (HWND, HANDLE, HBRUSH, LPCWSTR, WPARAM, LPARAM, MSG, RECT) # kernel32, gdi32, user32 are NOT module name # you must specify function name explicitly like "user32.CreateWindowExW" # cannot use "from user32 import *" kernel32 = windll.kernel32 gdi32 = windll.gdi32 user32 = windll.user32 # have to define constants WS_EX_APPWINDOW = 0x40000 WS_OVERLAPPEDWINDOW = 0xcf0000 WS_CAPTION = 0xc00000 SW_SHOWNORMAL = 1 SW_SHOW = 5 CS_HREDRAW = 2 CS_VREDRAW = 1 CW_USEDEFAULT = 0x80000000 WM_PAINT = 0xF WM_DESTROY = 0x2 WHITE_BRUSH = 0 DT_SINGLELINE = 0x20 DT_CENTER = 0x1 DT_VCENTER = 0x4 # have to declare data structures, function declaration WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM) # no CreateWindow export in user32.dll # We have to use WNDCLASSEX, RegisterClassExW and CreateWindowExW class WNDCLASSEX(Structure): _fields_ = [("cbSize", c_uint), ("style", c_uint), ("lpfnWndProc", WNDPROCTYPE), ("cbClsExtra", c_int), ("cbWndExtra", c_int), ("hInstance", HANDLE), ("hIcon", HANDLE), ("hCursor", HANDLE), ("hBrush", HBRUSH), ("lpszMenuName", LPCWSTR), ("lpszClassName", LPCWSTR), ("hIconSm", HANDLE), ] class PAINTSTRUCT(Structure): _fields_ = [('hdc', c_int), ('fErase', c_int), ('rcPaint', RECT), ('fRestore', c_int), ('fIncUpdate', c_int), ('rgbReserved', c_char * 32)] # removed play sound. def PyWndProcedure(hwnd, message, wParam, lParam): if message == WM_PAINT: ps = PAINTSTRUCT() rect = RECT() hdc = user32.BeginPaint(hwnd, byref(ps)) user32.GetClientRect(hwnd, byref(rect)) user32.DrawTextW(hdc, u"Hello, Windows 98!", -1, byref(rect), DT_SINGLELINE | DT_CENTER | DT_VCENTER) user32.EndPaint(hwnd, byref(ps)) return 0 ; elif message == WM_DESTROY: user32.PostQuitMessage(0) else: return user32.DefWindowProcW(hwnd, message, wParam, lParam) # need this return 0 WndProc = WNDPROCTYPE(PyWndProcedure) # have to get a handle to the current module explicitly hInst = kernel32.GetModuleHandleW(0) # create window class structure szAppName = u"HelloWin" wndclass = WNDCLASSEX() wndclass.cbSize = sizeof(WNDCLASSEX) wndclass.style = CS_HREDRAW | CS_VREDRAW wndclass.lpfnWndProc = WndProc wndclass.cbClsExtra = 0 wndclass.cbWndExtra = 0 wndclass.hInstance = hInst wndclass.hIcon = 0 wndclass.hCursor = 0 wndclass.hBrush = gdi32.GetStockObject(WHITE_BRUSH) wndclass.lpszMenuName = 0 wndclass.lpszClassName = szAppName wndclass.hIconSm = 0 # register window class hr_registerclass = user32.RegisterClassExW(byref(wndclass)) # create window hwnd = user32.CreateWindowExW(0, szAppName, u"The Hello Program", WS_OVERLAPPEDWINDOW | WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, 0) user32.ShowWindow(hwnd, SW_SHOW) user32.UpdateWindow(hwnd) msg = MSG() lpmsg = pointer(msg) while user32.GetMessageW(byref(msg), 0, 0, 0) != 0: user32.TranslateMessage(byref(msg)) user32.DispatchMessageW(byref(msg))
Hello world in python using win32py
# -*- coding: utf-8 -*- from win32api import (GetModuleHandle,) from win32gui import (WNDCLASS, GetStockObject, RegisterClass, CreateWindow, ShowWindow, UpdateWindow, GetMessage, TranslateMessage, DispatchMessage, PostQuitMessage, BeginPaint, GetClientRect, DrawText, EndPaint, ) from win32con import (WHITE_BRUSH, WS_OVERLAPPEDWINDOW, WS_CAPTION, CW_USEDEFAULT, SW_SHOW, WM_PAINT, WM_DESTROY, CS_VREDRAW, CS_HREDRAW, DT_SINGLELINE, DT_CENTER, DT_VCENTER, ) def OnPaint(hwnd, message, wParam, lParam): hdc, ps = BeginPaint(hwnd) rect = GetClientRect(hwnd) int, rect = DrawText(hdc, u"Hello, Windows 98!" , -1 , rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) EndPaint(hwnd, ps) return 0 def OnDestroy(hwnd, message, wParam, lParam): PostQuitMessage(0) message_map = {WM_PAINT: OnPaint, WM_DESTROY: OnDestroy, } # have to create hInstance explicitly hInst = GetModuleHandle() # create window class structure szAppName = u"HelloWin" wndclass = WNDCLASS() wndclass.style = CS_HREDRAW | CS_VREDRAW wndclass.lpfnWndProc = message_map wndclass.cbWndExtra = 0 wndclass.hInstance = hInst wndclass.hIcon = 0 wndclass.hCursor = 0 wndclass.hbrBackground = GetStockObject(WHITE_BRUSH) wndclass.lpszMenuName = '' wndclass.lpszClassName = szAppName.encode('utf8') # need encode! # register window class hr_registerclass = RegisterClass(wndclass) # create window hwnd = CreateWindow(szAppName, u"The Hello Program", WS_OVERLAPPEDWINDOW | WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, None) # must be None! ShowWindow(hwnd, SW_SHOW) UpdateWindow(hwnd) # message loop while True: b, msg = GetMessage(hwnd, 0, 0) if msg == 0: break TranslateMessage(msg) DispatchMessage(msg)
Another version
- all message monitoring
- use pyqt
# -*- coding: utf-8 -*- from win32api import (GetModuleHandle,) from win32gui import (WNDCLASS, GetStockObject, RegisterClass, CreateWindow, ShowWindow, UpdateWindow, GetMessage, TranslateMessage, DispatchMessage, PostQuitMessage, BeginPaint, GetClientRect, DrawText, EndPaint, DefWindowProc, ) from win32con import (WHITE_BRUSH, WS_OVERLAPPEDWINDOW, WS_CAPTION, CW_USEDEFAULT, SW_SHOW, WM_PAINT, WM_DESTROY, CS_VREDRAW, CS_HREDRAW, DT_SINGLELINE, DT_CENTER, DT_VCENTER, ) from PyQt4.QtCore import * from PyQt4.QtGui import * def OnEvent(hwnd, message, wParam, lParam): print message, wParam, lParam if message == WM_PAINT: OnPaint(hwnd, message, wParam, lParam) elif message == WM_DESTROY: OnDestroy(hwnd, message, wParam, lParam) else: return DefWindowProc(hwnd, message, wParam, lParam) return 0 def OnPaint(hwnd, message, wParam, lParam): hdc, ps = BeginPaint(hwnd) rect = GetClientRect(hwnd) int, rect = DrawText(hdc, u"Hello, Windows 98!" , -1 , rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) EndPaint(hwnd, ps) return 0 def OnDestroy(hwnd, message, wParam, lParam): PostQuitMessage(0) message_map = {WM_PAINT: OnPaint, WM_DESTROY: OnDestroy, } # have to create hInstance explicitly hInst = GetModuleHandle() # create window class structure szAppName = u"HelloWin" wndclass = WNDCLASS() wndclass.style = CS_HREDRAW | CS_VREDRAW wndclass.lpfnWndProc = OnEvent#message_map wndclass.cbWndExtra = 0 wndclass.hInstance = hInst wndclass.hIcon = 0 wndclass.hCursor = 0 wndclass.hbrBackground = GetStockObject(WHITE_BRUSH) wndclass.lpszMenuName = '' wndclass.lpszClassName = szAppName.encode('utf8') # need encode! # register window class hr_registerclass = RegisterClass(wndclass) # create window hwnd = CreateWindow(szAppName, u"The Hello Program", WS_OVERLAPPEDWINDOW | WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, None) # must be None! ShowWindow(hwnd, SW_SHOW) UpdateWindow(hwnd) # message loop app = QApplication([]) app.exec_()
page revision: 0, last edited: 03 May 2011 09:08