0
votes

Short: I think I need to know how an ActiveX control does/should interact with (shortcut) key presses when it is on a page in Internet Explorer?

Long:

I have a very strange problem which I am looking for any help with.

I have an ASP.NET web application. Some .aspx pages include ActiveX controls, via:

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

Nothing special. I have the source (C++/MFC) to the (2) ActiveX controls --- written in-house, not my area, author has departed. Everything about the ActiveX control works fine (including interaction with the user), except...

At runtime, as soon as the ActiveX control is shown on page, Internet Explorer (any version) stops all shortcut-keys working, in any normal HTML control on the page! So, for example, user cannot use Ctrl+C, Ctrl+V, Ctrl+A, also the Del key, in an <input> or <textarea> control; Ctrl+C does not copy anything from the page (not even static text), it leaves the current clipboard content untouched. So basically I think they are simply ignored. Using right-click context menu to copy/paste does work fine. Leaving the page is the only way to restore behaviour.

Even worse(?), in Visual Studio (2010) at design-time if I go into the HTML Editor on the host .aspx page and go into "Design" or "Split" view (but not "Source"-only) all such shortcut-keys similarly cease working anywhere inside VS, in any window, making code editing difficult! I have to exit VS and re-enter to resolve. I think I recall a while ago that VS prompted me with "This page contains an ActiveX control, would you like it to show as such while viewing/editing the page" and I said "Yes" (cannot find where to undo that now?); so I guess it's the same problem as the IE-runtime.

I assume this is not normal behaviour for an ActiveX control on a page? I am seeking any help/advice as to what to look for in the (large) ActiveX control source code, please? I do not know how an ActiveX control on the page might be intercepting shortcut-keys in IE, even when some other normal HTML control has the focus/input? If that is the case (which I'm guessing), what am I looking for in source code and how can I rectify?

I am really stuck not knowing how to start on this, so anything appreciated.

1

1 Answers

0
votes

Well, not knowing anything, I went through all the source code of the ActiveX control. I stumbled across a PreTranslateMessage() call, and guessed that might be the root.

The ActiveX control needed to process accelerator keys (I think I have learned since my question that Ctrl+C etc. are accelerators rather than shortcuts) when the user interacted with it. To do so it had code clearly taken from https://support.microsoft.com/en-gb/kb/187988. The gist of the code in my application was:

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());

In in ActiveX control in IE, AfxGetMainWnd() is the web page window in IE. So, this code was "gobbling" accelerators not only aimed at itself but also at all other controls on the page.

Clearly, it needed a test to determine if the keystroke was aimed at itself or not. I went for:

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

There may be other better/more robust ways, I don't know, but that allows my ActiveX control to process accelerators when the mouse cursor is anywhere over it, while allowing them through to the IE parent window when it is anywhere else, which seems functional.

Moral (for anyone who cares): If you need an ActiveX control to handle keystroke messages, you need to code some mechanism to determine whether they are aimed at your ActiveX control or at the IE host. None of the examples I could find mentioned that.