简短:我想想我需要知道当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控件有焦点/输入?如果是这种情况(我在猜测),我在源代码中寻找什么,我该如何纠正?
我真的不知道如何开始这个,所以任何感激。
答案 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主机。我找不到的例子都没有提到过。