如题
解决方案 »
- 如何让一个普通成员函数像operator()那样充当for_each的第三个参数?
- 基于vc++无线通信上位机软件设计
- 数据库数据显示时,使用CListCtrl和使用CDataGrid的优缺点各在哪儿?
- 如何得到/设置MSN输入框的内容?
- 哪里有支持CGI的免费个人主页空间可以审请啊?
- 知道进程id如何得到进程名
- 真怪,为什么我的 virtual 有时候能运行不时候则不能?
- 十万火急?咋搞的inparam/outparam???????
- 请问有关CFileDialog问题
- 急求!!c++调用c#生成的COM库,传递自定义结构体的问题
- VC最小化时的代码在什么地方写?
- 发个帖子纪念一下,今天是我的生日
http://support.microsoft.com/default.aspx?kbid=233263
SYMPTOMS
When a modeless dialog box is launched from a dynamic-link library (DLL), the TAB key and the arrow keys do not move the focus from control to control as you would expect.
CAUSE
For a modeless dialog box to process a TAB key, the message pump needs to call the IsDialogMessage API. However, if you are writing a DLL and do not have access to the .exe's source code, you cannot modify the message pump to do this.
RESOLUTION
To work around this problem, you can use a WH_GETMESSAGE hook to capture the keystroke messages and call the IsDialogMessage API. If IsDialogMessage returns TRUE, then do not pass the message on to the message pump. Set the hook when handling WM_INITDIALOG and unset it when handling the WM_DESTROY message.
STATUS
This behavior is by design.
MORE INFORMATION
The following code illustrates how to set and unset the hook as well as how to use IsDialogMessage() to process TAB key messages: BOOL CALLBACK DllDlgProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
case WM_INITDIALOG:
hHook = SetWindowsHookEx( WH_GETMESSAGE, GetMsgProc,
NULL, GetCurrentThreadId() );
return TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
DestroyWindow( hwndDlg );
hwndDllDlg = NULL;
}
return TRUE; case WM_DESTROY:
UnhookWindowsHookEx( hHook );
return FALSE;
}
return FALSE;
}
The hook procedure, GetMsgProc, should resemble the following:
LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
LPMSG lpMsg = (LPMSG) lParam; if ( nCode >= 0 && PM_REMOVE == wParam )
{
// Don't translate non-input events.
if ( (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) )
{
if ( IsDialogMessage(hwndDllDlg, lpMsg) )
{
// The value returned from this hookproc is ignored,
// and it cannot be used to tell Windows the message has been handled.
// To avoid further processing, convert the message to WM_NULL
// before returning.
lpMsg->message = WM_NULL;
lpMsg->lParam = 0;
lpMsg->wParam = 0;
}
}
} return CallNextHookEx(hHook, nCode, wParam, lParam);
}