将另一个应用程序的窗口设置为最顶层后焦点丢失
我正在将另一个应用程序的窗口置于最顶层,以确保在我的应用程序中单击会将另一个应用程序的对话框带入视图。 我遇到的问题是,通话后我没有将焦点返回到我的应用程序。 如果另一个应用程序有更多窗口,则其中一个窗口将获得焦点,否则没有窗口(仅查看任务栏)获得焦点。 我应该从哪里开始调查这个问题?
我使另一个应用程序位于最顶层的代码是:
Process p = Process.GetProcessById(trackedProcessID);
IntPtr h = p.MainWindowHandle;
uint TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS;
SetWindowPos(h, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
常量为
public static readonly uint SWP_NOMOVE = 0x0002;
public static readonly uint SWP_NOSIZE = 0x0001;
public static readonly uint SWP_ASYNCWINDOWPOS = 0x4000;
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
I'm making another app's window topmost to ensure that a click in my app brings the other's dialog into views. The problem I'm having is that I don't get focus back to my app after the call. If the other app has more windows one of them ends up with focus, and otherwise no window (looking at the taskbar only) gets focus. Where should I start investigating the issue?
My code for making the other app topmost is:
Process p = Process.GetProcessById(trackedProcessID);
IntPtr h = p.MainWindowHandle;
uint TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE | SWP_ASYNCWINDOWPOS;
SetWindowPos(h, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
with constants as
public static readonly uint SWP_NOMOVE = 0x0002;
public static readonly uint SWP_NOSIZE = 0x0001;
public static readonly uint SWP_ASYNCWINDOWPOS = 0x4000;
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您尝试过SWP_NOACTIVATE吗?
Have you tried SWP_NOACTIVATE?
[实际使用的解决方案]
到目前为止,我将把调用窗口的窗口句柄发送到目标应用程序,并让它在完成后将其推回顶部。 这确实很痛苦,因为我要处理大约 50 个窗口,但它看起来很稳定。 如果结果出现问题,下一个方法将是回调调用应用程序并要求它将窗口推到前台,但我不想这样做,因为它引入了用户可以执行某些操作的可能性消息传输时调用应用程序(只有在同一传输协议上传入大量消息时才会出现问题,这很可能发生)
不要尝试使用传入窗口句柄并设置显示的任何窗口的父窗口在该句柄的目标应用程序中,它只会使显示的对话框出现在调用应用程序窗口的范围内,并在必要时进行裁剪 - 无用非常
感谢上述问题的答案
[Actual solution used]
So far I'm going with sending the window handle of the calling window to the target app, and getting it to push it back on top when finished. It is a real pain as I will have ~50 windows to deal with, but it seems stable. The next approach, if this turns out to have problems, will be to call back to the calling app and ask it to push the window to the foreground, but I'd rather not as it introduces a possiblity that the user can do something to the calling app while the message is in transit (only a problem if there is a lot of messages comming in on the same transport protocol, which could well happen)
Do not try to use the incoming window handle and set the parent of any window shown in the target app to that handle, it only makes the shown dialog to appear within the bounds of the calling app window, and cropped if necessary - useless
Many thanks for the answers above to the question
相关: Process.MainWindowHandle 的意外行为
基本上,MainWindowHandle 为您提供了当前最顶层的窗口不管文档怎么说。
这解释了为什么其他进程的主窗口不一定获得焦点。
您的另一个问题是因为您在放弃应用程序后没有将焦点返回到应用程序上。
实际上,您正在做的事情的正确术语是建立 z-order。
与其尝试控制 z 顺序(这是无法保证的),不如向其他进程发送消息可能会更好。
Related: Unexpected behaviour of Process.MainWindowHandle
Basically MainWindowHandle gives you the current top-most window of the process despite what the documentation says.
That explains why the main window of your other process doesn't necessarily get focus.
Your other problem is because you are not returning focus to your app after giving it away.
Actually, the correct term for what you are doing is establishing z-order.
Instead of trying to control z-order - which cannot be guaranteed - you might be better off sending messages to the other process.