![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Letchik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 5.1.2010 Где: UGTB Репутация: нет Всего: нет |
Даже не знаю с чего начать...
![]() Ну для начала всем привет! Перебрал кучу вариантов, как можно легче реализовать поддержку горячих клавиш. Все методы работают, но у каждого есть один такой минус, который портит ВСЁ! Вот основные: 1) Акселераторы. Плюс: легко и удобно. Минус: Откликается во всех окнах приложения. Можно конечно это блокировать, но это будет "через попу". 2)RegisterHoKey() Плюс: кажется, что леко и удобно. Минус: Тот же что и у первого метода. В добавок, если работаю в другой программе, (например в скайпе сообщение хочу отправить кнопочкой Enter), кнопочка не работает. 3)Локальный хук для каждого диалогового окна программы. Плюс: Почти полный контроль над вводом с клавиатуры. Минус: Сложно, не удобно, есть мелкие глюки, нейтрализовать которые очень проблематично. Вопрос: как правильно реализовать поддержку горячих клавиш. Надо учитывать то, то одна и таже клавиша может использоватья и в главном окне, и в дочерном (например Enter или Insert), только выполнять она будет разные операции. Помогите кто может! ![]() |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Нужно сначала определиться для чего тебе горячие клавиши и что они должны делать. -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
Letchik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 5.1.2010 Где: UGTB Репутация: нет Всего: нет |
Горячие клавиши не мне, а пользователю
![]() Приведу пример: Клавиша Insert в главном окне должна открывать диалоговое окно добавления новой записи. В этом диалоговом окне есть два варианта дальнейших действий. Можно нажать ОК (или Enter). Тогда запись добавитья и окно закроется. Можно нажать "Next" (или Insert), тогда запись добавитья, но окно не закроется, а освободится для ввода следующей записи. |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
а что мешает перед вызовом диалога освободить хоткей Insert,
после чего, в самом диалоге повторно его использовать, уже для другого действия, а по закрытии диалога - снова назначить хоткей insert для работы в главном окне Это сообщение отредактировал(а) GremlinProg - 21.6.2010, 11:54 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
тогда все проще, отлавливай WM_KEYDOWN и определяй код нажатой клавиши, в зависимости от открытого окна делай различные действия на тот же Insert.
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Действительно, зачем тебе горячие клавиши. Смысл их как раз в полной прозрачности - где бы ни нажал, выполняется некоторое действие. А локальная обработка - через ловлю WM_KEYDOWN, в каждом окне по своему.
-------------------- ... |
|||
|
||||
Letchik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 5.1.2010 Где: UGTB Репутация: нет Всего: нет |
Именно это я и хотел сделать изначально.
Однако Enter скорее всего будет нажат тогда, когда курсор будет в каком-то эдитбоксе. А в таком случае WM_KEYDOWN не посылается окну родителю. |
|||
|
||||
Peter |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 771 Регистрация: 28.7.2003 Где: Ставрополь Репутация: 1 Всего: 1 |
Когда-то такую проблему для себя решал так: в главном цикле сообщений проверял
-------------------- всё, что делаете, делайте от души, как для Господа (Послание апостола Павла колоссянам, 3:23). |
|||
|
||||
TGrey |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: 1 Всего: 1 |
А если самому послать это сообщение окну родителю? Это сообщение отредактировал(а) TGrey - 21.6.2010, 15:39 |
|||
|
||||
Letchik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 5.1.2010 Где: UGTB Репутация: нет Всего: нет |
С удовольствием, только когда? |
|||
|
||||
TGrey |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: 1 Всего: 1 |
Когда? Когда оно приходит возможно? Возможно заменить оконную процедуру Едита, ну или чего там, в ней проверять, что приходит, заодно выполнять нужные действия и в любом случае вызывать оригинальную процедуру. Только наверно в таком случае чем больше элементов, и то каждый надо обрабатывать, тогда им всем ставить одну процедуру(свою), а потом вызывать ихние.
Или может хук всунуть в приложение, пусть ловит все сообщения, а там уже фильтровать, что куда. А прочитал, что хук не устраивает. Просто не вижу в чем его проблема? 1 хук, 1 фильтрующая функция, в которой проверять нужные сообщения, по сути забивать на эту функцию и выполнять нужные себе действия. Это сообщение отредактировал(а) TGrey - 21.6.2010, 16:55 |
|||
|
||||
Letchik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 5.1.2010 Где: UGTB Репутация: нет Всего: нет |
Это называется сабклассингом (Subclassing). Это я тоже пробовал. Но никому не советую использовать его в данных целях. Слишком много обработчиков получается. Дело в том, что обработчик Едита не подходит любому другому типу элементу управления (и наоборот). Для каждого типа прийдётся создавать свой обработчик. И это, извините, тоже через попу. Я склоняюсь к локальному хуку. Это сложно и кажется что неудобно, но я получаю почти полный контроль над вводом. GremlinProg посоветовал освобождать хоткей при открытии диалога. Так не пойдёт. Пользователь должен иметь возможность работать в главном окне несмотря на открытое диалоговое окно. Что касается локального хука. Есть пара идей, которые я реализую в ближайшее время. Как реализую - поделюсь опытом. По любому, каждое диалоговое окно будет иметь свой хук. Однако хук действует на все открытые окна приложения. Поэтому вначале обработчика мы будем проверять, активно ли нужное нам окно. Если активно - обрабатываем нажатие клавиши, если нет - то это нам не надо. |
|||
|
||||
TGrey |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 1.12.2007 Репутация: 1 Всего: 1 |
А какая разница в оконных процедурах Едита или чего либо? Структура то одинаковая. Я же не говорю все сообщения отлавливать. К примеру нужны же только клавиши, то есть только 1 сообщение, и в нем же и вообще в любом случае вызывать стандартный. По типу:
То есть выполнятся нужные вам действия, а потом все пойдет дальше, как ни в чем не бывало, конечно если там тоже, что-то будет на эту кнопку обрабатываться, то получится не красиво=) Ну а тогда если Диалог не модальный, тогда да... Горяие клавиши как-то ни к селу ни к городу=) Тогда точно, что надо проверять на активность окна. Хотя это тоже не ахти=) |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Вообще-то можно вместо хука вставить в главный цикл сообщений функцию-фильтр, что-то типа TranslateAccelerators, только свою. Можно разработать структуру данных, которая будет связывать хотя бы таблицу акселераторов с окном и использовать TranslateAccelerators. Или просто для каждого окна вызывать свой вариант фильтра. В общем, масса вариантов. А хук - это микроскопом гвозди. Я бы сказала, что в своем процессе хук нужно применять тогда, когда нужно добавить какую-то совершенно не связанную с функциональностью окна обработку. Или когда нужно ловить что-то в других, не подчиненных окнах.
В данном же случае, хук тебе потребуется не один - обработка-то разная. А если сделать просто каркас на основе таблиц соответствий - то функция-фильтр в основном цикле справиться ничуть не хуже. -------------------- ... |
|||
|
||||
Letchik |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 5.1.2010 Где: UGTB Репутация: нет Всего: нет |
Всё-таки я решил попробовать усовершенствовать мой локальный хук. Представьте, получилось. Ниодин метод реализации горячих клавиш не даёт такой гибкости как хук.
Казалось бы, это сложно, неудобно (только с первого взгляда), но всё совсем наоборот. Надо лишь проверять какое окно активно в данный момент. Если активно, то соответственно ввод произвёден именно в это окно. Решилось пару проблем касающихся TАВ"а. Например едит бокс со стилем ES_MULTILINE (что-то в этом роде) не отвечает на нажатие Таба. Поэтому я написал собственную обработку этой клавиши (Shift + TAB, TAB). Работает прекрасно. В топике была идея использовать сабклассинг. Напоминаю, для данной цели он не подходит. Представьте, в диалоговом окне есть контролы трёх разных типов. Это значит, что для каждого типа контрола нужен свой обработчик. Три (!) обработчика, когда можно обойтись только одним. Сабклассинг полезен тогда, когда этот контрол выполняет что-то конкретное, что-то такое, что другие контролы не должны выполнять. А локальный хук полезен когда все контролы (или их большинство) отвечают одним и тем-же действием на некоторое сообщение. Короче. Я выбираю Хук!!! ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |