开发基于MFC的ActiveX控件的时候的一些消息处理
来源:互联网 发布:达芬奇调色软件官方 编辑:程序博客网 时间:2024/06/05 04:56
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
SYMPTOMS
However, PreTranslateMessage is not always called for an MFC ActiveX control.
CAUSE
Internet Explorer does not automatically UI-Activate any controls when a page is first loaded. Internet Explorer waits until the user tabs to an ActiveX control on the page to UI-Activate it. Also, MFC ActiveX controls UI-Activate themselves when they are clicked with the mouse. In an MFC ActiveX control, this is done in COleControl::OnLButtonUp.
If you have a child control inside your COleControl, mouse-click messages on the child control are not sent to the COleControl and MFC does not UI- Activate the ActiveX control, even though the child control has just been given the keyboard focus. Internet Explorer intercepts the keystrokes and does not give the control a chance to filter them in PreTranslateMessage.
// 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; }
MORE INFORMATION
Sample Code
// 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(); }
Steps to Reproduce the Problem
- Select the MFC ActiveX ControlWizard to create an ActiveX control. Accept all the default settings.
- Display a modeless dialog box or propertysheet window when double-clicking inside the control.
在消息回调函数中调用PreTranslateMessage() 处理对话框消息,加速键消息,然后处理特殊按键
最后调用COleControl::PreTranslateMessage(pMsg); 如果该ActiveX控件内包含其他MFC类的子控件
若经过PreTranslateMessage处理以后把消息全部置空,这样这些消息就不会再被容器应用程序所处理。
- 开发基于MFC的ActiveX控件的时候的一些消息处理
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件开发
- 基于MFC的ActiveX控件
- MFC ActiveX (ocx)控件的开发的一些注意点
- Android操作Html打开其他APP
- 认识CoreData—高级用法
- js中call和apply
- android services生命周期深刻认识
- java常用设计模式
- 开发基于MFC的ActiveX控件的时候的一些消息处理
- 在CentOS Issue里显示服务器IP地址
- 删除一个固定目录下的文件
- 广播注册的两种方式
- PCB 过孔相关
- HDU-1260-Tickets【DP】
- 讯飞语音听写常见问题
- 一个爬虫的实现
- 最小编辑距离代码