使用ActiveX控件

时间:2015-07-24 15:28:58

标签: internet-explorer activex shortcut-key

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

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

我有一个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控件中停止所有快捷键的工作!因此,例如,用户无法使用 Ctrl + C Ctrl + V Ctrl + A ,还有 Del 键,在<input><textarea>控件中; Ctrl + C 不会从页面复制任何内容(甚至不是静态文本),它会保持当前剪贴板内容不变。所以基本上我认为他们只是被忽略了。使用右键单击上下文菜单进行复制/粘贴可以正常工作。离开页面是恢复行为的唯一方法。

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

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

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

1 个答案:

答案 0 :(得分:0)

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

处理加速键需要的ActiveX控件(我想我已经学会了 Ctrl + C 加速器而不是快捷键 em>)当用户与之交互时。为此,它的代码明确取自https://support.microsoft.com/en-gb/kb/187988。我的应用程序中代码的 gist 是:

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中的网页窗口。所以,这个代码“吞噬”加速器不仅针对自身,而且也适用于页面上的所有其他控件

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

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

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

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