首页 文章

使用ActiveX控件丢失网页上的复制/粘贴快捷键

提问于
浏览
0

Short :我想我需要知道当ActiveX控件在Internet Explorer的页面上时,它是如何与(快捷方式)按键交互的?

Long

我有一个非常奇怪的问题,我正在寻找任何帮助 .

我有一个ASP.NET Web应用程序 . 一些.aspx页面包含ActiveX控件,通过:

<object classid="..." type="application/x-oleobject" codebase="url-in-my-app" />

没什么特别的 . 我有源(C / MFC)到(2)ActiveX控件---内部写的,不是我的区域,作者已经离开了 . 关于ActiveX控件的一切工作正常(包括与用户的交互),除了...

在运行时,只要在页面上显示ActiveX控件,Internet Explorer(任何版本)就会阻止所有快捷键工作,在页面上的任何普通HTML控件中!因此,例如,用户不能在 <input><textarea> 控件中使用 Ctrl+CCtrl+VCtrl+A ,也是 Del 键; Ctrl+C 不会从页面复制任何内容(甚至不是静态文本),它会保持当前剪贴板内容不变 . 所以基本上我认为他们只是被忽略了 . 使用右键单击上下文菜单进行复制/粘贴可以正常工作 . 离开页面是恢复行为的唯一方法 .

更糟糕的是(?),在Visual Studio(2010)的设计时,如果我进入主机.aspx页面上的HTML编辑器并进入“设计”或“拆分”视图(但不是“源” - 仅)这样的快捷键同样停止在VS内的任何地方工作,在任何窗口中,使代码编辑变得困难!我必须退出VS并重新进入以解决问题 . 我想我不久前回忆起VS提示我“这个页面包含一个ActiveX控件,你希望它在查看/编辑页面的同时显示”并且我说“是”(现在无法找到撤消的地方吗? );所以我猜这与IE运行时的问题相同 .

我假设这不是页面上的ActiveX控件的正常行为?我正在寻找关于(大)ActiveX控件源代码中要查找的内容的任何帮助/建议,好吗?我不知道页面上的ActiveX控件如何拦截IE中的快捷键,即使其他一些普通的HTML控件有焦点/输入?如果是这种情况(我猜是这样),我在源代码中寻找什么,我该如何纠正?

我真的不知道如何开始这个,所以任何感激 .

1 回答

  • 0

    好吧,不知道什么,我浏览了ActiveX控件的所有源代码 . 我偶然发现了一个 PreTranslateMessage() 电话,并猜测可能是根 .

    当用户与之交互时,ActiveX控件需要处理加速键(我想我已经从我的问题中学到了 Ctrl+C 等是加速器而不是快捷键) . 为此,它的代码清楚地取自https://support.microsoft.com/en-gb/kb/187988 . 我的应用程序中的代码的要点是:

    BOOL CMyActiveXControl::PreTranslateMessage(MSG* pMsg) 
    {
      // if we're an ActiveX control, we don't get direction keys (arrows, home, end)
      // so we need to intercept them here, and handle them
      // we don't want the parent to handle them, so return TRUE
      ...
      return TRUE;
    }
    
    // Hook procedure for WH_GETMESSAGE hook type.
    LRESULT CALLBACK GetMessageProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
      // 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) &&
         AfxGetMainWnd()->PreTranslateMessage((LPMSG)lParam) )
         {
           // Do *not* propagate this message to further hooks
         }
    }
    
    SetWindowsHookEx(WH_GETMESSAGE, GetMessageProc, AfxGetInstanceHandle(), GetCurrentThreadId());
    

    在IE中的ActiveX控件中, AfxGetMainWnd() 是IE中的网页窗口 . 所以,这个代码是"gobbling"加速器不仅针对自己,而且针对页面上的所有其他控件 .

    显然,它需要一个测试来确定击键是否针对自己 . 我去了:

    CRect rcFrame;
    AfxGetMainWnd()->GetWindowRect(&rcFrame);
    if (rcFrame.PtInRect(lpMsg->pt))
    

    可能还有其他更好/更健壮的方法,我不知道,但是当鼠标光标在它上面的任何地方时,它允许我的ActiveX控件处理加速器,同时当它在任何其他地方时允许它们通过IE父窗口,看起来很实用

    道德(对于任何关心的人):如果您需要一个ActiveX控件来处理击键消息,您需要编写一些机制来确定它们是针对您的ActiveX控件还是IE主机 . 我找不到的例子都没有提到 .

相关问题