lxst
@lxst
Студент программист

Win32api | python | Как создать окно приложения, где взять wndProc?

Во всех документациях:
#get instance handle
    hInstance = win32api.GetModuleHandle()
 
    # the class name
    className = 'SimpleWin32'
 
 
    # create and initialize window class
    wndClass                = win32gui.WNDCLASS()
    wndClass.style          = win32con.CS_HREDRAW | win32con.CS_VREDRAW
    wndClass.lpfnWndProc    = wndProc # А вот тут показывает что неизвестный объект
    wndClass.hInstance      = hInstance
    wndClass.hIcon          = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
    wndClass.hCursor        = win32gui.LoadCursor(0, win32con.IDC_ARROW)
    wndClass.hbrBackground  = win32gui.GetStockObject(win32con.WHITE_BRUSH)
    wndClass.lpszClassName  = className

Где взять wndProc?
  • Вопрос задан
  • 1739 просмотров
Решения вопроса 2
Vindicar
@Vindicar
RTFM!
Тебе повезло, я недавно такое делал.
Нельзя просто взять и передать питоновскую функцию в WinAPI, так как у них совершенно разные способы вызова. Тебе сначалу нужно описать тип данных - указатель на функцию. Примерно так.
import ctypes
import ctypes.wintypes as w
LRESULT = w.LPARAM
WNDPROC = ctypes.WINFUNCTYPE(LRESULT, w.HWND, w.UINT, w.WPARAM, w.LPARAM)

Вот после этого ты можешь предоставить свою оконную функцию вида
def wnd_proc(hwnd: w.HWND, message: w.UINT, wParam: w.WPARAM, lParam: w.LPARAM) -> LRESULT:


А потом уже указываешь это в классе окна:
wndСlass.lpfnWndProc = WNDPROC(wnd_proc)

Но тут есть еще один подвох - оконных сообщений много, и их набор отличается для разных версий винды. Есть базовый, более-менее статичный набор, но помимо них может прийти много чего.
Тут на помощь приходит DefWindowProc().
def wnd_proc(hwnd, message, wParam, lParam):
    if message == SOME_MESSAGE_YOU_WANT:  # отлавливаешь интересующие тебя сообщения
        DoStuff()  # и обрабатываешь их
        return 0  # не забудь вернуть 0 как признак успеха!
    # а все остальное отдаёшь в DefWindowProc()
    return user32.DefWindowProcW(hwnd, message, wParam, lParam)

Обрати внимание, что как многие функции WinAPI, DefWindowProc() существует в двух видах - с сууфиксом A (однобайтовая кодировка ANSI) и с суффиком W (wide char, двухбайтовый вариант юникода). Смешивать не рекомендую, выбери один суффикс и придерживайся его во всей программе.

И ещё подвох, который меня чуть с ума не свёл - переменная с классом окна ДОЛЖНА существовать, пока существует окно. Иными словами, её не стоит делать локальной в методе - иначе сборщик мусора питона её потом соберёт, что будет неприятным сюрпризом для WinAPI. Поймаешь крэш приложения.
Ответ написан
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
wndProc - это ссылка на процедуру обработки сообщений окна. Очевидно, её нужно объявить.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы