| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Сообщение WM_KEYUP |
| Автор: Nastya 4.2.2003, 23:41 |
| Такая ситуация. Пустое диалоговое окно. Обрабатываю сообщенеи WM_KEYUP, WM_KEYDOWN. Все хорошо. Стоит поставить на него или статик или кнопку(любой элемент) и сообщение уже "достается" тому элементу и до самого окна не доходит. Что желать. А если элементов на окне не один. |
| Автор: Baa 5.2.2003, 00:23 |
| легким движением руки этого порешить не получилось (в виду не особо хорошего знания MFC) Возможные варианты решения: Если делать прогу без MFC, то там все просто... Можно использовать DirectInput. з.ы. грамотные люди, я бы тож очень хотел знать ответ на этот вопрос |
| Автор: Guest_Paradox 5.2.2003, 00:38 |
| Дело в том что как только появляется на форме некоторый визуальный компонент Windows передает фокус ему и все сообщения начинает получать этот компонент и соответственно обрабатывать их своими обработчиками по умолчанию. Надо просто убрать с него фокус ввода, если интересно отвечу подробнее... |
| Автор: Vaulter 5.2.2003, 00:49 |
| создай кнопку со стилем PARENTNOTIFY что то типа того. тогда сообщения от контрола будут идти в окно в форме WM_NOTIFY сообщения. но от самого окна также должно все идти как и раньше |
| Автор: Nastya 5.2.2003, 01:12 | ||
Надо... Спасибо... |
| Автор: HexoGen(i)us 9.2.2003, 07:42 |
| Одна из возможных проблем: для того что бы убрать фокус ввода с компонента на окне как мне кажется само окно должно иметь возможность получить этот фокус... для этого окно нужно создавать со стилем WS_TABSTOP второе что нам нужно это сделать так что бы если кнопка по каким либо причинам получила фокус то чтобы она его тут же отдавала (типа не тронь бяку) Для этого мы можем задать ей стиль BS_NOTIFY и она будет пересылать все свои нотификационные сообщения родительскому окну... А вот сами сообщения #define BN_CLICKED 0 #define BN_PAINT 1 #define BN_HILITE 2 #define BN_UNHILITE 3 #define BN_DISABLE 4 #define BN_DOUBLECLICKED 5 #if(WINVER >= 0x0400) #define BN_PUSHED BN_HILITE #define BN_UNPUSHED BN_UNHILITE #define BN_DBLCLK BN_DOUBLECLICKED #define BN_SETFOCUS 6 #define BN_KILLFOCUS 7 #endif /* WINVER >= 0x0400 */ Вобщем я так понимаю тебе нужно отлавливать нотификационное сообщение BN_SETFOCUS (возможно и сообщение при нажатии WM_COMMAND) и передавать фокус своему окну SetFocus(HandleMyWindow); Извини если все это не сработает... если честно я не знаю как правильно работать с сообщениями хотя и приходится их постоянно использовать... я все это опробывал в билдере а в нем сообщения перехватываются как я понимаю не так как в VC++ если не получится пиши |
| Автор: Chegal 26.2.2005, 08:45 |
| Может уже не актуально, но вдруг кому-то понадобится (сам искал все утро): для обработки ЛЮБЫХ сообщений до того как они будут переданы соответствующим дочерним окнам используем в MFC - BOOL PreTranslateMessage(MSG* pMsg) т.е. CTRL+w ->Messages->PreTranslateMessage (можно и вручную), после чего для обработки, например, клавиатуры вставляем код: BOOL CCommanderDlg::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class if (pMsg->message==WM_KEYDOWN && pMsg->wParam== VK_DOWN) { AfxMessageBox("Нажата клавиша вниз!"); } return CDialog::PreTranslateMessage(pMsg); } |
| Автор: Гость_ghost 16.6.2005, 01:34 |
| не с++, все на API. есть диалог, на нем два десятка EditBox и две кнопки в главном цикле диалога ловлю любые изменения в любом EditBox которые EditBox видимо посылает сам (типа я изменился) проблема. не могу отловить WM_KEYDOWN для служебных клавиш (Insert/Home/End) Могу конечно создать личный обработчик для каждого EditBox, но как то уж очень грамоздко. у кого какие идеи ?? |
| Автор: chaos 16.6.2005, 06:10 | ||
а по моему для этого WM_SYSKEYDOWN нужен |
| Автор: Гость_ghost 16.6.2005, 17:37 |
| WM_SYSKEYDOWN ловит Shift/Ctrl/Alt ;( |
| Автор: Earnest 17.6.2005, 20:23 | ||
1) Обработчик может быть один -> новая WindowProc -> класс для всех ваших edit'ов. 2) По-моему Hook, повешенный на окно, должен ловить сообщения детям/от детей, но точно не помню... |
| Автор: Fantasist 18.6.2005, 20:12 | ||
О каких Нооках идет речь? Если те, что SetWindwsHookEx - так они вешаются только на поток/процесс. А так просто своя WindowProc обычно выручает. |
| Автор: Earnest 20.6.2005, 08:02 |
| Да, SetWindowsHookEx, WH_KEYBOARD, можно повесить на поток, которому принадлежит окно и ловить весь клавиатурный ввод. Хотя в hook-процедуру окно не передается, но узнать, кто сейчас в фокусе, не проблема. Но не могу не согласиться, что для данной задачи проще и естественнее своя WindowProc. |
| Автор: Guest 20.6.2005, 19:24 | ||
| >>для данной задачи проще и естественнее своя WindowProc. Куда уже проще
Только case WM_COMMAND на нажатие клавиш Home/End не реагирует Пришлось создать новую EditBoxProc v case WM_INITDIALOG : SetWindowLong( GetDlgItem( dialog, NUM_0 ),GWL_WNDPROC, (LONG) EditBoxProc ) ; а потом в EditBoxProc ловить WM_KEYDOWN Все же попробую SetWindowsHookEx, может получится |
| Автор: Earnest 20.6.2005, 19:40 | ||||
Естественно, это не WM_COMMAND, а WM_KEYDOWN, причем приходящие одному из дочерних окон.
Собственно, именно это и имелось в виду. |
| Автор: Guest 20.6.2005, 20:06 |
| WM_KEYDOWN в главный цикл не попадает, а писать "новую EditBoxProc в case WM_INITDIALOG" для каждого EditBoxа кажется не совсем уместным, к тому же к етим EditBoxам уже добавилось 4 ComboBоxа, и что появится дальше никому не ихвестно |
| Автор: Guest 20.6.2005, 21:15 | ||
| поставил SetWindowsHookEx, cool. при иницизлизации KeyboardHook = SetWindowsHookEx( WH_KEYBOARD , (HOOKPROC) HookOnKeyboard, NULL , GetCurrentThreadId());
Теперь другая проблемма, ф-я KeybardProc отрабатывет дважды,а на breakpoint остнавливается один раз |
| Автор: Earnest 21.6.2005, 07:50 | ||
| 1) Может, это WM_KEYDOWN и WM_KEYUP ? 2) Если клавишу держать "long enough", код WM_KEYDOWN повторяется, см. описание WM_KEYDOWN в MSDN
|
| Автор: Fantasist 21.6.2005, 08:13 | ||||
Безусловно это не проблема, однако было утверждение о вешании хука на окно, вот я и уточнил, о чем речь. Далее. Я считаю использование хуков в данном случае это из пушки по воробьям. Во-первых, они явно создают лишнюю нагрузку. Во-вторых, сама идиология перехвата сообщений внутри своей программы мне кажется странноватой. В твоей программе control flow должен контролироваться логикой программы, а не перехватами.
Своя WindowProc - это не обязательно своя реализация ее. Из своей WindowProc вполне можно вызвать стандартную, сохранив ее перед этим вызвав GetWindowLong(); |
| Автор: Earnest 21.6.2005, 17:08 | ||||
В общем, конечно, правильно. Но...
Нельзя не посочувствовать автору... Писать хоть и тривиальные, но разные обработчики для новых типов контролов ... бр ... Хотя я бы, наверно, в такой гипотетической ситуации (только API, без с++), написала свой модальный цикл, как это делается в том же MFC. И уж там, между GetMessage и DispatchMessagе можно делать все что угодно. |
| Автор: Гость_ghost 24.6.2005, 21:06 |
| может оно и из пушки по воробьям Но в dialog у меня что то типа GRID для базы, за последнюю неделю добаволось еше пару комбов и с десяток edit, дурдом, на МФС можно было бы за неделю все сделать(я думаю) может даже ActiveX какой впихнуть, а тут толко Си 1) Может, это WM_KEYDOWN и WM_KEYUP ? тогда бы он на breakpoint остановился бы короче, в HookOnKeyboard HIWORD(lParam) приходит один раз с нормальным кодом и тут же с какойто хернеЙ которая > 49000 , что ето такое нигде не нашел да черт с ней . Работает ? Не трогай : |
| Автор: Earnest 24.6.2005, 22:15 | ||||
Не обязательно. На WM_KEYDOWN остановится, а WM_KEYUP уже в другой процесс попадет... Т.к. активно в этот момент будет окно отладчика. Поймать KEYUP можно только, если пропускать KEYDOWN...
Набери в MSDN WM_KEYDOWN и все тебе про параметры расскажут - там битовая структура. Если надо, конечно... |