Как включить вкладки и клавиши со стрелками с помощью python win32gui

Я создал несколько кнопок (окон) в главном окне, но клавиши вкладок и стрелок не работают. Мои исследования показали, что для С++ использование IsDialogMessage в насосе сообщений создает обход TranslateMessage/DispatchMessage следующим образом, чтобы разрешить эту функцию:

while(GetMessage(&Msg, NULL, 0, 0))
{
    if(!IsDialogMessage(g_hToolbar, &Msg))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
}

Однако я использую python и модуль win32gui для CreateWindows, и я не могу понять, как обойти обычный захват сообщений, чтобы обеспечить естественную обработку клавиатуры. Мой код похож на этот:

from win32gui import *
from win32con import *

window_class = WNDCLASS()
hinst = window_class.hInstance = GetModuleHandle(None)
window_class.lpszClassName = 'ClassName'
window_class.style = CS_VREDRAW | CS_HREDRAW
window_class.hCursor = LoadCursor(0, IDC_ARROW)
window_class.hbrBackground = COLOR_WINDOW
window_class.lpfnWndProc = {}
classAtom = RegisterClass(window_class)

hwnd = CreateWindow(classAtom, "", WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION
                    | WS_SYSMENU | WS_MINIMIZEBOX | WS_EX_TOPMOST | WS_CLIPSIBLINGS,
                    0, 0, 140, 100, 0,  0, GetModuleHandle(None), None)
btn1_hwnd = CreateWindow("Button", "btn 1", WS_GROUP | WS_TABSTOP | WS_VISIBLE
                         | WS_CHILD | BS_DEFPUSHBUTTON | WS_CLIPSIBLINGS,
                         10, 10, 100, 20, hwnd, 0, GetModuleHandle(None), None)
btn2_hwnd = CreateWindow("Button", "btn 2", WS_GROUP | WS_TABSTOP | WS_VISIBLE
                         | WS_CHILD | BS_DEFPUSHBUTTON | WS_CLIPSIBLINGS,
                         10, 40, 100, 20, hwnd, 0, GetModuleHandle(None), None)

UpdateWindow(hwnd)
PumpMessages()

EDIT: С помощью этого кода создается окно с двумя кнопками, но невозможно перенести фокус с одного на другой, хотя оба они имеют флаг WS_TABSTOP.

В соответствии с спецификацией MSDN IsDialogMessage, приведенный выше фрагмент С++ является решением.

Когда IsDialogMessage обрабатывает сообщение, он проверяет сообщения клавиатуры и преобразует их в выборки для соответствующего диалогового окна. Например, клавиша TAB при нажатии выбирает следующий элемент управления или группу элементов управления, а клавиша DOWN ARROW при нажатии выбирает следующий элемент управления в группе.

Поскольку функция IsDialogMessage выполняет все необходимые переводы и отправку сообщений, сообщение, обработанное IsDialogMessage, не должно передаваться функции TranslateMessage или DispatchMessage.

Итак, в основном, вопрос в том, может ли IsDialogMessage использоваться из Python win2gui, или есть ли какое-то обходное решение?

Ответ 1

Я нашел пример CreateDialogIndirect использования programcreek.com, который создает окно, похожее на одно из вопроса, с вкладками. Здесь он слегка изменен:

import win32con
import win32gui
import win32api

parent_hwnd = None
msgs = {}
style=win32con.WS_BORDER|win32con.WS_VISIBLE|win32con.WS_CAPTION|win32con.WS_SYSMENU  ## |win32con.DS_SYSMODAL
h=win32gui.CreateDialogIndirect(
    win32api.GetModuleHandle(None),
    [['One ugly dialog box !',(100,100,200,100),style,0],
     ['Button','Create', win32con.IDOK, (10,10,30,20),win32con.WS_VISIBLE|win32con.WS_TABSTOP|win32con.BS_HOLLOW|win32con.BS_DEFPUSHBUTTON],
     ['Button','Never mind', win32con.IDCANCEL, (45,10,50,20),win32con.WS_VISIBLE|win32con.WS_TABSTOP|win32con.BS_HOLLOW],
     ['Static','Desktop name:',71,(10,40,70,10),win32con.WS_VISIBLE],
     ['Edit','',72,(75,40,90,10),win32con.WS_VISIBLE]],
    parent_hwnd, msgs)

win32gui.EnableWindow(h,True)
hcontrol = win32gui.GetDlgItem(h,72)
win32gui.EnableWindow(hcontrol,True)
win32gui.SetFocus(hcontrol)
win32gui.PumpMessages()

Ответ 2

Есть два ответа, короткие и длинные.

Короткий ответ, просто установите клавиатуру v0.6.5.

Длинный ответ: наберите короткий код клавиатуры, затем установите его.