DestroyWindow( hwndDlg ); hwndDllDlg = NULL; } return TRUE; case WM_DESTROY: UnhookWindowsHookEx( hHook ); return FALSE; } return FALSE; } 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); } 参考文档 微软知识库文章Q233263 PRB: Modeless Dialog Box in a DLL Does Not Process TAB Key
1.in your init function.call this MSG msg; while (::IsWindowVisible(g_hOEMainWnd)) { if(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg);
// Send all keyboard messages to the window of your // application. hwndApp is the window handle of // your application. //
DispatchMessage(&msg); } } 2.in your dialog function deal OnKeydown function LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // m_spWebBrowser is a data member of type IWebBrowser2. // Using CComQIPtr in this way queries m_spWebBrowser // for the IOleInPlaceActiveObject interface which is // then stored in the pIOIPAO variable. // CComQIPtr<IOleInPlaceActiveObject, &IID_IOleInPlaceActiveObject> pIOIPAO(m_spWebBrowser);
问:我的COM组件中有几个非模态对话框,使用客户程序调用这些非模态对话框,但却发现它们不能响应键盘操作,比如按回车或tab键都不起作用,郁闷死了,这些键盘操作对我来说挺重要。有哪位高手能给予指点迷津,先谢谢啦!
答:要让非模态对话框处理对话框特定消息,消息循环需要调用IsDialogMessage API。但是动态库和COM组件无法修改当前的从消息循环来做到这一点。你可以在对话框生命期中用一个WH_MESSAGE钩子来捕获并且处理这些消息
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;
}
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);
}
参考文档
微软知识库文章Q233263 PRB: Modeless Dialog Box in a DLL Does Not Process TAB Key
MSG msg;
while (::IsWindowVisible(g_hOEMainWnd))
{
if(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
// Send all keyboard messages to the window of your
// application. hwndApp is the window handle of
// your application.
//
// if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST && msg.message == WM_KEYDOWN)
// ::SendMessage(this->m_hWnd,msg.message, msg.wParam, msg.lParam);
DispatchMessage(&msg);
}
}
2.in your dialog function deal OnKeydown function
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
// m_spWebBrowser is a data member of type IWebBrowser2.
// Using CComQIPtr in this way queries m_spWebBrowser
// for the IOleInPlaceActiveObject interface which is
// then stored in the pIOIPAO variable.
//
CComQIPtr<IOleInPlaceActiveObject,
&IID_IOleInPlaceActiveObject> pIOIPAO(m_spWebBrowser);
HRESULT hr = S_FALSE;
if (pIOIPAO)
{
MSG msg;
msg.message = uMsg;
msg.wParam = wParam;
msg.lParam = lParam;
hr = pIOIPAO->TranslateAccelerator(&msg);
}
return hr;
}
for more details ,msdn have an article talking about this