在我的表单失效之前触发的事件失去焦点

时间:2016-12-19 03:38:24

标签: c# winforms

我需要在整个表格失去焦点之前收到警报。 Deactivate事件仅在失去焦点后触发。 LostFocus和Leave仅适用于控件。

我也尝试重写WndProc,但这仅在处理完消息后触发。

重写PreProcessMessage只能用于键盘内容,而不是表单停用。

2 个答案:

答案 0 :(得分:1)

狡诈方法

即使这是一种快速而又愚蠢的方式,但改变输入语言是不自然的......

private void Form1_Deactivate(object sender, EventArgs e)
{
    ((Form)sender).Activate();
    System.Diagnostics.Debug.WriteLine(this.ActiveControl.Name);
    //Change Input Language here..

    //Alt TAB to set focus to the application selected 5 milliseconds ago
    SendKeys.SendWait("%{TAB");
}

正确和orthadox方法

How to monitor focus changes?C#: Detecting which application has focus

使用Automation framework,添加对UIAutomationClientUIAutomationTypes的引用并使用Automation.AddAutomationFocusChangedEventHandler,例如:

public class FocusMonitor
{
    public FocusMonitor()
    {
        AutomationFocusChangedEventHandler focusHandler = OnFocusChanged;
        Automation.AddAutomationFocusChangedEventHandler(focusHandler);
    }

    private void OnFocusChanged(object sender, AutomationFocusChangedEventArgs e)
    {
        AutomationElement focusedElement = sender as AutomationElement;
        if (focusedElement != null)
        {
            int processId = focusedElement.Current.ProcessId;
            using (Process process = Process.GetProcessById(processId))
            {
                Debug.WriteLine(process.ProcessName);
            }
        }
    }
}

答案 1 :(得分:0)

知道了,这个黑客完美无缺。

    private void MyForm_Deactivate(object sender, EventArgs e)
    {
        Thread.Sleep(200);  //delay to allow external tab time to open
        Form f1 = new Form();  //create a new form that will take focus, switch input, then terminate itself
        f1.Shown += new EventHandler((s, e1) => { f1.Activate();  InputLanguage.CurrentInputLanguage = InputLanguage.DefaultInputLanguage; f1.Close(); });
        f1.Show();
    }
编辑:经过进一步测试,我发现这同样不可靠。似乎没有一个好方法可以做到这一点。

目前我正在跟踪鼠标和键盘,以检测用户何时即将停用它。显然,鼠标和键盘挂钩是一个可怕的解决方案,但它是目前唯一可靠的解决方案。