问题描述
我正在尝试制作一个检测其他窗口的程序,将窗口最小化一小段时间,然后从另一个程序中使同一窗口正常。
var p = Process.GetProcessesByName("MyTargetwindow").GetFirstOrDefault();
var elem = AutomationElement.FromHandle(p.MainWindowHandle);
var pattern = elem.GetCurrentPattern(WindowPattern.Pattern) as WindowPattern;
pattern.SetwindowVisualState(WindowVisualState.Minimized);
现在我想通过另一个程序再次使窗口正常大小。
此时,如果我存储 p.MainWindowHandle
并重新使用它,我没有任何问题。
但是,如果我不这样做,并且如果我尝试按照类似的代码运行以使窗口正常,则在调用 GetCurrentPattern
时我将收到 InvalidOperationException。 (我了解新手柄不支持Pattern)
var p = Process.GetProcessesByName("MyTargetwindow").GetFirstOrDefault();
var elem = AutomationElement.FromHandle(p.MainWindowHandle);
var pattern = elem.GetCurrentPattern(WindowPattern.Pattern) as WindowPattern; // InvalidOperationException
pattern.SetwindowVisualState(WindowVisualState.normal);
原因很简单,第二个代码中的p.MainWindowHandle
与原来的窗口不同。
问题是为什么 p.MainWindowHandle
不同?
最终,如何在不将句柄存储在变量中的情况下重新检索相同的句柄
编辑:
如果 IntPtr 存储是强制性的,我别无选择,只能将它作为字符串存储在磁盘上,然后通过 new IntPtr(Convert.ToInt32) 重新检索它,我希望会有其他解决方案。
编辑2:
存储 IntPtr 对我来说仍然有问题。最终,我可以将它存储到注册表并读取它,但我还必须跟踪句柄何时存储到注册表。它变得比我想要的更复杂。
我真的很希望有一种方法可以不存储 IntPtr 并且仍然找到正确的句柄。
解决方法
“主窗口是当前具有焦点的进程打开的窗口(TopLevel 窗体)。”但是最小化的窗口不再具有焦点。
在其上保存 IntPtr
和 P/Invoke ShowWindow()
。一个简单得多的提议;当你已经可以做到这一点时,没有必要搞乱自动化等。
我不建议在本机代码中重新实现整个“查找窗口句柄”之类的东西的原因是它不会稳定,因为其他进程可以在两次之间创建/销毁窗口,因此您不会无论您做什么,都能可靠地再次抓取同一个窗口。