Отправляет email-рассылки с помощью сервиса Sendsay

[prg] win32 приложение. обработка нажатия клавиш

Здравствуйте, уважаемые.

В Win32-приложении пользователь нажимает клавишу Пробел и мне нужно, чтобы
это нажатие обработалось не по умолчанию, а как выполнение некоторых
действий. Сообщение WM_KEYDOWN обрабатывает оконная процедура таким образом:

INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam) {
switch(uMsg) {
case WM_INITDIALOG: {
return 0;
}
case WM_KEYDOWN: {
switch (wParam) {
case VK_SPACE:
out << "нажали клавишу Пробел" << endl;
out.close();
break;
default:
break;
}
return 0;
}
...

Вопрос первый: почему это сообщение вообще не обрабатывается и что для этого
нужно?

Вопрос второй: если мне понадобится обработать не нажатие одной клавиши
<Space>, а сочетания клавиш <CTRL+SPACE>, то перед обработкой нажатия
клавиши пробел, я должен убедиться, что была еще нажата клавиша <CTRL>
функцией GetAsyncKeyState?

p.s. Если можно побольше конкретики.

Ответить   Tue, 24 Dec 2013 13:32:56 +0400 (#2901863)

 

Ответы:

Приветствую всех.

Вопрос так ставить нельзя. Но по сути ваши проблемы в том, что вы используете
диалоговое окно, а ожидаете, что оно будет вести себя как обычное.

Не совсем понятно, для "этого" -- для чего? Для того чтобы обрабатывать или для
того чтобы не обрабатывать?

Как вариант: обрабатывать нажатие на уровне элемента управления, то есть переопределить
оконную процедуру конкретного элемента управления (например, списка), в котором
вы хотите перехватывать нажатие пробела (такое переопределение называется "сабклассинг").

Успехов. Анатолий.

Ответить   "i_chay" Tue, 24 Dec 2013 15:59:42 +0300 (#2901972)

 

цитата:
вы используете диалоговое окно, а ожидаете, что оно будет вести себя как
обычное.

ответ:
создал пустой win32-проект. Когда вызываю панель элементов открывается не
список прежних элементов, которые можно было добавить в диалоговое окно, а
что-то типа "inputbutton, inputreset, image, select..." и так дальше по
табуляции.
То есть, добавление элементов в диалоговое окно происходит несколько по
другому нежели в главное окно приложения? А может вообще так добавить
элементы управления нельзя?

Если резюмировать два вопроса, то как нужно построить проект, чтобы в
главном окне win32 приложения были те же элементы управления что и в
диалоговом окне (ListBox, Button, Edittext, checkbox), но с возможностью
обработки нажатия клавиш в той же оконной процедуре, где обрабатываются все
сообщения. Разумеется, возможность добавления дополнительных модальных
диалоговых окон не исключается.

p.s. Готов, если необходимо, переделать весь проект под обычное
win32-приложение с регистрацией класса окна, затем созданием, выводом его на
дисплей и перисовкой. Главное, понять, последовательность своих действий.

Грызунов Александр

Ответить   Wed, 25 Dec 2013 13:44:29 +0400 (#2902804)

 

Приветствую всех.

Конкретное решение было указано прямым текстом: используйте сабклассинг.
Вы должны отчётливо себе представлять, в каком из окон происходит обработка сообщения.
Каждый элемент управления -- это окно. У _каждого_ окна есть своя оконная процедура.
Сообщение WM_KEYDOWN поступает в окно, которое непосредственно содержит фокус.
Это все написано в документации (и даже по-русски)!
А теперь напишите своими словами, что происходит, когда в вашем приложении фокус
находится, например, на кнопке и вы нажимаете клавишу пробел?
Какое окно получит сообщение WM_KEYDOWN???
Если есть трудности с пониманием работы оконного интерфейса Windows, то в вашем
распоряжении, во-первых, утилита spyxx.exe (должна присутствовать, по крайней
мере, в профессиональном выпуске VisualStudio), которая позволяет перехватывать
любые сообщения любых окон; во-вторых, если работа с spyxx.exe тоже вызывает
затруднение, то у вас есть швейцарский нож под названием "скрипты JAWS", при
помощи которых можно послать любое сообщение любому окну. В качестве эксперимента
напишите скрипт, который отправит WM_KEYDOWN (0x100) вашему диалоговому окну
напрямую и ваш код обработки WM_KEYDOWN сработает.

Надо ещё понимать концептуальные вещи: диалоговые окна и элементы управления
придуманы, кроме всего прочего, и для того, чтобы разработчик приложения не занимался
непосредственной обработкой клавиатурного ввода. Необходимость обработки нажатий
отдельных клавиш в диалоговом окне или обычном окне с элементами управления означает,
что вы неправильно спроектировали интерфейс пользователя. Либо ваше приложение
настолько оригинальное, что имеющиеся элементы управления ему не подходят, тогда
вы берёте "чистое" окно и полностью реализуете обработку клавиатурного ввода
(не используя никакие элементы управления). Так делают, например, в играх.
Либо вы используете стандартные элементы управления, меню, ускорители и т.п.,
тогда при правильном их использовании у вас не возникает необходимости опускаться
до обработки клавиатурного ввода (все делает система и элементы управления).

Исключением из последнего варианта является случай, когда стандартный элемент
управления вас (как разработчика приложения) почти устраивает, но некоторые изменения
в его поведение вам хотелось бы внести. Именно для этого и предназначен сабклассинг.

Успехов. Анатолий.

Ответить   "i_chay" Thu, 26 Dec 2013 00:23:50 +0300 (#2903338)

 

Приветствую всех.

Когда я говорил об отличиях в поведении обычного и диалогового окна, то подразумевал,
что вы изучите соответствующую документацию, чтобы разобраться в этих отличиях,
а не броситесь бездумно заменять одно на другое.
Например, обратите внимание на возвращаемое значение:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms645469%28v=vs.85%29.aspx

Typically, the dialog box procedure should return TRUE if it processed the message,
and FALSE if it did not. If the dialog box procedure returns FALSE,
the dialog manager performs the default dialog operation in response to the message.

Для обычного окна смысл возвращаемого значения зависит от обрабатываемого сообщения
(то есть это то значение, которое указано в документации к конкретному сообщению):
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573%28v=vs.85%29.aspx

The return value is the result of the message processing and depends on the message
sent.

Успехов. Анатолий.

Ответить   "i_chay" Thu, 26 Dec 2013 01:21:00 +0300 (#2903380)