如何在我的表单后面制作 Window 的屏幕截图?

How can I make a screen shot of a Window behind my Form?

我的应用程序在 Google Chrome Window 前面运行。 chrome window 的右侧四分之一始终可见,因为我可能需要与之交互。 chrome window 的左侧完全被覆盖,因为这是我的控件所在的位置。

麻烦的是,Chrome Window 左侧有几项可能会不时更改,我需要知道何时会发生这种情况。在我的表格上制作透明区域看起来真的很乱,所以我需要做的是每隔几秒钟在我的表格后面拍摄 chrome window 的图形,这样我就可以检查是否有任何差异。

我发现了许多使用 bitblt 等的代码示例,但到目前为止,我得到的都是纯黑色。没有任何图像返回。那么如何才能拍出ChromeWindow的图呢?

如果有人可以提供 returns 来自 hwnd 的位图的功能,那就太棒了!

好吧,试试PrintWindow

此函数发出 WM_PRINTWM_PRINTCLIENT 消息(取决于指定的标志),因此接收和处理消息的 Window 将自身打印到 hDC 传入函数调用。
► Window 可以完全被另一个遮住,没关系,不是截图。不过 Window 必须处理消息。


此处显示的是静态(Shared)RenderWindow方法,return是PrintWindow函数生成的Bitmap对象.

您应该尝试将 True 作为 clientAreaOnly 参数传递,以将 PW_CLIENTONLY 设置为 nFlags 选项,因为许多 WPF 应用程序旨在隐藏默认值Window 框架,而 WinForms Windows 通常不会,所以在这种情况下尝试通过 False

可选的 tryGetFullContent 参数设置 PW_RENDERFULLCONTENT 标志,可从 Windows 8.1+ 获得。此标志未记录。
更新:在这种情况下,这是完成工作的原因。

要得到你关心的Window的句柄,你有很多选择。

Process.GetProcessesByName("processName").FirstOrDefault(...)Process.GetProcessById(id),如果您知道进程 ID。

FindWindowEx, or EnumWindows, or EnumDesktopWindows,视情况而定。
请参阅此处: 了解 FindWindowEx 函数的简单用法。

假设您有一个 WinForms 应用程序,您可以像这样调用方法,以在 PictureBox 中显示呈现的 Window 的位图:

Dim proc = Process.GetProcessesByName("WINWORD").FirstOrDefault(Function(p) p.MainWindowHandle <> IntPtr.Zero)
If proc IsNot Nothing Then
    PictureBox1.Image = RenderWindow(proc.MainWindowHandle, True)
End If

RenderWindow 方法的 Win32 声明和实现:

► 在这里,我使用 DwmGetWindowAttribute,指定 DWMWA_EXTENDED_FRAME_BOUNDS 作为属性,以检索 Window 矩形。
您也可以使用 GetWindowRect,但此功能不是 DpiAware(并且有点旧 :),在特定条件下可能 return 大小错误。

Public Shared Function RenderWindow(hWnd As IntPtr, clientAreaOnly As Boolean, Optional tryGetFullContent As Boolean = False) As Bitmap
    Dim printOption = If(clientAreaOnly, PrintWindowOptions.PW_CLIENTONLY, PrintWindowOptions.PW_DEFAULT)
    printOption = If(tryGetFullContent, PrintWindowOptions.PW_RENDERFULLCONTENT, printOption)

    Dim dwmRect = New Rectangle()
    Dim hResult = DwmGetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, dwmRect, Marshal.SizeOf(Of Rectangle)())
    If hResult < 0 Then
        Marshal.ThrowExceptionForHR(hResult)
        Return Nothing
    End If

    Dim bmp = New Bitmap(dwmRect.Width, dwmRect.Height)
    Using g = Graphics.FromImage(bmp)
        Dim hDC = g.GetHdc()

        Try
            Dim success = PrintWindow(hWnd, hDC, printOption)
            ' success result not fully handled here
            If Not success Then
                Dim win32Error = Marshal.GetLastWin32Error()
                Return Nothing
            End If
            Return bmp
        Finally
            g.ReleaseHdc(hDC)
        End Try

    End Using
End Function

本机方法:

<DllImport("user32.dll", SetLastError:=True)>
Friend Shared Function PrintWindow(hwnd As IntPtr, hDC As IntPtr, nFlags As UInteger) As Boolean
End Function

<DllImport("dwmapi.dll", SetLastError:=True)>
Friend Shared Function DwmGetWindowAttribute(hwnd As IntPtr, dwAttribute As DWMWINDOWATTRIBUTE, ByRef pvAttribute As Rectangle, cbAttribute As Integer) As Integer
End Function

Public Enum DWMWINDOWATTRIBUTE As UInteger
    DWMWA_NCRENDERING_ENABLED = 1      ' [get] Is non-client rendering enabled/disabled
    DWMWA_NCRENDERING_POLICY           ' [set] DWMNCRENDERINGPOLICY - Non-client rendering policy
    DWMWA_TRANSITIONS_FORCEDISABLED    ' [set] Potentially enable/forcibly disable transitions
    DWMWA_ALLOW_NCPAINT                ' [set] Allow contents rendered In the non-client area To be visible On the DWM-drawn frame.
    DWMWA_CAPTION_BUTTON_BOUNDS        ' [get] Bounds Of the caption button area In window-relative space.
    DWMWA_NONCLIENT_RTL_LAYOUT         ' [set] Is non-client content RTL mirrored
    DWMWA_FORCE_ICONIC_REPRESENTATION  ' [set] Force this window To display iconic thumbnails.
    DWMWA_FLIP3D_POLICY                ' [set] Designates how Flip3D will treat the window.
    DWMWA_EXTENDED_FRAME_BOUNDS        ' [get] Gets the extended frame bounds rectangle In screen space
    DWMWA_HAS_ICONIC_BITMAP            ' [set] Indicates an available bitmap When there Is no better thumbnail representation.
    DWMWA_DISALLOW_PEEK                ' [set] Don't invoke Peek on the window.
    DWMWA_EXCLUDED_FROM_PEEK           ' [set] LivePreview exclusion information
    DWMWA_CLOAK                        ' [set] Cloak Or uncloak the window
    DWMWA_CLOAKED                      ' [get] Gets the cloaked state Of the window
    DWMWA_FREEZE_REPRESENTATION        ' [set] BOOL, Force this window To freeze the thumbnail without live update
    DWMWA_LAST
End Enum

Public Enum PrintWindowOptions As UInteger
    PW_DEFAULT = 0
    PW_CLIENTONLY = 1
    PW_RENDERFULLCONTENT = 2
End Enum