我试图自动第三方Win32应用程序,在那里我想要捕获的图形内容的一个特别窗口在规定的时间间隔。我在早期阶段如此,我目前正试图使用 Microsoft UI自动化 API通过C#做的大多数之间的相互作用我的客户应用程序和外部应用程序。我现在可以得到外部应用程序做什么我想要它做的,但是现在我想要捕获的图形,从一个具体的窗口,这似乎是某些第三方所有人绘的控制。我怎么可以这样做?窗户我想捕捉是一个标志着红色的长方形,在这个图象:

I need what's in the red rectangle

我有一个执行这种工作,但它依赖于外部应用程序的用户界面上顶上,这不能保证我,所以我想找一些更一般性。

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_PRINTSendMessage 尝试?

有帮助吗?

解决方案

这种修改的 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-以后拍摄的图像。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top