Задать вопрос
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?
  • Вопрос задан
  • 2173 просмотра
Подписаться 1 Средний Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Python-разработчик: расширенный курс + нейросети
    12 месяцев
    Далее
  • Академия Эдюсон
    Python-разработчик
    9 месяцев
    Далее
  • ProductStar × РБК
    Профессия: Python-разработчик + ИИ
    8 месяцев
    Далее
Решения вопроса 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 - это ссылка на процедуру обработки сообщений окна. Очевидно, её нужно объявить.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
ITK academy Краснодар
от 220 000 до 300 000 ₽
ITK academy Краснодар
от 75 000 ₽
DimaTech Ltd Краснодар
от 140 000 до 140 000 ₽