情景
我的主要应用程序最初是在Borland C++中编写的,它是由c*.net应用程序启动的。此主应用程序偶尔会从名为brwsexe的进程中打开一个模式对话框。弹出模式对话框窗口后,您可能会意外地单击主应用程序中的某个位置(不在对话框上),导致焦点短暂更改为主应用程序,并按z顺序在其后面发送模式对话框。但是您实际上无法在主应用程序上执行任何操作,它被模式对话框窗口锁定,必须先关闭该窗口,然后才能继续。
问题
使用启动所有内容的.NET应用程序,我可以查找与主应用程序相关的brwsexe实例,并将其强制放到前台。到目前为止,这种策略在我测试过的所有地方(WindowsXP、Windows7、WindowsServer2003R2)都能完美地工作,但在WindowsServer2008上不起作用。据我所知,我的代码运行得很好……但那个环境中的某些东西正在抛弃它。
我的密码
[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
static extern IntPtr AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach);
private void PushBRWSEXEToFront()
{
//Make sure MyApplication is running
if (Process.GetProcessesByName("MyApplicationName").Length == 1)
{
Process[] brwsProc = Process.GetProcessesByName("BRWSEXE"); //Locate any processes for the browse dialog windows
for (int x = brwsProc.Length - 1; x > -1; x--)
{
//Make sure the browse window we are looking at is associated with the active program we are looking at
if (brwsProc[x].SessionId == Process.GetCurrentProcess().SessionId
|| brwsProc[x].SessionId == Process.GetProcessesByName("MyApplicationName")[0].SessionId)
{
//attach to the main applications thread
AttachThreadInput(brwsProc[x].MainWindowHandle, Process.GetProcessesByName("MyApplicationName")[0].MainWindowHandle, true);
//Call Set foreground window to push the browse window in front of the rest of the program.
SetForegroundWindow(brwsProc[x].MainWindowHandle);
//Detach from the main thread
AttachThreadInput(brwsProc[x].MainWindowHandle, Process.GetProcessesByName("MyApplicationName")[0].MainWindowHandle, false);
}
}
}
}
最佳答案
你的声明完全错误。它返回AttachThreadInput
,参数是bool
。你用错了,你应该传递线程id,而不是窗口句柄。你需要uint
。
而且你根本没有检查错误,所以你显然无法诊断故障。GetWindowThreadProcessId()
属性必需,使用SetLastError
检索错误。使用pinvoke.net获得更好的pinvoke声明。
关于c# - Windows Server 2008上的SetForegroundWindow失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8702800/