OnKeyDown and integration with managed code

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello,

I have a legacy MFC application that has a lot of editor functionality
associated with a class that extends CFrameWnd. This editor watches for key
down events by using the OnKeyDown handler in the message map. In my legacy
MFC application, my OnKeyDown handler is always called, as I would expect.

I'm calling the legacy application's editor window from within a C#
application. I've written a little C++/CLI application that bridges the
managed code, and exposes a C# friendly method for via explicit p/invoke.
This allows my editor to show up and (generally) work as I'd hope.

The problem is that the OnKeyDown handler in the CFrameWnd based dialog does
not always get called when the window is invoked from my managed code. It
gets called when I use simple keys like 'A' or '1' but if I press the Esc
key, my handler is not called.

Can anyone give any clues as to why my handler is not being called when the
Esc key is pressed? I used Spy++ to look at the messages being sent to the
CFrameWnd based dialog and it is receiving the WM_KEYDOWN message with the
VK_ESCAPE virtual key. Also, in case it matters, in my legacy application,
the window that launches the CFrameWnd based dialog is modeless, while in my
C# application, the window from which the CFrameWnd based dialog is launched
is modal.

Thanks!
Notre
 
Notre Poubelle said:
Hello,

I have a legacy MFC application that has a lot of editor functionality
associated with a class that extends CFrameWnd. This editor watches for
key
down events by using the OnKeyDown handler in the message map. In my
legacy
MFC application, my OnKeyDown handler is always called, as I would expect.

I'm calling the legacy application's editor window from within a C#
application. I've written a little C++/CLI application that bridges the
managed code, and exposes a C# friendly method for via explicit p/invoke.
This allows my editor to show up and (generally) work as I'd hope.

The problem is that the OnKeyDown handler in the CFrameWnd based dialog
does
not always get called when the window is invoked from my managed code. It
gets called when I use simple keys like 'A' or '1' but if I press the Esc
key, my handler is not called.

Can anyone give any clues as to why my handler is not being called when
the
Esc key is pressed? I used Spy++ to look at the messages being sent to
the
CFrameWnd based dialog and it is receiving the WM_KEYDOWN message with the
VK_ESCAPE virtual key. Also, in case it matters, in my legacy
application,
the window that launches the CFrameWnd based dialog is modeless, while in
my
C# application, the window from which the CFrameWnd based dialog is
launched
is modal.

The .NET local message dispatch loop, used for modal windows, probably calls
IsDialogMessage and then doesn't dispatch the message through your window
procedure. Try Application.AddMessageFilter for a workaround (catch
WM_KEYDOWN, call TranslateMessage+DispatchMessage, and then kill the
message, let all other messages be default processed).
 
Hi Notre,

Yes, just as Ben pointed out, .Net Winform encapsulates the GUI message
loop in the .Net BCL code. Also, to support some special key function in
..Net Winform, the WndProc of .Net Winform code may implement some type of
preprocessing to the message before dispatching to your OnKeyDown handler.
You may use Reflector to view the source code of
System.Windows.Forms.Application.ThreadContext.PreTranslateMessage method
to get a glance of the preprocessing.

So I suspect the .Net Winform preprocessing code may identify the ESC key
as a special key and did not dispatch to the MFC handler correctly.

Is it possible for you to create a little sample C++/CLI MFC project to
help me reproduce this problem? Once I can give it a local reproduce, I
will perform some debugging over it and provide some suggestion to you.

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thank you both Ben & Jeffrey for your prompt responses!

I'm not sure if I'm stating the problem correctly, or maybe I just do not
understand the responses.

The editor that extends CFrameWnd is the one that is not recognizing the
OnKeyDown handler when the Esc key is pressed. This editor is itself a
modeless window. It is the 'parent' window that is different between my
managed application and my legacy MFC application. In my managed
application, this parent window is modal. In my legacy application, this
parent window is modeless.

Do you guys think that your comments still apply, or are they more if the
editor window itself (the one that extends CFrameWnd) had changed from a
modeless to a modal window?

Thanks again!!!
Notre
 
Notre Poubelle said:
Thank you both Ben & Jeffrey for your prompt responses!

I'm not sure if I'm stating the problem correctly, or maybe I just do not
understand the responses.

The editor that extends CFrameWnd is the one that is not recognizing the
OnKeyDown handler when the Esc key is pressed. This editor is itself a
modeless window. It is the 'parent' window that is different between my
managed application and my legacy MFC application. In my managed
application, this parent window is modal. In my legacy application, this
parent window is modeless.

Do you guys think that your comments still apply, or are they more if the
editor window itself (the one that extends CFrameWnd) had changed from a
modeless to a modal window?

If any modal window exists on the thread, then message processing will be
done through a local dialog message dispatch loop instead of the main
application event loop. In Win32, such a loop calls IsDialogMessage before
dispatching messages, I see that the method Jeffrey mentioned inside .NET
does as well
(System.Windows.Forms.Application+ThreadContext.LocalModalMessageLoop(Form)
calls
System.Windows.Forms.Application+ThreadContext.PreTranslateMessage(ref MSG)
pinvokes IsDialogMessage). IsDialogMessage is known to eat the Escape key.

However, before calling IsDialogMessage, PreTranslateMessage calls
ProcessFilters, which invokes registered IMessageFilter objects, hence I
suggested that you use Application.AddMessageFilter to register a message
filter, which can pinvoke TranslateMessage and DispatchMessage, as
LocalModalMessageLoop does for all messages not processed by
IsDialogMessage. You should also check that the destination hwnd of the
message is your editor window or one of its descendants, otherwise you may
break the behavior of the owner modal window.
 
Hi Notre,

Glad to see Ben's suggestion of using IMessageFilter resolves your problem.

If you are curious, I have discussed this issue with one Architect of the
VC++ team. We agree that the modal issue is likely the problem. See the KB
below:
"PRB: Modal Dialog Box Prevents Calls to PreTranslateMessage"
http://support.microsoft.com/kb/126874.

Below is his comment:

"This KB isn't 100% correct in my opinion, however. I added code to MFC
back in '96 /' 97 to address this problem with normal modal MFC dialogs.
MFC has its own modal message loop now that does all the correct MFC things
like calling PreTranslateMessage.

However, if you are hosted by something else, this isn't going to happen.
The ESC key is normally used to cancel a modal dialog and this won't be
passed to any control in a dialog normally.

Exactly how is this dialog being hosted and invoked? Who actually controls
(i.e. who runs the loop of) the top-level dialog window? A screen shot
from Spy++ with the window hierarchy shown would be helpful."

Anyway, since your problem is resolved, hope this information just makes
sense to you.

If you need further help, please feel free to post. I am glad to help you.
Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thank you Jeffrey for following up further on this, and speaking with an
arhitect about the problem. I read through the KB and the architect's
comments for my own education. Ben's solution does indeed work, and I think
proves that the modal dialog box was causing the problem.

Thanks again,
Notre
 
Hi Notre,

Thanks for your feedback.

Glad to see the architect's reply makes sense to you. Yes, I also learned a
lot during the communication between the customer and the VC++ product
team. :-)

If you need further help, please feel free to post, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi Ben,

Also, thank you for sharing your good experience with the community!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top