我需要在整个表格失去焦点之前收到警报。 Deactivate事件仅在失去焦点后触发。 LostFocus和Leave仅适用于控件。
我也尝试重写WndProc,但这仅在处理完消息后触发。
重写PreProcessMessage只能用于键盘内容,而不是表单停用。
答案 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,添加对UIAutomationClient
和UIAutomationTypes
的引用并使用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();
}
编辑:经过进一步测试,我发现这同样不可靠。似乎没有一个好方法可以做到这一点。
目前我正在跟踪鼠标和键盘,以检测用户何时即将停用它。显然,鼠标和键盘挂钩是一个可怕的解决方案,但它是目前唯一可靠的解决方案。