【发布时间】:2013-03-04 00:09:00
【问题描述】:
我遇到了 SetWindowPos 无法可靠地将外部进程窗口置于 z 顺序顶部的问题。我可以将窗户放在前面,例如:
NativeMethods.SetWindowPos(hwnd, new IntPtr(-1), Left, Top, Width, Height, 0x10);
NativeMethods.SetWindowPos(hwnd, new IntPtr(-2), Left, Top, Width, Height, 0x10);
不过,它并非 100% 有效。经过一番阅读,我发现了一些东西。
SetWindowPos 文档说明:
To use SetWindowPos to bring a window to the top, the process that owns the window must have SetForegroundWindow permission.
MSDN 上的一篇文章接着说
A process that is started with UIAccess rights has the following abilities:
* Set the foreground window.
AllowSetForeground 提及
The calling process must already be able to set the foreground window
我已经签署了我的 .exe 并启用了 UIAccess,以便我可以在清单中设置前台窗口:
<requestedExecutionLevel level="highestAvailable" uiAccess="true" />
我的程序启动,我收到 UAC 提示请求权限。然后我测试 UIAccess、管理员权限和 TokenElevationType。前 2 个返回 true,第 3 个返回 TokenElevationTypeFull。虽然我的新代码仍然遇到同样的问题。
我的代码是:
uint processid=0;
NativeMethods.GetWindowThreadProcessId(hwnd, out processid);
NativeMethods.AllowSetForegroundWindow((int)processid);
NativeMethods.SetWindowPos(hwnd, IntPtr.Zero, Left, Top, Width, Height, 0x10);
NativeMethods.RedrawWindow(hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RedrawWindowFlags.Erase | NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.NoChildren);
NativeMethods.RedrawWindow(hwnd, IntPtr.Zero, IntPtr.Zero, NativeMethods.RedrawWindowFlags.Erase | NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.UpdateNow | NativeMethods.RedrawWindowFlags.AllChildren);
【问题讨论】:
-
为什么你的应用需要提升,你为什么将 uiAccess 设置为 true?
-
我的程序是一个扑克自动化程序。它将需要注意的表格带到 zorder 的顶部,以便用户可以对它们进行操作。我正在使用 hack 通过将 setwindowpos 设置为 topmost 然后 nontopmost 来使其工作。不过还不够可靠。我需要一种 100% 有效的方法。我在主帖中解释了我为什么觉得我需要 UIAccess 的原因。
-
你无法找到工作。您愿意介绍一下背景吗?
-
抱歉,David 我不小心输入了我的评论。我已经更新了。