views:

66

answers:

4

Hi,

I used a ActiveXControl in a C# Forms application and had the possibility to implement a PreviewKeyDown event handler for that ActiveXControl. That was needed to specify that, e.g. the [ALT] key, is an input key.

For some reasons or other I have to reimplement the application in native C++/MFC and don't know how to specify that this [ALT] key is an input key and to be handled by the ActiveXControl.

A: 

I think that you can use the GetAsyncKeyState Win32 function (http://msdn.microsoft.com/en-us/library/ms646293%28VS.85%29.aspx) to get the state of all the keys in the system, VK_MENU is the kye you should monitor for the [Alt] key. Although I don't know if it will work for ActiveX Controls. Might need some investigation.

fritzone
A: 

Haven't tried this, but MSDN doesn't say that you won't get a WM_KEYDOWN for the ALT key -- any other key pressed while ALT is down generates a WM_SYSKEYDOWN, but that doesn't say that you can't handle ALT via WM_KEYDOWN.

AAT
A: 

You could use SetTimer to generate a WM_TIMER event 20 times a second or so

SetTimer( NULL, kMyTimer, 50, MyTimerCallback );

Then implement a function as follows.

 void CALLBACK MyTimerCallback( HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
 {
      static short lastLeftAltPress = 0;
      short thisLeftAltPress = GetAsyncKeyState( VK_LMENU );
      if ( thisLeftAltPress != 0 && lastLeftAltPress == 0 )
      {
           CallAltHandlingCode();
      }
      thisLeftAltPress = lastLestAltPress;

      // Handling code for other keys goes here.
 }

This will then poll the keyboard every 50ms to find out if the left alt key has just been pressed and then call your handling code. If you want to fire the handler when its released then you would use the following if statement

 if ( thisLeftAltPress == 0 && lastLeftAltPress != 0 )

or if you just want to see if it is down then you do

 if ( thisLeftAltPress != 0 )

The docs for GetAsyncKeyState do state that you can check whether the lowest bit is set to see if the key has just been pressed but it does also point out that this may fail in unexpected ways in multi-threaded environments. The above scheme should always work.

Goz
A: 

Hi,

thanks for all your recommendations.

For my case I finally found some way how to make it work. So far what I have learnt the situation is that a PreviewKeyDown event is triggered before the KeyDown message is sent.

I implemented PreTranslateMessage in the dialog which hosts the ActiveX control and called ::SendMessage(WM_KEYDOWN...) with the handle of the ActiveX control, using pMsg for the arguments.

Cheers,

Ilmari

Ilmari