python ctypes Win32方式窗口标题被截断了吗? [英] python ctypes Win32 way window title gets truncted?
问题描述
我一直在尝试通过使用python(2.7)和ctypes模块创建Win32应用程序。创建并显示了窗口,但是窗口的标题被截断了。我得到的是 M而不是我的测试窗口。我在做什么错了?
预先感谢
P.S。下面是代码和屏幕截图:
#-*-编码:utf-8-*-
从sys导入平台,退出
从ctypes导入*
从ctypes.wintypes导入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
b
CS_HREDRAW = 2
CS_VREDRAW = 1
CW_USEDEFAULT = 0x80000000
WM_DESTROY = 2
WHITE_BRUSH = 0
类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):
如果Msg == WM_DESTROY:
windll.user32.PostQuitMessage(0)
else:
return windll.user32.DefWindowProcA(hWnd,Msg,wParam,lParam)
返回0
WndProc = WNDPROCTYPE(PyWndProcedure)
hInst = windll.kernel32.GetModuleHandleW(0)
print(hInst)
wclassName = u'我的Python Win32类'
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我的测试窗口'
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 hWnd:
print('无法创建窗口')
exit(0)
print('ShowWindow',windll.user32。 ShowWindow(hWnd,SW_SHOW))
print('UpdateWindow',windll.user32.UpdateWindow(hWnd))
msg = MSG()
lpmsg =指针(msg)
print('进入消息循环')
而windll.user32.GetMessageA(lpmsg, 0,0,0)!= 0:
windll.user32.TranslateMessage(lpmsg)
windll.user32.DispatchMessageA(lpmsg)
print('done。')
这是因为您正在使用<$创建Unicode窗口c $ c> CreateWindowExW ,然后调用ANSI DefWindowProcA
。您正在传递的Unicode字符串通常每个其他字节为零,因为您的文本在ASCII范围内,这说明了您观察到的内容。呼叫 DefWindowProcW
。
实际上,更好的解决方案是使用 win32gui
可以为您带来更多收益。
I been trying to create Win32 Application by using python (2.7) and ctypes module. Window is created and shown but title of window gets truncated. I got 'M' instead of 'My test window'. What I am doing wrong?
Thanks in advance
P.S. Here follows the code and screenshot:
# -*- 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.')
It is because you are creating a Unicode window with CreateWindowExW
but then calling the ANSI DefWindowProcA
. You are passing Unicode strings which typically have zero for every other byte since your text is in the ASCII range which explains what you observe.
The solution? Call DefWindowProcW
instead.
Actually, a better solution would be to use win32gui
instead which wraps this up a bit more for you.
这篇关于python ctypes Win32方式窗口标题被截断了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!