2011-03-22 29 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)看起來很奇怪,我。也許根源在別的地方。

我希望它能幫助