【问题标题】:Winforms stealing keystrokes from COM component?Winforms 从 COM 组件中窃取击键?
【发布时间】:2010-10-21 16:55:45
【问题描述】:

我有一个 C++ ATL COM 组件,它显示一个弹出窗口(普通的 Win32,使用 WS_POPUP 样式),它允许用户输入一些搜索信息。这个组件已经针对 VB6 表单进行了相当广泛的测试(主要是为了便于调试),但我们希望将它与 .NET winforms 一起使用。

我们从 winforms 环境调用组件时发现的奇怪的事情是某些击键不再进入我们的弹出窗口。例如:我们在弹出窗口上子类化了一个编辑框来监听 ESC 键并关闭弹出窗口。在 VB6 中这很好用,但在 winforms 中,弹出窗口永远不会收到 ESC 的 keydown 事件(它会收到其他键,如标准字母数字)。

该组件的使用非常简单,但我将在此处提供一个快速示例来避免任何问题:

public partial class Form1 : Form
{
    CustomPopup panel;

    public Form1()
    {    
        panel = new CustomPopup(); //This is the COM object
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Point p = this.PointToScreen(button1.Location);
        // Display the popup, which gives focus to a child WC_EDIT field
        panel.ShowPopupAt(p.X, p.Y);
    }
}

如您所见,没什么大不了的。那么,关于 winforms 中的什么正在吞噬我们的击键以及我们如何让它停止的任何想法?

【问题讨论】:

  • 啊!!!!好吧,这真的让我很生气,但我找到了一个解决方法:当我的 WM_KEYDOWN 事件被迅速转移到以太中时,我的 WM_KEYUP 事件可以正常通过。在我的确切情况下,我可以利用它,但这远不是这个问题的一般解决方案。我不会将工单标记为已关闭,除非我们能得到某种解释,说明为什么按键消息被抑制以及如何解决这个问题。 (正是这样的事情让我慢慢开始鄙视.NET)

标签: .net winforms com key-events


【解决方案1】:

尝试抑制 WND 消息的 Windows 窗体处理(在窃取消息的控件/窗体中):

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_LBUTTONDOWN || m.Msg == WM_LBUTTONUP || m.Msg == WM_LBUTTONDBLCLK
       )
    {
        return;
    }
    base.WndProc(ref m);
}

【讨论】:

  • 我已经重写了 WndProc 来寻找消息并且它从来没有收到它,所以这不起作用。如果我注册为 IMessageFiler,我确实会在 PreFilterMessage 中看到它,有趣的是,如果我在 Spy++ 中找到该窗口,它显示的窗口句柄似乎是正确的,但它仍然无法弥补我的子类 proc。跨度>
  • 如果您的表单正在窃取焦点并且您从未点击过 WndProc 方法,则说明有问题。您确定要在窃取焦点的特定控件上处理 WndProc 吗?
  • 我不是 100% 确定,但考虑到程序由一个表单、一个按钮和我的弹出窗口组成,没有太多选项可供查看。 :)
  • 小更新:我现在正在查看我正在实例化的每个窗口(表单、按钮、弹出面板和编辑框)的消息,以及我见过的唯一地方我的 ESC 按键位于 PreMessageFilter 中,这似乎表明 .NET 在消息被发送到任何窗口之前正在抑制该消息。 :P
猜你喜欢
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 2017-07-26
  • 1970-01-01
  • 2016-06-08
  • 1970-01-01
相关资源
最近更新 更多