Перехват Esc и Enter в диалоге
Суть такова, что в диалогах, которые создаются из ресурсов, некоторые сообщения не приходят в DlgProc (они отсеиваются IsDialogMessage). Одноим из таких сообщений является WM_KEYDOWN. Поискав по интернетам, где я и узнал об этом, я нашёл 2 варианта:
0. Сабклассинг оконной процедуры. Сказано — сделано
Код:
LRESULT APDTextSubclass(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData){
if(uMsg==WM_KEYDOWN && wParam==VK_RETURN){
//Отловили!
return 1;
}
return DefSubclassProc(hWnd,uMsg,wParam,lParam);
}
int APDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch(uMsg){
case WM_INITDIALOG:{
SetWindowSubclass(GetDlgItem(hDlg,TxtRegKey),APDTextSubclass,0,0);
…
if(uMsg==WM_KEYDOWN && wParam==VK_RETURN){
//Отловили!
return 1;
}
return DefSubclassProc(hWnd,uMsg,wParam,lParam);
}
int APDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch(uMsg){
case WM_INITDIALOG:{
SetWindowSubclass(GetDlgItem(hDlg,TxtRegKey),APDTextSubclass,0,0);
…
1. Среди этих обсуждений наткнулся на упоминание WM_GETDLGCODE. По описанию на MSDN вижу, что вроде то, что нужно. Пишу
Код:
int APDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch(uMsg){
case WM_GETDLGCODE:{
//Поймали это сообщение
}break;
…
switch(uMsg){
case WM_GETDLGCODE:{
//Поймали это сообщение
}break;
…
Как справиться хотя бы с одним из этих способов, чтобы они работали полностью и корректно?
Почитай, друг мой :). В частности, секция "Dialog Box Keyboard Interface" и табличка.
Если коротко, то Enter и Esc приходят не в WM_KEYDOWN, а в WM_COMMAND.
Если коротко, то Enter и Esc приходят не в WM_KEYDOWN, а в WM_COMMAND.
Спасибо, почитал ☺ Кстати, мне удалось реализовать это через имеющееся решение, только WM_KEYDOWN заменил на WM_KEYUP и ВНЕЗАПНО всё заработало! Правда, есть минусы, так что я всё-таки мигрирую на WM_COMMAND ☺
Upd.: будем считать, что это решение =) Ты бы в скайп ещё смотрел — цены б тебе не было.
Цитата: @pixo $oft
О, сам великий А-92 снизошёл к нам! :-D
Ну шо делать, шо делать... :D Считай, что потянуло в родные пенаты. :D
Цитата: @pixo $oft
мне удалось реализовать это через имеющееся решение, только WM_KEYDOWN заменил на WM_KEYUP и ВНЕЗАПНО всё заработало!
Месье знает толк в извращениях :)
Цитата: @pixo $oft
Ты бы в скайп ещё смотрел — цены б тебе не было.
Пополз в Скайп...
Upd.: Если попробуешь в студии создать оконное Win32-приложение -- только не пустое, а шаблонное, -- увидишь, что там в диалоговой процедуре обработка Enter & Esc как раз сделана через WM_COMMAND.
Не работает Enter. В описании сказано "wParam parameter is set to IDOK or control identifier of the default push button", но ни в ветку IDOK, ни в ветку кнопки по умолчанию выполение кода не входит. ЧЯДНТ?
Код:
switch (message) {
// ...
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
// ...
break;
case IDCANCEL:
// ...
break;
}
break;
// ...
}
// ...
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
// ...
break;
case IDCANCEL:
// ...
break;
}
break;
// ...
}