本文共 7154 字,大约阅读时间需要 23 分钟。
MFC有PreTranslageMessage() 可以处理一些基于MFC的消息处理。
可是有时候如果你开发一个基于MFC的ActiveX作为容器,内部实现是Win32 或者其他框架会发现,好多消息都不能正常收到。
除非把你现有的内部的控件基于各种MFC的基类实现(会重载各种MFC的PreTranslateMessage)才能收到各种消息。
根本原因是基于MFC的ActiveX控件没有自己的消息循环,要基于使用ActiveX的容器来处理消息。这样有时候会忽略掉一些我们需要的消息。
微软官方有出过KB来解决问题,这里贴出了备忘一下。
PRB: MFC ActiveX Control in IE Doesn't Detect Keystrokes
https://support.microsoft.com/en-us/kb/168777
The TAB key, arrow keys, and accelerator keys do not work as expected when an ActiveX control is the parent window of a modeless dialog box or of a propertysheet window
https://support.microsoft.com/en-us/kb/187988
// trap keys and forward on to the control BOOL CMyActiveXCtrl::PreTranslateMessage(MSG* pMsg) { switch (pMsg->message) { case WM_KEYDOWN: case WM_KEYUP: switch (pMsg->wParam) { case VK_UP: case VK_DOWN: case VK_LEFT: case VK_RIGHT: case VK_HOME: case VK_END: SendMessage (pMsg->message, pMsg->wParam, pMsg->lParam); // Windowless controls won't be able to call SendMessage. // Instead, just respond to the message here. return TRUE; } break; } return COleControl::PreTranslateMessage(pMsg); }
int CMyActiveXCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message) { if (!m_bUIActive) OnActivateInPlace (TRUE, NULL); // == UI-Activate the control return COleControl::OnMouseActivate(pDesktopWnd, nHitTest, message); }
int CMyActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (COleControl::OnCreate(lpCreateStruct) == -1) return -1; OnActivateInPlace (TRUE, NULL); // == UI-Activate the control return 0; }
// Handle to the Windows Message hook. It can be a global variable or a // member variable in your CPropertySheet-derived class. HHOOK hHook = NULL; // Hook procedure for WH_GETMESSAGE hook type. LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam) { // Switch the module state for the correct handle to be used. AFX_MANAGE_STATE(AfxGetStaticModuleState( )); // If this is a keystrokes message, translate it in controls' // PreTranslateMessage(). LPMSG lpMsg = (LPMSG) lParam; if( (nCode >= 0) && PM_REMOVE == wParam && (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) && AfxGetApp()->PreTranslateMessage((LPMSG)lParam) ) { // 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 = 0L; lpMsg->wParam = 0; } // Passes the hook information to the next hook procedure in // the current hook chain. return ::CallNextHookEx(hHook, nCode, wParam, lParam); } // Declare and define the following two functions: BOOL CModelessPropertySheet::OnInitDialog() { CPropertySheet::OnInitDialog(); // Install the WH_GETMESSAGE hook function. hHook = ::SetWindowsHookEx( WH_GETMESSAGE, GetMessageProc, AfxGetInstanceHandle(), GetCurrentThreadId()); ASSERT (hHook); return TRUE; // Return TRUE unless you set the focus to a control. // EXCEPTION: OCX Property Pages should return FALSE. } void CModelessPropertySheet::OnClose() { // Uninstall the WH_GETMESSAGE hook function. VERIFY (::UnhookWindowsHookEx (hHook)); CPropertySheet::OnClose(); }
在消息回调函数中调用PreTranslateMessage() 处理对话框消息,加速键消息,然后处理特殊按键
最后调用COleControl::PreTranslateMessage(pMsg); 如果该ActiveX控件内包含其他MFC类的子控件
若经过PreTranslateMessage处理以后把消息全部置空,这样这些消息就不会再被容器应用程序所处理。
转载地址:http://gxbg.baihongyu.com/