Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: События клавиатуры  (Прочитано 20926 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aleexeey
Постоялец

ru
Offline Offline

« : 29-03-2008 13:28 » 

Добрый день!

  У меня такая проблема:
есть диалоговое окно, и на нем дочерние элементы.
есть событие от нажатия клавиши на клавиатуре.
  Так вот, событие возникает если фокус непосредственно на диалоге,
а когда фокус на дочернем элементе, то хоть "зажмись" клавишей, события не возникнет!

Может кто знает, как получать события с клавиатуры, не зависимо от фокуса диалога!

(Использование хука для данной ситуации мне не приемлема).
пожалуйста! кто может!!!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 29-03-2008 13:35 » 

1) для начала надо определиться с ОС
2) в любом случаем: события перехватить в дочерних элементах и отправить родителю

Записан

Aleexeey
Постоялец

ru
Offline Offline

« Ответ #2 : 29-03-2008 13:43 » 

винда  Улыбаюсь.
а как перехватить событие дочерних?
« Последнее редактирование: 29-03-2008 13:45 от Aleexeey » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 29-03-2008 14:32 » 

произвести от нужных контролов дитёв, там переопределить DefWindowProc и в нужных сообщениях перенаправить к родительскому окну
Записан

Aleexeey
Постоялец

ru
Offline 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 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 29-03-2008 16:16 » 

на чистом АПИ не знаю как, видимо да , обрабатывать нужные сообщения в своей процедуре, а остальное отдавать на обработку по умолчанию для окна

проделай эксперимент: забей какое нибудь сообщение, например WM_MOUSEMOVE . Если получиться - считай оно самое )
Записан

Aleexeey
Постоялец

ru
Offline Offline

« Ответ #6 : 30-03-2008 07:10 » 

спс! буду пробовать!
Записан
Aleexeey
Постоялец

ru
Offline Offline

« Ответ #7 : 30-03-2008 08:13 » 

Что это такое?

После регистрации:
Код:
RegisterClass(&wName);

компонент создается, но принимает либо облик другого компонента, либо вообще не отображается Не понял
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 30-03-2008 08:59 » 

1) а что делал не как обычно
2) как заполнена wName ?
Записан

Aleexeey
Постоялец

ru
Offline 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 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 30-03-2008 10:26 » 

в DefWindowProc что написал ?
Записан

Aleexeey
Постоялец

ru
Offline 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
Постоялец

ru
Offline 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 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline 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
Постоялец

ru
Offline Offline

« Ответ #14 : 30-03-2008 15:28 » 

Спасибо Алексей1153++!
А вот этого я и не знал! Буду пробовать,
мож что получится!

Спасибо еще раз!!!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 30-03-2008 15:41 » 

Aleexeey, расскажи потом про результаты, мне тоже интересно )
Записан

Aleexeey
Постоялец

ru
Offline 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;

Работоспособность проверена!!!
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 31-03-2008 09:41 » 

ты просто напросто не проверяешь msg.message.hwnd , где лежит хендл окна, которое должно обработать сообщение, поэтому, всё что ни летит - ты перехватил. )

Работает - значит всё правильно получилось. Осталось только заставить лететь сообщения к контролам, если это тоже понадобится Ага

Можно так сделать:
Код:
else
{
MyFunction();
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Записан

Aleexeey
Постоялец

ru
Offline Offline

« Ответ #18 : 31-03-2008 09:47 » 

Спс!  Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines