.NET + COM 改变了键盘路由行为

发布于 2024-07-13 22:54:26 字数 1332 浏览 6 评论 0原文

我有一个非常奇怪的问题,我几乎无法给它起一个合适的标题。

简而言之:我有用 MSVC++/MFC 编写的 COM 对象,以及从 CDialog 派生的对话框。 在该对话框中,我有三个子“用户控件” - 从普通 CWnd 派生的窗口。

当我从不同的地方使用这个 COM 对象时,一切都按我的预期工作。 但是,当我从 C# 应用程序(.exe 文件)使用它时,键盘行为有所不同,或者我应该说是损坏了。

我的意思是:

  • 当我的任何“用户控件”获得焦点时按下的每个键都会从某处产生“错误蜂鸣声”,即使我尝试吞下 WM_KEYDOWN 消息,
  • “用户控件”也不会收到 WM_CHAR / OnChar ,虽然 Spy++ 说,
  • 如果我将 MessageBox 首先放入 OnKeyDown 和 OnChar,然后突然 OnChar 被调用,并且在显示位于 OnKeyDown 中第一个的 MessageBox 之前调用它,
  • 我可以通过发布消息来克服 OnChar 被调用的问题来自 OnKeyDown,但我无法找到停止蜂鸣声的方法。

与非 .NET 应用程序使用的 COM 对象对话框相比,这都是改变的行为。

我找到了一个我不太满意的工作,所以如果有人能阐明这个问题,我会非常高兴! :-)

解决方法如下。 我没有创建我的“用户控件”,如下所示:

m_mheSpell.CreateEx(
    WS_EX_CLIENTEDGE,
    NULL,
    "",
    WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL,
    4,18,340,100,
    GetSafeHwnd(), (HMENU)3000 );

我将其更改为:

m_mheSpell.CreateEx(
    WS_EX_CLIENTEDGE,
    "Edit",  // <-- changed here
    "",
    WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL,
    4,18,340,100,
    GetSafeHwnd(), (HMENU)3000 );

然后我必须确保阻止键盘、鼠标和焦点消息,以便底层编辑控件不会干扰我。 我只是担心我会错过阻止一些重要的消息,并且用户会在我自己发现之前发现一些意想不到的行为......

简而言之:“某些东西”(与周围的.NET环境相关)认为我的“ CWnd 控件”无法进行键盘处理,这让我很困惑。 派生自“编辑”使这个“某事”改变了主意。 例如,当周围进程是 VB6 应用程序时,所有这一切都不会发生。

有人吗?

I have a problem so strange that I hardly can put an adequate title to it.

In short: I have COM object written in MSVC++/MFC with a dialog derived from CDialog. On that dialog I have three child "user controls" - windows derived from plain CWnd.

When I use this COM object from a variety of places, everyhing works as I expect. But when I use it from a C# application (.exe file) the keyboard behavior is different, or shall I say broken.

And by different I mean that:

  • each key pressed when any of my "user controls" has focus produces an "error beep" from somewhere, even if I try to swallow the WM_KEYDOWN message
  • no WM_CHAR / OnChar is received by the "user control", although Spy++ says that one is posted
  • if I put a MessageBox first in OnKeyDown and OnChar, THEN suddenly OnChar gets called AND it gets called BEFORE the MessageBox located first in OnKeyDown is displayed
  • I can overcome the lack of OnChar getting called by posting a message from OnKeyDown, but I cannot figure out a way to stop the beeping

This is all CHANGED behavior compared to the COM object dialog being used from non-.NET applications.

I have found a work around which I'm not perfectly happy with, so if anyone could shed some light on this problem I'd be very happy! :-)

The work around goes like this. Instead of creating my "user controls", like this:

m_mheSpell.CreateEx(
    WS_EX_CLIENTEDGE,
    NULL,
    "",
    WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL,
    4,18,340,100,
    GetSafeHwnd(), (HMENU)3000 );

I change it to:

m_mheSpell.CreateEx(
    WS_EX_CLIENTEDGE,
    "Edit",  // <-- changed here
    "",
    WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL,
    4,18,340,100,
    GetSafeHwnd(), (HMENU)3000 );

and then I must make sure to block away keyboard, mouse and focus messages so the underlying edit control doesn't mess with me. I'm just afraid that I'll miss to block some important message and the user will find some unexpected behavior before I find it myself...

In short: "something" (related to the surrounding .NET environment) thinks that my "CWnd controls" aren't capable of doing keyboard processing and messes with me. Deriving from "Edit" makes this "something" change it's mind. All this does NOT happen when the surrounding process is, for example, a VB6 application.

Someone?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愛放△進行李 2024-07-20 22:54:26

啊,我现在可以回答我自己的问题了:
WM_GETDLGCODE
叹息

Ah, I can now answer my own question:
WM_GETDLGCODE
sigh

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文