Aleexeey
Постоялец
Offline
|
|
« : 29-03-2008 13:28 » |
|
Добрый день!
У меня такая проблема: есть диалоговое окно, и на нем дочерние элементы. есть событие от нажатия клавиши на клавиатуре. Так вот, событие возникает если фокус непосредственно на диалоге, а когда фокус на дочернем элементе, то хоть "зажмись" клавишей, события не возникнет!
Может кто знает, как получать события с клавиатуры, не зависимо от фокуса диалога!
(Использование хука для данной ситуации мне не приемлема). пожалуйста! кто может!!!
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #1 : 29-03-2008 13:35 » |
|
1) для начала надо определиться с ОС 2) в любом случаем: события перехватить в дочерних элементах и отправить родителю
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #2 : 29-03-2008 13:43 » |
|
винда . а как перехватить событие дочерних?
|
|
« Последнее редактирование: 29-03-2008 13:45 от Aleexeey »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 29-03-2008 14:32 » |
|
произвести от нужных контролов дитёв, там переопределить DefWindowProc и в нужных сообщениях перенаправить к родительскому окну
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #4 : 29-03-2008 14:47 » |
|
а если у меня элементы типа HWND, то получается к каждому элементу CALLBACK DefWindowProc(... писать надо?
я правильно понял? - создаю: WNDCLASS wc; ... ... wc.lpfnWndProc = (WNDPROC)DefWindowProc; ... ... регистрирую: RegisterClass(&wc); а потом LRESULT CALLBACK DefWindowProc(... и так для каждого элемента?
|
|
« Последнее редактирование: 29-03-2008 15:42 от Aleexeey »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 29-03-2008 16:16 » |
|
на чистом АПИ не знаю как, видимо да , обрабатывать нужные сообщения в своей процедуре, а остальное отдавать на обработку по умолчанию для окна
проделай эксперимент: забей какое нибудь сообщение, например WM_MOUSEMOVE . Если получиться - считай оно самое )
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #6 : 30-03-2008 07:10 » |
|
спс! буду пробовать!
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #7 : 30-03-2008 08:13 » |
|
Что это такое? После регистрации: компонент создается, но принимает либо облик другого компонента, либо вообще не отображается
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 30-03-2008 08:59 » |
|
1) а что делал не как обычно 2) как заполнена wName ?
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #9 : 30-03-2008 10:07 » |
|
1) только добавил обработку событий DefWindowProc и регистрацию. 2)wName лучше переименовать как wElem WNDCLASS wElem; memset(&wElem,0,sizeof(WNDCLASS)); wElem.lpfnWndProc = (WNDPROC)DefWindowProc; wElem.hInstance = hinst; // HINSTANCE hinst = GetModuleHandle(...); wElem.lpszClassName = "ComboBox"; // элемент класса Combo boxes Control wElem.hCursor=LoadCursor(NULL,IDC_ARROW); RegisterClass(&wElem); а компонент без данной регистрации работает как надо!?
|
|
« Последнее редактирование: 30-03-2008 10:09 от Aleexeey »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 30-03-2008 10:26 » |
|
в DefWindowProc что написал ?
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #11 : 30-03-2008 12:20 » |
|
Я понял в чем тут дело! Ведь wElem.lpszClassName = "имя класса"; - присваивает имя класса, а у меня компонент должен иметь "имя класса" своего класса (например "ComboBox" - элемент едит с выпадающем меню (Combo boxes))!!! Класс присваивается к wElem, а у элемента этот класс становиться неизвестным. Поэтому элемент либо создается с классом по умолчанию, применяя атрибуты "чужого" класса либо не может создать элемент вообще!!! Что делать А еще одна "заноза": Функция главного диалога обрабатывает описанные события, а остальные он посылает какрас в DefWindowProc, для обработки по умолчанию (default): return DefWindowProc(hDlg, iMsg, wParam, lParam); т. е. вызвав отдельно эту функцию, некуда дальше посылать необработанные события!? Что делать? ! ? как мне исчерпать "вышеспрошеный" вопрос!?
|
|
« Последнее редактирование: 30-03-2008 12:23 от Aleexeey »
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #12 : 30-03-2008 12:40 » |
|
Сначало я попытался использовать Hot. Т. е. инициализирую и регистрирую клавишу: bool RKey = RegisterHotKey(hwnd, код, NULL, VK_клавиша); затем ее использую в CALLBACK DialogProc(... : case WM_HOTKEY: if (wParam == код && (GetActiveWindow() == hDlg)) вызов моей функции(); break; а при закрытии диалога уничтожаю регистрацию зарезервированной клавиши: case WM_DESTROY: UnregisterHotKey(hDlg, код); я бы и оставил так, но в других приложениях перестает зарезервированная клавиша работать!!! Как быть! либо вышесказанный способ сделать или этот усовершенствовать! спасибо заранее!
|
|
« Последнее редактирование: 30-03-2008 13:18 от Aleexeey »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #13 : 30-03-2008 14:09 » |
|
Aleexeey, при переопределении обработки сообщения нужно возвращаться из своей оконной процедуры с не нулевым результатом. Вот к примеру LRESULT MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hWnd, Msg, wParam, lParam); }
- это будет абсолютно то же самое для дочернего класса, как будто ничего не переопределяли. А вот тут 3 разных случая переопределения реакции на события (в зависимости от нужной цели): LRESULT MyWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch { case WM_xxx1 { //выполняем свой код //...
//хотим также, чтобы выполнился и код базового класса - после свича это будет } break;
case WM_xxx2 { //выполняем свой код //...
//больше ничего не нужно выполнять тут return 1; } break;
case WM_xxx3 { //хотим, чтобы выполнился код базового класса DefWindowProc(hWnd, Msg, wParam, lParam);
//выполняем свой код //...
//больше ничего не нужно выполнять тут return 1; } break; }
//всё остальное по умолчанию - в процедуру базового класса return DefWindowProc(hWnd, Msg, wParam, lParam); }
должно всё выглядеть как-то так
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #14 : 30-03-2008 15:28 » |
|
Спасибо Алексей1153++! А вот этого я и не знал! Буду пробовать, мож что получится!
Спасибо еще раз!!!
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 30-03-2008 15:41 » |
|
Aleexeey, расскажи потом про результаты, мне тоже интересно )
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #16 : 31-03-2008 09:30 » |
|
Ребята! я нашел ответ!!! Дело вот в чем: Функция TranslateMessage проверяет сообщения WM_KEY DOWN или WM_SYSKEYDOWN, если одно из этих сообщений есть, то происходит попытка преобразовать код сообщения в символ. В случае удачи вызывается PostMessage для генерации сообщения WM_CHAR или WM_SYSCHAR, иначе переходит к функции DispatchMessage которая передает сообщение оконной (диалоговой) функции (например DefWindowProc). На основе этого получилось кое что собрать, но не знаю насколько это правильно!? Хочу услышать Ваше мнение! while (GetMessage(&msg, NULL, 0, 0)) { // вставка для перехрата сообщения. Т. е. если в сообщении событие от клавиши (данная клавиша утрачивает // свое сообщение и диалогу (компоненту) уже не передается!) то выполняется определенная функция!!! if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_SPACE)) MyFunction(); else // иначе все как обычно! { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; Работоспособность проверена!!!
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 31-03-2008 09:41 » |
|
ты просто напросто не проверяешь msg.message.hwnd , где лежит хендл окна, которое должно обработать сообщение, поэтому, всё что ни летит - ты перехватил. ) Работает - значит всё правильно получилось. Осталось только заставить лететь сообщения к контролам, если это тоже понадобится Можно так сделать: else { MyFunction(); TranslateMessage(&msg); DispatchMessage(&msg); }
|
|
|
Записан
|
|
|
|
Aleexeey
Постоялец
Offline
|
|
« Ответ #18 : 31-03-2008 09:47 » |
|
Спс!
|
|
|
Записан
|
|
|
|
|