python ctypes Win32方式窗口标题被截断?

时间:2011-03-22 08:34:51

标签: python winapi ctypes

我一直在尝试使用python(2.7)和ctypes模块创建Win32应用程序。创建并显示窗口但窗口标题被截断。我得到'M'而不是'我的测试窗口'。我做错了什么?

提前致谢

P.S。以下是代码和屏幕截图:

enter image description here

# -*- coding: utf-8 -*-
from sys import platform, exit
from ctypes import *
from ctypes.wintypes import DWORD, HWND, HANDLE, LPCWSTR, WPARAM, LPARAM, RECT, POINT, MSG

WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)

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_DESTROY = 2

WHITE_BRUSH = 0

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", HANDLE),
                ("lpszMenuName", LPCWSTR),
                ("lpszClassName", LPCWSTR),
                ("hIconSm", HANDLE)]

def PyWndProcedure(hWnd, Msg, wParam, lParam):
    if Msg == WM_DESTROY:
        windll.user32.PostQuitMessage(0)
    else:
        return windll.user32.DefWindowProcA(hWnd, Msg, wParam, lParam)
    return 0

WndProc = WNDPROCTYPE(PyWndProcedure)

hInst = windll.kernel32.GetModuleHandleW(0)
print(hInst)

wclassName = u'My Python Win32 Class'

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 = windll.gdi32.GetStockObject(WHITE_BRUSH)
wndClass.lpszMenuName = 0
wndClass.lpszClassName = wclassName
wndClass.hIconSm = 0
print(wndClass)

regRes = windll.user32.RegisterClassExW(byref(wndClass))
print(regRes)

wname = u'My test window'

hWnd = windll.user32.CreateWindowExW(
    0,
    wclassName,
    wname,
    WS_OVERLAPPEDWINDOW | WS_CAPTION,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    300,
    300,
    0,
    0,
    hInst,
    0)
print('hWnd', hWnd)
if not hWnd:
    print('Failed to create window')
    exit(0)

print('ShowWindow', windll.user32.ShowWindow(hWnd, SW_SHOW))
print('UpdateWindow', windll.user32.UpdateWindow(hWnd))

msg = MSG()
lpmsg = pointer(msg)

print('Entering message loop')
while windll.user32.GetMessageA(lpmsg, 0, 0, 0) != 0:
    windll.user32.TranslateMessage(lpmsg)
    windll.user32.DispatchMessageA(lpmsg)

print('done.')

2 个答案:

答案 0 :(得分:4)

这是因为您正在使用CreateWindowExW创建一个Unicode窗口,然后调用ANSI DefWindowProcA。您传递的Unicode字符串通常对于每隔一个字节都为零,因为您的文本处于ASCII范围内,这解释了您观察到的内容。

解决方案?请改为呼叫DefWindowProcW

实际上,一个更好的解决方案是使用win32gui而不是为你包装更多。

答案 1 :(得分:0)

如果您提供常规字符串而不是unicode字符串,则文本会正确显示。

wname ='我的测试窗口'

我觉得很奇怪,因为你使用的是Unicode API(CreateWindowExW)。也许根本原因就在其他地方。

我希望它有所帮助