python ctypes Win32方式窗口标题被截断了吗? [英] python ctypes Win32 way window title gets truncted?

查看:135
本文介绍了python ctypes Win32方式窗口标题被截断了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试通过使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆