场景I有我的主要应用程序,它最初是用Borland C++编写的,正在由C# .Net应用程序启动。这个主应用程序偶尔会从一个名为BRWSEXE的进程中打开一个模态对话框。在弹出一个模态对话框窗口后,您可能会意外地单击主应用程序中的某个位置(而不是对话框上),导致焦点简短地切换到主应用程序,然后以Z顺序发送其后面的模态对话框。但是您实际上不能对主应用程序执行任何操作,它会被该模式对话框窗口锁定,该窗口必须先关闭,然后才能继续。
问题使用启动所有内容的.net应用程序,我可以查找与主应用程序相关的BRWSEXE实例,并将它们强制放到前台。到目前为止,我测试过的所有地方(Windows、Windows7、Windows 2003 R2)都能完美地使用这种策略,但它在Windows 2008上不起作用。因此,据我所知,我的代码工作在fine...but环境中的东西正在抛出它。
我的代码
[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);
}
}
}
}发布于 2012-01-02 16:06:15
您的AttachThreadInput声明完全错误。它返回bool,参数为uint。如果使用不当,则应该传递线程ID,而不是窗口句柄。你需要GetWindowThreadProcessId()。
而且你根本没有检查错误,所以很明显你不能诊断故障。属性所需的SetLastError属性,使用Marshal.GetLastWin32Error()检索错误。使用pinvoke.net进行更好的pinvoke声明。
发布于 2012-01-02 16:01:30
我使用过SwitchToThisWindow(),尽管MSDN说它可以在未来版本的Windows中删除,但它仍然适用于我。
https://stackoverflow.com/questions/8702800
复制相似问题