OCX控件在IE中无法侦测到键盘消息( MFC ActiveX Control in IE Doesn't Detect Keystrokes)

症状描述:

Accelerator keys, such as ARROW keys, are first received by the message pump of the ActiveX control's container. Even if the control has the focus, it does not receive messages for keystrokes that have special meaning to control containers, such as ARROW and TAB keys. MFC ActiveX controls have a chance to intercept these messages by overriding their PreTranslateMessage function.

However, PreTranslateMessage is not always called for an MFC ActiveX control.

原因:

PreTranslateMessage in an MFC ActiveX control is called by the TranslateAccelerator method of the IOleInPlaceActiveObject interface of the control. Internet Explorer only calls this method for the control that is currently UI-Active. Only one control can be UI-Active at a time.

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.

解决:

Here is a typical PreTranslateMessage. This code forwards ARROW, HOME, and END keys back to the control so that they can be received using a MESSAGE_MAP entry: 
   // 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);
   }
    If you have a child control within your ActiveX control, you need to UI-Activate the whole control whenever that child control is activated. For example, if you have an edit control inside your ActiveX control, add a handler as follows to your ActiveX control class: 
   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);
   }
    Because Internet Explorer may not immediately UI-Activate a control, even if that is the only control on the page, it may be desirable to automatically request a UI-Activation when the control is created. This can be done during the COleControl::OnCreate (WM_CREATE) handler. Windowless controls do not get WM_CREATE or any windows messages; therefore, this code won't work in a windowless control. Also note that this does not guarantee that a control will remain UI-Activated. If there are other controls on a page that request UI-Activation in a similar manner, only one will eventually be UI-Activated and receive keystroke messages as described. And if the user TABs away from an ActiveX Control, Internet Explorer will automatically UI-deactivate the control. 
   int CMyActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
   {
      if (COleControl::OnCreate(lpCreateStruct) == -1)
         return -1;
      OnActivateInPlace (TRUE, NULL); // == UI-Activate the control
      return 0;
   }
    

STATUS:
This behavior is by design. 
MORE INFORMATIONCalling OnActiveInPlace() in WM_CREATE causes an assert when the control is hosted in Test Container. The assert is bogus and can be ignored.

原文地址:http://support.microsoft.com/kb/168777/en-us

时间: 2024-10-29 10:50:15

OCX控件在IE中无法侦测到键盘消息( MFC ActiveX Control in IE Doesn't Detect Keystrokes)的相关文章

写了ocx控件 在网页中调用显示 对象不支持此属性或方法

问题描述 写了ocx控件 在网页中调用显示 对象不支持此属性或方法 我用的是 vs2010 用模版自动生成的只加了一个方法,然后自己写了一个vbs脚本调用这个方法正常,用的是控件名创建的对象.在网页中控件也创建成功的用的是classid方式创建的,但是调用这个方法就是提示对象不支持此属性或方法.我用activex control test 工具测试一切正常,也能看到这个方法,但是一到网页中就提示对象不支持此属性或方法 麻烦大家帮忙分析分析(我是初学者) 解决方案 应该是浏览器安全性阻止了控件的加

急,关于OCX控件在网页中的使用,在线等

问题描述 VC写的OCX控件,要调用3个DLL.该控件我已经在系统中注册.其其放入网页中后在.net的页面设计中可以看见该控件,但是在运行使用时就是看不见控件.也无法对其操作.(控件我没有打成.cab包,IE上有关ACTIVEX的限制我也全改过了,但还是不行.似乎根本就没下载,但是因该注册了就能使用了.)希望高手能指教,解决了立刻给分. 解决方案 解决方案二:顶解决方案三:难道就没人知道吗?解决方案四:在ASP.NET中使用OCX一般分以下几个步骤:一.对生成的DLL文件进行注册在CMD中reg

VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程

开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是总结了网上好多人写的文章,我只是汇总一下,加上部分自己的东西,在这里感谢所有在网上发表相关内容的朋友们.) ActiveX控件用于Web的过程是将控件嵌入主页中,用户通过浏览器访问该主页时,将主页中的控件下载,并在用户机器上注册,以后就可在用户的浏览器上运行.控件下载一次后就驻留在用户本地机器上,下次再访问相同的主页时,可不再下载该控件,而是直接运行用户本地的控件.这里控件容器就是

visual studio 2010-.exe怎么转为.ocx控件

问题描述 .exe怎么转为.ocx控件 在vs2010中,已经开发好了一个mfc基于对话框程序,怎么将此程序转换为.ocx控件

在HTM中引用VB6的OCX控件

控件 VB6可以很方便的编写OCX控件及DLL组件,要在网站中使用DLL组件的使用很简单,直接在ASP中使用Server.CreateObject("工程名.组件名")可以在服务器端调用该组件.而OCX使用则因为需要下载到客户端而变得复杂些,以下是我的一些经验: OCX打包成internet包:启运打包程序:菜单"外接程序"->"外接程序管理器"->启用"打包和展开向导"开始打包:菜单"外接程序"

VISUAL C++中的OCX控件的使用方法

新一代32位操作系统WINDOWS 95舍弃了VBX控件,取而代之的是OCX控件.OCX控件具有功能强大,界面美观的特点,然而许多参考书中并没有详细阐述OCX控件的使用方法,使得一些如数据库表格,远程数据控件等接口复杂的OCX难于使用.这里将详细阐述OCX的使用方法. 首先提醒读者要注意的是:使用OCX构件之前,必须登记注册,否则不能使用.安装VISUAL C++时,系统自动注册登记软件附带的OCX控件.如果不幸没有登记,那么请使用REGSVR32应用程序来注册.以VISUAL C++ 5.0为

在64位系统中ocx控件调用问题

问题描述 在64位系统中ocx控件调用问题 在64位系统中已注册32位程序的ocx控件,为什么32位程序无法显示ocx控件? 解决方案 和64位没有什么关系,你的程序必须是32bit的才可以调用32bit的控件. 如果你用的是C#,你需要强制将程序集限定为32bit 参考:http://blog.csdn.net/blueboy2000/article/details/4242369 解决方案二: jsp调用ocx控件 解决方案三: 你是不是用的的32bit版本的regsvr32注册. 然后就是

vs2008-如何在ocx控件中调用另一个已经封装完整的ocx控件?

问题描述 如何在ocx控件中调用另一个已经封装完整的ocx控件? ocx开发初学者一名. 手上有一个完整的ocx控件A,我希望在另一个控件B中插入这个A.在调用控件B的界面中可以看到A的界面.就像用一个exe调用ocx一样实现是否可行? vs2008环境.

win32应用程序中如何调用ocx控件呀?有没有哪位大神有写好的demo可以参考呀?

问题描述 win32应用程序中如何调用ocx控件呀?有没有哪位大神有写好的demo可以参考呀? win32应用程序中如何调用ocx控件呀?有没有哪位大神有写好的demo可以参考呀? 解决方案 例子:http://www.codeproject.com/Articles/18417/Use-an-ActiveX-control-in-your-Win-Project-witho