最近碰到一个问题,就是自己DialogBox创建的对话框处理不到WM_KEYDOWN消息,很奇怪!网上看了好多些解答,但是大多数都是说用MFC的PreTranslateMessage来处理,这个对于win32写的应用程序就没办法了。后来经过自己的摸索终于找到解决办法了!
首先我的问题场景是:DialogBox创建的模态对话框,里面有一个DropDown风格的Combobox,可以支持手动输入的。然后里面我添加了很多个选项,并且都很长,所以就要求用户手动输入选项的前面一些字符的时候可以自动匹配出对应的选项。在我做了这个联想的功能之后呢,发现如果我输错了想退格的时候Back和Delete键无效了,根本没反应。仔细想想不是没有响应,而是按了这个之后系统又自动联想了,把选项补全了,导致我们误以为没响应WM_KEYDOWN消息。
这里我提供两种解决办法:
1、完美的解决办法是:将DialogBox换成CreateDialog,用法不变,此时呢你得在WinMain里面手动加上消息循环,并对WM_KEYDOWN消息进行截获处理。要注意的是在消息过程中统一返回FALSE,对于没有处理过的消息,也就是default分支我们直接break掉就可以了,防止你在处理过程中弹出的MessageBox无法响应。
2、如果你不想将DialogBox换成CreateDialog并且自己手动写消息循环的话,那就麻烦点。在消息过程的WM_INITDIALOG中对Combobox的edit控件进行子类化:
HWND hWndCombo = GetDlgItem(hWnd, IDC_COMBO_BoardType);
POINT pt;
pt.x = 1;
pt.y = 1;
HWND hWndEdit = ChildWindowFromPoint(hWndCombo, pt);
lpOldProc = (WNDPROC)SetWindowLong(hWndEdit, GWL_WNDPROC, (LONG)NewDialogProc);
WNDPROC lpOldProc = NULL;
INT_PTR CALLBACK NewDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_KEYDOWN:
if (VK_BACK == wParam || VK_DELETE == wParam)
{
g_bAuto = FALSE;
}
else
{
g_bAuto = TRUE;
}
break;
case WM_SETFOCUS:
//ShowCaret(GetDlgItem(g_hWnd, IDC_COMBO_BoardType));
return FALSE;
default:
break;
}
return CallWindowProc(lpOldProc, hWnd, uMsg, wParam, lParam);
}
这样做,虽然可以满足需求,但是有一个问题,就是edit中的插入符不显示了,想了很多种办法都没有能解决掉。如果各位大侠有好的方法,欢迎跟帖!
本文介绍了在Win32非MFC应用中,DialogBox创建的对话框无法处理WM_KEYDOWN消息的问题。作者通过两种方法解决此问题:1. 使用CreateDialog并自行添加消息循环处理;2. 对ComboBox的edit控件进行子类化。第一种方法完美解决,第二种方法存在edit控件插入符不显示的副作用。

被折叠的 条评论
为什么被折叠?



