我在完全理解 AttachThreadInput 时遇到了一点问题。
我知道它正在“连接”2个线程的消息队列,这(我想做的)允许我例如强制我的窗口(winforms)在前台。
我可以用这种方法做:
private void SetForegroundWindowEx(IntPtr hWnd)
{
uint SW_SHOW = 5;
uint appThread = GetCurrentThreadId();
uint foregroundThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
if (foregroundThread != appThread)
{
AttachThreadInput(foregroundThread, appThread, true);
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
AttachThreadInput(foregroundThread, appThread, false);
}
else
{
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
}
}
然而,一旦线程分离,两个窗口都会失去焦点。
如果我等待消息队列清空(Application.DoEvents())并激活我的窗口(现在处于前台但未聚焦),它将重新获得焦点并保留它。
如果我在消息队列为空之前这样做,它将再次失去焦点。
所以我猜想分离的一些东西把焦点从我的窗户上移开了,但我不知道那是什么或如何防止它。
这是我不太明白的第一件事。
我没有得到的第二件事是,如果我没有将窗口设置为前景:
AttachThreadInput(foregroundThread, appThread, true);
AttachThreadInput(foregroundThread, appThread, false);
Application.DoEvents();
this.Activate();
等待消息队列清空,然后激活我的窗口(这次它不在前台,另一个窗口仍然具有焦点),它实际上被激活了,即使线程不再附加。
也许对 AttachThreadInput 有更好理解的人可以回答我这两个问题。
信息:
在这种情况下,我需要窃取焦点,因为我的应用程序是通过 API 调用的。另一个调用我的应用程序,等待来自我的应用程序的反馈,并且在大多数情况下冻结,直到它获得信息。
如果另一个应用程序是全屏的,许多用户不会注意到任务栏中的闪烁,并认为另一个应用程序崩溃并使用 Taskmamanger 将其杀死。由于我不一定可以控制其他应用程序,因此我不能告诉它将焦点设置到我的窗口。
如果不是绝对必要,则不会调用此方法,在这种情况下,我知道这种敌对行为是我自己和用户都想要的。