我可以得到一位的任意一个窗口,在另一个应用程序的过程?
-
26-09-2019 - |
题
我试图自动第三方Win32应用程序,在那里我想要捕获的图形内容的一个特别窗口在规定的时间间隔。我在早期阶段如此,我目前正试图使用 Microsoft UI自动化 API通过C#做的大多数之间的相互作用我的客户应用程序和外部应用程序。我现在可以得到外部应用程序做什么我想要它做的,但是现在我想要捕获的图形,从一个具体的窗口,这似乎是某些第三方所有人绘的控制。我怎么可以这样做?窗户我想捕捉是一个标志着红色的长方形,在这个图象:
我有一个执行这种工作,但它依赖于外部应用程序的用户界面上顶上,这不能保证我,所以我想找一些更一般性。
var p = Process.Start("c:\myapp.exe");
var mainForm = AutomationElement.FromHandle(p.MainWindowHandle);
// "workspace" below is the window whose content I want to capture.
var workspace = mainForm.FindFirst(TreeScope.Descendents,
new PropertyCondition(AutomationElement.ClassNameProperty, "AfxFrameOrView70u"));
var rect = (Rect) workspace.GetCurrentPropertyValue(AutomationElement.BoundingRectangleProperty);
using (var bmp = new Bitmap((int)rect.Width, (int)rect.Height))
{
using (var g = Graphics.FromImage(bmp))
{
g.CopyFromScreen((int)rect.Left, (int)rect.Top, 0, 0, new Size((int)rect.Width, (int)rect.Height));
bmp.Save(@"c:\screenshot.png", ImageFormat.Png);
}
}
上述工作以及足够的时的自动化应用程序是在最前面,但它只是盲目地将屏幕中的矩形,所以在我的代码是怜悯无论发生什么事情上运行的机器,可能掩盖我的应用程序的窗口。
我读过一些建议发送的 WM_PRINT
消息窗口。此 提问/答复 从几个月后似乎有希望,但当我用这个代码,我刚得到一个白色的长方形没有我的控制的实际内容。
var prop = (int)workspace.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty);
var hwnd = new IntPtr(prop);
using ( var bmp2 = new Bitmap((int)rect.Width, (int)rect.Height))
{
using (Graphics g = Graphics.FromImage(bmp2))
{
g.FillRectangle(SystemBrushes.Control, 0, 0, (int)rect.Width, (int)rect.Height);
try
{
SendMessage(hwnd, WM_PRINT, g.GetHdc().ToInt32(), (int)(DrawingOptions.PRF_CHILDREN | DrawingOptions.PRF_CLIENT | DrawingOptions.PRF_OWNED));
}
finally
{
g.ReleaseHdc();
}
bmp2.Save(@"c:\screenshot.bmp");
}
}
因此,首先,它甚至可能对我来说,可靠地保存一位图的一个窗口的内容吗?如果是这样,什么是最好的方式,和什么是错的我 WM_PRINT
与 SendMessage
尝试?
解决方案
这种修改的 PrintWindow
API例 在pinvoke.net 网站似乎已经完成的伎俩。
Bitmap bmp = new Bitmap((int)rect.Width, (int)rect.Height);
Graphics memoryGraphics = Graphics.FromImage(bmp);
IntPtr dc = memoryGraphics.GetHdc();
bool success = PrintWindow(hwnd, dc, 0);
memoryGraphics.ReleaseHdc(dc);
bmp.Save(@"c:\screenshot.bmp");
这个工作,如果该程序是所涵盖的另一个窗口,但是它不工作,如果该程序是最小化。我想我可以住这一点。
其他提示
有没有 可靠的 的方式来获得一位来自一个不同的应用程序,如果这一程序是不是在顶部。这是因为该应用程序的控制甚至不渲染,如果该程序是不可见的,窗户不一定还记得什么样的最后已知内容的控制之后,控制失去最顶层的位置在z-顺序。
你最好的赌注是移动的目标应用以前的z-order的时候,你需要采取的截图,然后选择恢复原来的z-以后拍摄的图像。