IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Кнопки WinAPI, Реакция на горячие клавиши и таб.
сообщение
Сообщение #1


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Созднаю кнопку со стилем ws_Child or ws_Visible or bs_PushButton or ws_TabStop и заголовком &A
Буква подчёркивается, но реакции на альт+А нету. Если создать две кнопки, то переключатель по таб между ними не работает. Горячие клавиши реализуются системой, или надо самому их отдельно регистрировать?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Цитата
Если создать две кнопки, то переключатель по таб между ними не работает.
WM_TABSTOP работает в диалоговых окнах, то есть, если у родителя существует функция диалогового окна (а это совсем не то же самое, что простая функция окна) и присутствует (у родителя же) стиль WS_EX_CONTROLPARENT...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Так что мне делать для того, чтобы кнопки срабатывали от клавиатуры? RegisterHotKey и всё?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Можно - 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;
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


Но в глубине души эти акселлераторы всё равно являются хоткеями, которые каждый раз все регистрируются/разрегестрировываются в ответ на wm_Activate?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Ничего не регистрируется/разрегистрируется.

Для обработке Хоткея Windows проделывает дополнительную работу, и всем приложениям, установившим этот хоткей в очередь сообщений назначенного RegisterHotKey-ем приложения пишет WM_HOTKEY всегда, независимо от того активно это приложение или нет.

А если приложение, ждущее акселератор, активно - то код нажатой клавиши кроме всего прочего поступает в очередь сообщений этого приложения, и естественно обрабатывается TranslateAccelerator-ом. Если НЕактивно - то код нажатой клавиши в очередь не пишется.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> if TranslateAccelerator(handleWnd, hAccel, Msg) = 0

А тут в качестве handleWnd должно быть активное окно или главное? И тогда для каждого окна проекта нужна своя таблица акселераторов?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата
для каждого окна проекта нужна своя таблица акселераторов?
Да. Техника описана у MS: How To Manage Per-Window Accelerator Tables

( для случая MDI-интерфейса существует также Функция TranslateMDISysAccel )
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


На пункты меню действует, на bs_PushButton - тоже, а вот на bs_AutoRadioButton - нет. Что делать?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






В функции окна прописано, что при получении соответствующего сообщения надо включить AutoRadioButton?

TranslateAccelerator не занимается обработкой сообщений, он только переводит код нажатой клавиши в сообщение WM_COMMAND. Там его и надо обрабатывать...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> В функции окна прописано, что при получении соответствующего сообщения надо включить AutoRadioButton?

Не написано. Написал, заработало. Вот только как сделать, чтобы остальные элементы радиогруппы выключились? Я это сделал через ж
SendMessage(H, wm_LButtonDown, 0, 0);
SendMessage(H, wm_LButtonUp, 0, 0);
А как сделать нормально?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


А, всё, сообщение bm_Click можно послать. Оно вроде не приводит к рекурсивной обработке wm_Comand?


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Если создавать радио-кнопки так:
  (*
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

, то не надо никакой эмуляции нажатия на кнопку мыши. Радио-кнопки они на то и радио, что в одной группе может быть одновременно выбрана только одна такая кнопка...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Злостный любитель
*****

Группа: Пользователи
Сообщений: 1 755
Пол: Мужской

Репутация: -  62  +


> Если создавать радио-кнопки так:

Ну я так и делал.

> // Смотрим только одну группу. Если есть еще одна - отдельно

Каждую группу отдельно?
Мышкой сэмулировать проще... К тому же позволяет, ничего не меняя, вешать хоткеи на что угодно, например, на поля ввода.


--------------------
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






Цитата
Мышкой сэмулировать проще...
Проще - не всегда правильнее... Дело твое, хочешь потом ловить баги из-за того, что не играл по правилам ОС - лови. Я предпочитаю писать программы по-другому.

Цитата
К тому же позволяет, ничего не меняя, вешать хоткеи на что угодно, например, на поля ввода.
Угу, вон оно, уже позволило тебе словить отсутствие работоспособности. Продолжай в том же духе. Ничего не меняя, главное...

P.S.
Цитата
Я это сделал через ж
, но
Цитата
Мышкой сэмулировать проще...
А потом удивляются, что 90% кода в интернете - говно
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 19.04.2024 5:40
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name