确保 C# 窗体在应该获得焦点时获得焦点

Making sure that a C# form has focus when it should

我是 Visual C# 的新手,但使用 Delphi 编写代码已有很长时间了。我已经创建了一个表单,它有一个隐藏的简单面板,除非您在键盘上键入一个特定的键(我确实为表单设置了 "KeyPreview" 为 true 并且我正在使用 KeyDown 事件来处理确定是否按下了正确的键并使面板 visible/invisible)。面板正下方是一个 webBrowser 组件。

具体情况如下:

当我的表单最初启动时,我有 "Shown" 事件的代码来确保表单最初具有焦点:

private void Form1_Shown(object sender, EventArgs e)
{
    if (!Focused)
    {
        Focus();
    }
}

当窗体在此时获得焦点时,我用于检测正确击键以使面板出现或消失的代码工作正常。

这是事情变得奇怪的地方,我不确定该怎么做。我正在处理两个部分的错误:

  1. 如果我单击另一个表单,然后再次单击我的表单的标题栏以聚焦我的表单并尝试击键,则击键检测不起作用。但是,如果我单击另一个表单然后再次返回我的表单,则该表单的击键检测会起作用。我该怎么做才能确保每次我的 from 再次获得焦点时它都能正常工作?

  2. 如果我在自己的表单中单击 Web 浏览器组件,表单的 KeyDown 代码将不再生效。即使我单击窗体的标题栏,KeyDown 事件也不起作用。我需要做什么来确保,如果我的表单中的组件被单击,我的表单仍然会响应 KeyDown 事件?

提前感谢您的任何建议。

我说不出为什么你的标题栏似乎在拦截关键事件。可能是窗体上的各个组件都可以拥有焦点,从而捕获键盘事件。我知道网络浏览器控件是这样工作的。您可以考虑全局捕获键盘事件。

我在 Codeproject 上看到了有关如何执行此操作的内容。希望对您有所帮助。

他们使用 UserActivityHooks。

UserActivityHook actHook;
void MainFormLoad(object sender, System.EventArgs e)
{
   actHook= new UserActivityHook(); // crate an instance

// hang on events

   actHook.OnMouseActivity+=new MouseEventHandler(MouseMoved);
   actHook.KeyDown+=new KeyEventHandler(MyKeyDown);
   actHook.KeyPress+=new KeyPressEventHandler(MyKeyPress);
   actHook.KeyUp+=new KeyEventHandler(MyKeyUp);
}

至于webbrowser控件,当然是要拦截键盘事件了。用户通常需要在表单中输入文本,而开发人员通常会在网页上编写代码 javascript 以专门挂接到键盘事件。所以 webbrowser 控件必须能够捕获这些。