2011-03-22 67 views
2

我一直试图通过使用python(2.7)和ctypes模块来创建Win32应用程序。窗口被创建并显示,但窗口标题被截断。我得到'M'而不是'我的测试窗口'。我做错了什么?蟒蛇ctypes Win32的方式窗口标题得到truncted?

在此先感谢

P.S.如果你提供了一个常规的字符串,而不是unicode字符串,正确显示文本

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.') 
+0

也许这个使用win32gui.CreateWindow的工作示例可以给你一个提示:http://stackoverflow.com/questions/5353883/python3-ctype-createwindowex-simple-example/5355663#5355663 – alexandrul 2011-03-22 09:33:07

回答

4

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

解决方案?改为拨打DefWindowProcW

实际上,更好的解决方案是使用win32gui,而不是将它包装多一点给你。

+0

我的愚蠢的错误。谢谢你的帮助! – 2011-03-22 10:31:27

0

:在这里,下面的代码和屏幕截图。

wname = '我的测试窗口'

它,因为你使用Unicode API(CreateWindowExW)看起来很奇怪,我。也许根源在别的地方。

我希望它能帮助