python3 ctype CreateWindowEx简单示例

Dar*_*kas 6 winapi ctypes pywin32 win32gui python-3.x

我已经google了一段时间,但找不到用于创建和显示窗口的python3 ctypes和Win32 API的简单示例.请指出我的好链接或显示代码.

提前致谢!

Dav*_*nan 10

这对win32gui模块及其朋友win32api和win32con来说最容易实现.没有必要为Windows API编写自己的ctypes包装器.最简单的Petzold风格的应用程序出现如下:

import win32api, win32con, win32gui

class MyWindow:

    def __init__(self):
        win32gui.InitCommonControls()
        self.hinst = win32api.GetModuleHandle(None)
        className = 'MyWndClass'
        message_map = {
            win32con.WM_DESTROY: self.OnDestroy,
        }
        wc = win32gui.WNDCLASS()
        wc.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW
        wc.lpfnWndProc = message_map
        wc.lpszClassName = className
        win32gui.RegisterClass(wc)
        style = win32con.WS_OVERLAPPEDWINDOW
        self.hwnd = win32gui.CreateWindow(
            className,
            'My win32api app',
            style,
            win32con.CW_USEDEFAULT,
            win32con.CW_USEDEFAULT,
            300,
            300,
            0,
            0,
            self.hinst,
            None
        )
        win32gui.UpdateWindow(self.hwnd)
        win32gui.ShowWindow(self.hwnd, win32con.SW_SHOW)

    def OnDestroy(self, hwnd, message, wparam, lparam):
        win32gui.PostQuitMessage(0)
        return True

w = MyWindow()
win32gui.PumpMessages()
Run Code Online (Sandbox Code Playgroud)

  • @Tcll`pip install pypiwin32` (3认同)

Tcl*_*cll 5

找到了这个漂亮的小饰品,并花时间让它在 vanilla python 3.4.0 的标准库上工作:(
对于那些希望通过 PyWin32 使用本地程序的人)
http://code.activestate.com/recipes/208699 -calling-windows-api-using-ctypes-and-win32con/

import sys
from ctypes import *

kernel32 = windll.kernel32
user32 = windll.user32
gdi32 = windll.gdi32

NULL = 0
CW_USEDEFAULT = -2147483648
IDI_APPLICATION = 32512
WS_OVERLAPPEDWINDOW = 13565952

CS_HREDRAW = 2
CS_VREDRAW = 1

IDC_ARROW = 32512
WHITE_BRUSH = 0

SW_SHOWNORMAL = 1

WNDPROC = WINFUNCTYPE(c_long, c_int, c_uint, c_int, c_int)

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)]

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)]

def ErrorIfZero(handle):
    if handle == 0:
        raise WinError
    else:
        return handle

def MainWin():
    global NULL
    CreateWindowEx          = 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]
    CreateWindowEx.restype  = ErrorIfZero

    # Define Window Class
    wndclass = WNDCLASS()
    wndclass.style          = CS_HREDRAW | CS_VREDRAW
    wndclass.lpfnWndProc    = WNDPROC(WndProc)
    wndclass.cbClsExtra = wndclass.cbWndExtra = 0
    wndclass.hInstance      = kernel32.GetModuleHandleA(c_int(NULL))
    wndclass.hIcon          = user32.LoadIconA(c_int(NULL), c_int(IDI_APPLICATION))
    wndclass.hCursor        = user32.LoadCursorA(c_int(NULL), c_int(IDC_ARROW))
    wndclass.hbrBackground  = gdi32.GetStockObject(c_int(WHITE_BRUSH))
    wndclass.lpszMenuName   = None
    wndclass.lpszClassName  = b"MainWin"
    # Register Window Class
    if not user32.RegisterClassA(byref(wndclass)):
        raise WinError()
    # Create Window
    hwnd = CreateWindowEx(0,
                          wndclass.lpszClassName,
                          b"Python Window",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          NULL,
                          NULL,
                          wndclass.hInstance,
                          NULL)
    # Show Window
    user32.ShowWindow(c_int(hwnd), c_int(SW_SHOWNORMAL))
    user32.UpdateWindow(c_int(hwnd))
    # Pump Messages
    msg = MSG()
    pMsg = pointer(msg)
    NULL = c_int(NULL)

    while user32.GetMessageA( pMsg, NULL, 0, 0) != 0:
        user32.TranslateMessage(pMsg)
        user32.DispatchMessageA(pMsg)

    return msg.wParam

WM_PAINT = 15
WM_DESTROY = 2

DT_SINGLELINE = 32
DT_CENTER = 1
DT_VCENTER = 4
def WndProc(hwnd, message, wParam, lParam):
    ps = PAINTSTRUCT()
    rect = RECT()

    if message == WM_PAINT:
        hdc = user32.BeginPaint(c_int(hwnd), byref(ps))
        user32.GetClientRect(c_int(hwnd), byref(rect))
        user32.DrawTextA(c_int(hdc),
                         b"Python Powered Windows" ,
                         c_int(-1), byref(rect), 
                         DT_SINGLELINE|DT_CENTER|DT_VCENTER)
        user32.EndPaint(c_int(hwnd), byref(ps))
        return 0
    elif message == WM_DESTROY:
        user32.PostQuitMessage(0)
        return 0

    return user32.DefWindowProcA(c_int(hwnd), c_int(message), c_int(wParam), c_int(lParam))

if __name__=='__main__':
    sys.exit(MainWin())
Run Code Online (Sandbox Code Playgroud)



Mar*_*nen 5

这里是纯粹的ctypes基于 @Tcll 答案的纯版本,也移植到“广泛”API。原始版本无法正确处理 64 位 Python(将句柄转换为 c_int)并且使用 ANSI API,但不再推荐这样做。它还为所有内容声明完整的 argtypes/restype 以帮助捕获编码错误。

\n

正如您所看到的,使用起来更加容易pywin32

\n

在 Python 2.7 32 位、Python 3.6 64 位和 Python 3.8 32 位上测试。

\n
#coding:utf8\nfrom __future__ import unicode_literals\n\nimport sys\nfrom ctypes import *\nfrom ctypes import wintypes as w  # ctypes has many pre-defined Windows types\n\ndef errcheck(result,func,args):\n    if result is None or result == 0:\n        raise WinError(get_last_error())\n    return result\n\n# Missing from ctypes.wintypes...\nLRESULT = c_int64\nHCURSOR = c_void_p\n\nWNDPROC = WINFUNCTYPE(LRESULT,w.HWND,w.UINT,w.WPARAM,w.LPARAM)\n\ndef MAKEINTRESOURCEW(x):\n    return w.LPCWSTR(x)\n\nclass WNDCLASSW(Structure):\n    _fields_ = [(\'style\', w.UINT),\n                (\'lpfnWndProc\', WNDPROC),\n                (\'cbClsExtra\', c_int),\n                (\'cbWndExtra\', c_int),\n                (\'hInstance\', w.HINSTANCE),\n                (\'hIcon\', w.HICON),\n                (\'hCursor\', HCURSOR),\n                (\'hbrBackground\', w.HBRUSH),\n                (\'lpszMenuName\', w.LPCWSTR),\n                (\'lpszClassName\', w.LPCWSTR)]\n\nclass PAINTSTRUCT(Structure):\n    _fields_ = [(\'hdc\', w.HDC),\n                (\'fErase\', w.BOOL),\n                (\'rcPaint\', w.RECT),\n                (\'fRestore\', w.BOOL),\n                (\'fIncUpdate\', w.BOOL),\n                (\'rgbReserved\', w.BYTE * 32)]\n\nkernel32 = WinDLL(\'kernel32\',use_last_error=True)\nkernel32.GetModuleHandleW.argtypes = w.LPCWSTR,\nkernel32.GetModuleHandleW.restype = w.HMODULE\nkernel32.GetModuleHandleW.errcheck = errcheck\n\nuser32 = WinDLL(\'user32\',use_last_error=True)\nuser32.CreateWindowExW.argtypes = w.DWORD,w.LPCWSTR,w.LPCWSTR,w.DWORD,c_int,c_int,c_int,c_int,w.HWND,w.HMENU,w.HINSTANCE,w.LPVOID\nuser32.CreateWindowExW.restype = w.HWND\nuser32.CreateWindowExW.errcheck = errcheck\nuser32.LoadIconW.argtypes = w.HINSTANCE,w.LPCWSTR\nuser32.LoadIconW.restype = w.HICON\nuser32.LoadIconW.errcheck = errcheck\nuser32.LoadCursorW.argtypes = w.HINSTANCE,w.LPCWSTR\nuser32.LoadCursorW.restype = HCURSOR\nuser32.LoadCursorW.errcheck = errcheck\nuser32.RegisterClassW.argtypes = POINTER(WNDCLASSW),\nuser32.RegisterClassW.restype = w.ATOM\nuser32.RegisterClassW.errcheck = errcheck\nuser32.ShowWindow.argtypes = w.HWND,c_int\nuser32.ShowWindow.restype = w.BOOL\nuser32.UpdateWindow.argtypes = w.HWND,\nuser32.UpdateWindow.restype = w.BOOL\nuser32.UpdateWindow.errcheck = errcheck\nuser32.GetMessageW.argtypes = POINTER(w.MSG),w.HWND,w.UINT,w.UINT\nuser32.GetMessageW.restype = w.BOOL\nuser32.TranslateMessage.argtypes = POINTER(w.MSG),\nuser32.TranslateMessage.restype = w.BOOL\nuser32.DispatchMessageW.argtypes = POINTER(w.MSG),\nuser32.DispatchMessageW.restype = LRESULT\nuser32.BeginPaint.argtypes = w.HWND,POINTER(PAINTSTRUCT)\nuser32.BeginPaint.restype = w.HDC\nuser32.BeginPaint.errcheck = errcheck\nuser32.GetClientRect.argtypes = w.HWND,POINTER(w.RECT)\nuser32.GetClientRect.restype = w.BOOL\nuser32.GetClientRect.errcheck = errcheck\nuser32.DrawTextW.argtypes = w.HDC,w.LPCWSTR,c_int,POINTER(w.RECT),w.UINT\nuser32.DrawTextW.restype = c_int\nuser32.EndPaint.argtypes = w.HWND,POINTER(PAINTSTRUCT)\nuser32.EndPaint.restype = w.BOOL\nuser32.PostQuitMessage.argtypes = c_int,\nuser32.PostQuitMessage.restype = None\nuser32.DefWindowProcW.argtypes = w.HWND,w.UINT,w.WPARAM,w.LPARAM\nuser32.DefWindowProcW.restype = LRESULT\n\ngdi32 = WinDLL(\'gdi32\',use_last_error=True)\ngdi32.GetStockObject.argtypes = c_int,\ngdi32.GetStockObject.restype = w.HGDIOBJ\n\nCW_USEDEFAULT = -2147483648\nIDI_APPLICATION = MAKEINTRESOURCEW(32512)\nWS_OVERLAPPEDWINDOW = 13565952\n\nCS_HREDRAW = 2\nCS_VREDRAW = 1\n\nIDC_ARROW = MAKEINTRESOURCEW(32512)\nWHITE_BRUSH = 0\n\nSW_SHOWNORMAL = 1\n\nWM_PAINT = 15\nWM_DESTROY = 2\nDT_SINGLELINE = 32\nDT_CENTER = 1\nDT_VCENTER = 4\n\ndef MainWin():\n    # Define Window Class\n    wndclass = WNDCLASSW()\n    wndclass.style          = CS_HREDRAW | CS_VREDRAW\n    wndclass.lpfnWndProc    = WNDPROC(WndProc)\n    wndclass.cbClsExtra = wndclass.cbWndExtra = 0\n    wndclass.hInstance      = kernel32.GetModuleHandleW(None)\n    wndclass.hIcon          = user32.LoadIconW(None, IDI_APPLICATION)\n    wndclass.hCursor        = user32.LoadCursorW(None, IDC_ARROW)\n    wndclass.hbrBackground  = gdi32.GetStockObject(WHITE_BRUSH)\n    wndclass.lpszMenuName   = None\n    wndclass.lpszClassName  = \'MainWin\'\n\n    # Register Window Class\n    user32.RegisterClassW(byref(wndclass))\n\n    # Create Window\n    hwnd = user32.CreateWindowExW(0,\n                          wndclass.lpszClassName,\n                          \'Python Window\',\n                          WS_OVERLAPPEDWINDOW,\n                          CW_USEDEFAULT,\n                          CW_USEDEFAULT,\n                          CW_USEDEFAULT,\n                          CW_USEDEFAULT,\n                          None,\n                          None,\n                          wndclass.hInstance,\n                          None)\n    # Show Window\n    user32.ShowWindow(hwnd,SW_SHOWNORMAL)\n    user32.UpdateWindow(hwnd)\n\n    # Pump Messages\n    msg = w.MSG()\n    while user32.GetMessageW(byref(msg), None, 0, 0) != 0:\n        user32.TranslateMessage(byref(msg))\n        user32.DispatchMessageW(byref(msg))\n\n    return msg.wParam\n\ndef WndProc(hwnd, message, wParam, lParam):\n    ps = PAINTSTRUCT()\n    rect = w.RECT()\n\n    if message == WM_PAINT:\n        hdc = user32.BeginPaint(hwnd,byref(ps))\n        user32.GetClientRect(hwnd,byref(rect))\n        user32.DrawTextW(hdc,\n                         \'Python Powered Windows \xe4\xbd\xa0\xe5\xa5\xbd\xe5\x90\x97\xef\xbc\x9f\',\n                         -1, byref(rect), \n                         DT_SINGLELINE|DT_CENTER|DT_VCENTER)\n        user32.EndPaint(hwnd,byref(ps))\n        return 0\n    elif message == WM_DESTROY:\n        user32.PostQuitMessage(0)\n        return 0\n\n    return user32.DefWindowProcW(hwnd,message,wParam,lParam)\n\nif __name__==\'__main__\':\n    sys.exit(MainWin())\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n