![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Почему-то в ListView не перехватывается нажатие Enter. Я смотрел нотификационное сообшение LVN_KEYDOWN, использовал subclassing и перехватывал посылаемые ListView сообщения WM_SYSKEYDOWN, WM_KEYDOWN, WM_CHAR, но нажатие Enter нигде обнаружено не было. Интересно, что нажатие Enter в Edit'е успешно перехватывается в WM_KEYDOWN. Может, кто подскажет, что с этим делать?
|
|||
|
||||
| Pulse69 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 28.4.2006 Где: Хабаровск Репутация: 8 Всего: 10 |
Наш любимый МСДН:
NM_RETURN (list view) Notification -------------------------------------------------------------------------------- Notifies a list-view control's parent window that the control has the input focus and that the user has pressed the ENTER key. NM_RETURN is sent in the form of a WM_NOTIFY message. --------------------
Ctrl+Alt+Reset |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Это очень странно, но NM_RETURN тоже не перехватывается...
Добавлено @ 12:20 Вот моя тестовая программка
|
|||
|
||||
| Pulse69 |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 138 Регистрация: 28.4.2006 Где: Хабаровск Репутация: 8 Всего: 10 |
У тебя List-View в диалоге, вся проблема именно в этом. Я с таким как-то сталкивался. В MSDN Magazine есть статья примерно на такую тему. Если у тебя VS2005, посмотри эту ссылку:
ms-help://MS.MSDNQTR.v80.en/MS.MSDN.v80/dnmag00/html/c0700.htm Суть в том, что мне пришлось создавать таблицу акселераторов с VK_RETURN, а затем обрабатывать сообщение от акселератора. По-другому я не знаю как. PS: Xотя нет, знаю. Не пиши для диалога =) --------------------
Ctrl+Alt+Reset |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Спасибо большое!
|
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Кстати, в MFC, оказывается, перехватить нажатие Enter еще сложнее, потому что диалоговое окно при его нажатии закрывается
Даже, если нет кнопки по кмолчанию... |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
В MFC как раз проще - там есть волшебная функция PreTranslateMessage.
-------------------- ... |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Буду знать
|
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Есть решение проблемы! Оказывается, существует сообщение WM_GETDLGCODE. Оно посылается функции окна элемента управления. Возвращенное из функции окна значение говорит, какие клавиши ты хочешь обрабатывать сам. Windows при нажатии этих клавиш не будет сам ничего делать (кроме как ставить очередное сообщение в очередь). С моим ListView это проходит!
|
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Обнаружилась странная вещь
Функции диалогового окна, несмотря на то что она не есть "the window procedure associated with a control" (MSDN), WM_GETDLGCODE все равно приходит. Правда, толку от него мало: Enter в диалоговом окне не ловится Это сообщение отредактировал(а) 0x07L - 11.7.2006, 09:41 |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Ты немного не так понял. Существует стандартная обработка некоторых клавиш в диалоге
Но если в оконной функции контрола в ответ на WM_GETDLGCODE возвратить определенные значения, то это стандартное поведение можно изменить. А ENTER попробуй ловить как WM_CHAR с соответствующим ASCII-кодом, а не WM_KEYDOWN. -------------------- ... |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Глупый вопрос: а как сделать так, чтобы в функцию диалога приходил WM_CHAR?
|
|||
|
||||
| DeadSoul |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва Репутация: нет Всего: 11 |
Создать обработчик этого сообщения? -------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Обработчик-то есть:
Это сообщение отредактировал(а) 0x07L - 11.7.2006, 09:43 |
|||
|
||||
| DeadSoul |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 1217 Регистрация: 25.9.2005 Где: Москва Репутация: нет Всего: 11 |
А WM_KEYDOWN тоже не ловится? Spy++ смотрел какие сообщения приходят?
-------------------- Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". Бьем спамеров их же оружием. Пусть весь спам сыпется им [email protected] |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Что за чушь? В Spy есть WM_KEYDOWN, WM_CHAR, WM_KEYUP. Причем нажатие Enter там тоже видно
Добавлено @ 22:49 А, кстати, при нажатии на Enter не приходит WM_CHAR Добавлено @ 22:57 Вот как (засунуть это в обработчик WM_GETDLGCODE):
Это сообщение отредактировал(а) 0x07L - 11.7.2006, 00:12 |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Дописал я тут свою программку
Теперь все работает. Рзве что почему-то не приходит WM_KEYUP Кстати, WM_GETDLGCODE, сообщающий о нажатии Enter, приходит всегда (независимо от того, что возвращено в обработчике). Так что буду юзать WM_GETDLGCODE. PS Прошу извинить меня за предыдущий пост. Так торопился, что забыл, что должна возвращать функция диалогового окна. Это сообщение отредактировал(а) 0x07L - 11.7.2006, 00:31 |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Никогда не думал, что Windows тоже может посылать сообщения с таймаутом. Он как раз и делает так с WM_KEYUP. Из-за моих MessageBox'ов (да и из-за отладчика) таймаут просто уже проходит.
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Не из-за тайм-аутов, а из-за переключения окна: сообщения ввода (клавиатуры и мыши) всегда приходят активному окну. Т.е. WM_KEYDOWN приходит твоему диалогу, а WM_KEYUP - уже MessageBox. Или отладчику. Тоже самое будет с WM_BUTTONDOWN \ UP.
Так все-таки ENTER в WM_KEYDOWN приходит или нет? Или ты получаешь его только через lParam от WM_GETDLGCODE? Я с чистым API давно не работала, так что интересно... Похоже, его функция TranslateMessage во что-то преобразует... -------------------- ... |
|||
|
||||
| 0x07L |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Ответы на предыдущие посты
Enter приходит и с WM_GETDLGCODE, и с WM_KEYDOWN, и с WM_CHAR, но, как я уже говорил, без WM_KEYUP. Насчет переключения окна. Исправил свою программку, добавив перед каждым MessageBox'ом вызов Sleep(500):
Таким образом добиваемся того, что клавиша отжимается до того, как показывается MessageBox. Между тем сообщения WM_KEYUP как не было, так и нет (и в Spy++ его тоже не видно). Новые наблюдения 1) Опытным путем установлено, что если закомментировать Sleep и MessageBox в обработчике WM_KEYDOWN, не приходит не только WM_KEYUP, но и WM_CHAR (в Spy++ последний, однако, виден):
Замечу, что WM_KEYDOWN приходит (ставил точку останова) 2) Если же вдобавок к этому закомментировать WM_GETDLGCODE, то посылается только WM_KEYUP:
Замечу, что WM_GETDLGCODE и WM_KEYDOWN здесь приходят (ставил точку останова). Что неприятно, с включенной точкой останова WM_KEYUP не посылается (таймаут или переключение окна?). В Spy++ видны WM_KEYDOWN, WM_CHAR (что же он до меня-то не доходит?) и, соответственно, WM_KEYUP. 3) Если закомментировать WM_GETDLGCODE, а WM_KEYDOWN оставить, то все проходит, как будто комментариев нет вообще. В смысле, как в изначальном варианте (в том, который приведен в первой вставке в данном посте) Примечание: результаты приводятся для символьной клавиши (если говорить точнее, клавиши I) Выводы из наблюдений и вопросы Не слишком ясная картина, не так ли. Особенно возмутил меня пункт (1). Каким образом комментарии в WM_KEYDOWN влияют на WM_CHAR? Возникает нахальная мысль: может это проделки Visual Studio? Если кто-нибудь поймет, в чем дело, напишите. Мне это хоть и надоело, но интерес еще остался. Искренне надеюсь, что не напортачил очередной раз. А, чуть не забыл. Может кто-нибудь откомпилить мой код, дабы проверить результаты? Это сообщение отредактировал(а) 0x07L - 11.7.2006, 09:58 |
||||||
|
|||||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Компилировать и проверять, честно говоря, в лом, да и некогда, но вот еще пара вопросов:
1) Что будет, если возвращать в WM_KEYDOWN FALSE? 2) Сделать "чистый тест" поступления сообщений, без MessageBox и точек останова, а просто выводить диагностику с помощью OutputDebugString. Нужно добавить, что картина не совсем стандартная, но и цикл обработки сообщений у тебя непонятно какой: стандартного цикла GetMessage - TranslateMessage - DispatchMessage нет, а что там Windows делает внутри DialogBox - хто знает. Самое интересное, конечно, это исчезновение WM_KEYUP... Просто удивительно... -------------------- ... |
|||
|
||||
| 0x07L |
|
||||||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
1) Пробовал возвращать FALSE. Ничего от этого не меняется.
2) Чистый тест поступления сообщений Новая тестовая программка:
Прошу извинить на низкую читабельность кода. В этот раз все просто. Комментируй WM_KEYDOWN или нет, получаем следующее: В окошке Output:
В Spy++:
Что тут сказать? Опять пропал WM_CHAR Ради эксперимента вновь включил MessageBox'ы. Получил следующее В окошке Output и в MessageBox'ах
В Spy++
Как я понял, WM_CHAR и WM_KEYUP не могут существовать вместе 3) Мы в данном топике рассматриваем особенности диалоговых окон. В обычном окне все должно быть OK, поскольку там нет этой самой обработки клавиш по умолчанию. С немодальном диалоговом окном я попробовал. Если применять IsDislogMessage, ничего не меняется. Если обходится без IsDialogMessage, окно функционирует как обычное, не диалоговое (приходят, как и должно быть, WM_KEYDOWN, WM_CHAR, WM_KEYUP). WM_GETDLGCODE не приходит. Если включить MessageBox'ы, то и в окошке Output, и в MessageBox'ах, и в Spy++:
Есть что-то общее с диалоговыми окнами, не правда ли? 4) Общие вопросы и предложения Earnest, спасибо за OutputDebugString. Про эту функцию я тоже не знал. Кто знает, почему Spy++ не поддерживает помещение текста в буфер обмена? Такая полезная возможность была бы. Вопрос. Как отлаживать код, подобный моему (с макросами)? Это сообщение отредактировал(а) 0x07L - 11.7.2006, 20:44 |
||||||||||||
|
|||||||||||||
| Earnest |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
0x07L, молодец, вот уж не поленился!
А в чем, собственно, вопрос? Я вижу только одну проблему: отладочные макросы сильно замусоривают код... Лучше, конечно, делать их более незаметными. Во-первых, нет смысла выводить отладочную информацию в MessageBox - это всегда нарушает нормальный ход выполнения (переключение активных окон и т.д.). От использования Sleep - тоже польза сомнительная (разве что с разными потоками работаешь). Т.е. для вывода достаточно трассировочных сообщений. Приходим к следующему:
При желании все же иметь MessageBox, можно эту возможность включить в функцию, которая выполняет DEBUG_DUMP. Если отладкой управляют несколько макросов (разными опциями) их реализацию нужно выносить в вспомогательную функцию:
Коротко, смысл в следущем. Никаких #ifdef\#endif внутри полезного кода. Никаких временных переменных для отладки. Если в них все же возникает необходимость, написать вспомогательные функции, классы и т.д., за пределами полезного кода. Отладочный макрос должен записываться одним предложением, желательно покороче. И т.д. Тогда полезный код сохраняет прозрачность, отладка включается \ отключается легко и очевидно. И проблем с отладкой не возникает. -------------------- ... |
||||
|
|||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Здорово!
А я тут заметил еще момент. Флажок DLGC_WANTCHARS (один из тех, которые мы возвращаем из обработчика WM_GETDLGCODE) вообще не играет роли. Если его не указывать, все остается так, как было. Интересно, почему в MSDN об этом не упоминается. |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Да? А если вообще GetDlgCode не обрабатывать, тоже? По идее, вроде, должно.
Т.е. меня изначально удивило, что в диалоге что-то меняется от наличия\отсутствия обработчика GETDLGCODE. А в MSDN это как раз написано, но не прямо: GETDLGCODE стандартно имеет смысл для контролов, диалог по-умолчанию вроде должен получать весь ввод (который контролы схватить не успели). Только почему-то у тебя в самом начале вроде не получалось получить ENTER. Я ранний код не очень внимательно смотрела (большой -------------------- ... |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Если не использовать в обработчике WM_GETDLGCODE SetWindowLong(...MSGRESULT...WANTALLKEYS...), то Enter будет приходить только через lParam этого самого WM_GETDLGCODE и больше его не будет видно нигде.
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Понятно, т.е. WANTALLKEYS нужно, а WANTCHARS нет...
Интересно, откуда все же разница между выводом Spy и твоей DialogProc? По идее, Spy подключает хук к процессу и выводит все проходящие сообщения. Остается только предположить, что внутри цикла DialogBox происходит какая-то трансляция сообщений. Т.е. Spy, видимо, подключается непосредственно к очереди, а в диалоговую процедуру попадают уже процеженные сообщения ... -------------------- ... |
|||
|
||||
| 0x07L |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 272 Регистрация: 10.6.2006 Где: Москва Репутация: 4 Всего: 5 |
Причем сообщения могут не только процеживаться, но еще и добавляться (WM_GETDLGCODE). Без SendMessage и PostMessage, кстати.
Что мы имеем: 1) WM_KEYUP не посылается из-за переключения окна или истечения времени ожидания. 2) Что происходит с WM_CHAR, непонятно. Ясно только то, что с ним что-то делает цикл обработки сообщений диалогового окна Это сообщение отредактировал(а) 0x07L - 11.7.2006, 20:38 |
|||
|
||||
| diverkaz |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 26.11.2007 Репутация: нет Всего: нет |
У меня тоже проблема с Enter и ListView, почитал эту тему и попробова... И в результате он у меня в WM_GETDLGCODE ВОБЩЕ не заходит.. подскажите в чем проблемма... может у диалога стиль кокойнить особый нужен...
Пробовал даже копиваровать ваш исходник... но все равно не заходит ни в WM_GETDLGCODE ни в WM_KEYDOWN? |
|||
|
||||
| AndreyK |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 102 Регистрация: 15.3.2007 Репутация: нет Всего: нет |
У меня была та-же проблема, но с другими элементами - они сначала сами обрабатывают свои сообщения, а потом только соизволяют передать (ненужное), обработчику.
Я эту проблему решил, при помощи перехвата всех сообщений в программе (SetWindowsHook). При старте диалога я включаю режим фильтрации и сравниваю хендл окна, если совпадает - обрабатываю.
Это сообщение отредактировал(а) AndreyK - 26.11.2007, 16:34 |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |