Reputation: 10701
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.')
Upvotes: 2
Views: 2230
Reputation: 613592
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.
Upvotes: 5
Reputation: 43166
If you provide a regular string rather than an unicode string, the text is displayed properly.
wname = 'My test window'
It looks strange to me because you are using the Unicode API (CreateWindowExW). Maybe the root cause is somewhere else.
I hope it helps
Upvotes: 0