Созднаю кнопку со стилем ws_Child or ws_Visible or bs_PushButton or ws_TabStop и заголовком &A Буква подчёркивается, но реакции на альт+А нету. Если создать две кнопки, то переключатель по таб между ними не работает. Горячие клавиши реализуются системой, или надо самому их отдельно регистрировать?
Если создать две кнопки, то переключатель по таб между ними не работает.
WM_TABSTOP работает в диалоговых окнах, то есть, если у родителя существует функция диалогового окна (а это совсем не то же самое, что простая функция окна) и присутствует (у родителя же) стиль WS_EX_CONTROLPARENT...
Можно - RegisterHotKey (это добавит данную комбинацию для всей системы). Если этого не хочется, а хочется - только когда свое приложение активно - можно создать файл ресурсов (*.RC), в нем описать ресурс типа ACCELERATORS, в котором перечислить все нужные горячие клавиши и связанные с ними сообщения, а в программе чуть-чуть изменить основной цикл обработки сообщений:
var hAccel: THandle; // ... hAccel := LoadAccelerators(hInstance, 'Accels'); // Accels - название таблицы акселераторов в RC-файле while GetMessage (Msg, 0, 0, 0) do if TranslateAccelerator(handleWnd, hAccel, Msg) = 0 then // Вот для чего все это делается begin TranslateMessage (Msg); DispatchMessage (Msg); end;
Для обработке Хоткея Windows проделывает дополнительную работу, и всем приложениям, установившим этот хоткей в очередь сообщений назначенного RegisterHotKey-ем приложения пишет WM_HOTKEY всегда, независимо от того активно это приложение или нет.
А если приложение, ждущее акселератор, активно - то код нажатой клавиши кроме всего прочего поступает в очередь сообщений этого приложения, и естественно обрабатывается TranslateAccelerator-ом. Если НЕактивно - то код нажатой клавиши в очередь не пишется.
В функции окна прописано, что при получении соответствующего сообщения надо включить AutoRadioButton?
TranslateAccelerator не занимается обработкой сообщений, он только переводит код нажатой клавиши в сообщение WM_COMMAND. Там его и надо обрабатывать...
> В функции окна прописано, что при получении соответствующего сообщения надо включить AutoRadioButton?
Не написано. Написал, заработало. Вот только как сделать, чтобы остальные элементы радиогруппы выключились? Я это сделал через ж SendMessage(H, wm_LButtonDown, 0, 0); SendMessage(H, wm_LButtonUp, 0, 0); А как сделать нормально?
(* WS_GROUP - значит, началась новая группа радио-кнопок. Все последующие AUTORADIOBUTTON-ы будут добавляться именно в эту группу. Нужна еще одна - при создании первой кнопки, которая будет в новой группе, надо опять указать WS_GROUP *) hRBtn_1 := CreateWindowEx(0, 'BUTTON', 'Опция &0', WS_GROUP or BS_AUTORADIOBUTTON or WS_VISIBLE or WS_CHILD, 15, 132, 95, 25, handleWnd, RBTN_0, hInstance, nil); hRBtn_2 := CreateWindowEx(0, 'BUTTON', 'Опция &1', BS_AUTORADIOBUTTON or WS_VISIBLE or WS_CHILD, 15, 154, 155, 25, handleWnd, RBTN_1, hInstance, nil); hRBtn_3 := CreateWindowEx(0, 'BUTTON', 'Опция &2', BS_AUTORADIOBUTTON or WS_VISIBLE or WS_CHILD, 15, 176, 155, 25, handleWnd, RBTN_2, hInstance, nil); CheckRadioButton(handleWnd, RBTN_0, RBTN_2, RBTN_0); // включаем любую кнопку в группе
, а WM_COMMAND обрабатывать так:
case AMessage of WM_COMMAND: begin case LoWord(WParam) of RBTN_0 .. RBTN_2: // Смотрим только одну группу. Если есть еще одна - отдельно begin // В группе включить нужную. Естественно, остальные выключатся CheckRadioButton(Window, RBTN_0, RBTN_2, LoWord(WParam)); end; end
, то не надо никакой эмуляции нажатия на кнопку мыши. Радио-кнопки они на то и радио, что в одной группе может быть одновременно выбрана только одна такая кнопка...
Проще - не всегда правильнее... Дело твое, хочешь потом ловить баги из-за того, что не играл по правилам ОС - лови. Я предпочитаю писать программы по-другому.
Цитата
К тому же позволяет, ничего не меняя, вешать хоткеи на что угодно, например, на поля ввода.
Угу, вон оно, уже позволило тебе словить отсутствие работоспособности. Продолжай в том же духе. Ничего не меняя, главное...