【问题标题】:Tricky c# form keyboard input focus issue棘手的c#表单键盘输入焦点问题
【发布时间】:2010-08-26 17:50:19
【问题描述】:

我有一个应用程序使用以下代码根据第三方应用程序生成的文件获取输入。

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        const int WM_KEYDOWN = 0x100;
        const int WM_SYSKEYDOWN = 0x104;

        if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
        {
            switch (keyData)
            {
                case Keys.F1:
                    clicked_F1(null, null);
                    break;

                case Keys.F2:
                    clicked_F2(null, null);
                    break;

                case Keys.F3:
                    clicked_F3(null, null);
                    break;
            }
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

Form.TopMost 设置为 true,并且在 OnShown 回调期间调用 this.Activate()。这适用于大多数机器,但有时键盘输入不会传递给我的应用程序,例如,如果按下 F1,则会弹出窗口帮助。

谁能解释这种行为?我需要确保我的表单能够接收这些键盘事件。

干杯, 理查德

【问题讨论】:

    标签: c# forms focus


    【解决方案1】:

    让您的表单 TopMost 足以确保此方法运行。你的表格也需要有焦点。这需要调用它的 Activate() 方法(Win32 API 中的 SetForegroundWindow)。 保证运行,您不能将焦点从用户正在使用的窗口中窃取。只有在距离上一次输入事件已经过去足够的时间后,您才能获得焦点。

    不确定你真正想要做什么,也许你需要一个键盘挂钩或使用 RegisterHotKey。

    【讨论】:

    • 谢谢汉斯。我在 OnShown 回调中设置了 Activate() 方法。我需要在始终设置 TopMost 运行的旧版 Till 应用程序上方放置一个窗口,以便为用户提供额外的选项。
    • 好吧,Windows 并不关心这个。我认为 pinvoking AttachThreadInput() 可能会有所帮助,您需要获取该程序的 UI 线程的 TID。 GetWindowThreadProcessId().
    • 绝对正确,这不是常规情况 - 我希望能够以另一种方式做到这一点。我可能会回到绘图板上,看看是否还有其他选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    相关资源
    最近更新 更多