我的应用程序在 Google Chrome 窗口前运行。 Chrome 窗口的右侧四分之一始终可见,因为我可能需要与其交互。 Chrome 窗口的左侧被完全覆盖,因为这是我的控件所在的位置。
问题是,Chrome 窗口左侧有一些内容可能会不时发生变化,我需要知道这种情况何时发生。在我的表单上创建透明区域看起来真的很困惑,所以我需要做的是每隔几秒拍摄一张表单后面的 Chrome 窗口的图形,这样我就可以检查是否有任何差异。
我发现了许多使用 bitblt
等的代码示例,但到目前为止我得到的只是纯黑色。没有任何东西返回任何图像。那么如何拍摄 Chrome 窗口的图形呢?
如果有人可以提供一个从 hwnd
返回位图的函数,那就太棒了!
最佳答案
好吧,尝试一下PrintWindow
。
此函数发出 WM_PRINT
或 WM_PRINTCLIENT
消息(取决于指定的标志),因此接收和处理该消息的窗口将其自身打印到 hDC
传入函数调用。
► 窗口可以被另一个窗口完全遮挡,没关系,这不是屏幕截图。不过,窗口必须处理该消息。
此处显示的静态(Shared
)RenderWindow
方法返回由 PrintWindow 生成的 Bitmap 对象。功能。
您应该尝试将 True
作为 clientAreaOnly
参数传递,以将 PW_CLIENTONLY
设置为 nFlags
选项,因为许多 WPF 应用程序设计为隐藏默认窗口框架,而 WinForms Windows 通常不会,因此在这种情况下尝试传递 False
。
可选的 tryGetFullContent
参数设置 PW_RENDERFULLCONTENT
标志,该标志在 Windows 8.1+ 中可用。该标志没有记录。
更新:在这种情况下,这就是完成工作的原因。
要获得您关心的窗口的句柄,您有很多选择。
Process.GetProcessesByName("processName").FirstOrDefault(...)
或 Process.GetProcessById(id)
(如果您知道进程 ID)。
或者FindWindowEx ,或EnumWindows ,或EnumDesktopWindows ,取决于上下文。
参见这里:How to obtain task bar Notification Area width简单使用 FindWindowEx
函数。
假设您有一个 WinForms 应用程序,您可以调用如下方法,以在 PictureBox 中显示渲染窗口的位图:
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
Win32 RenderWindow 方法的声明和实现:
► 在这里,我使用 DwmGetWindowAttribute ,指定 DWMWA_EXTENDED_FRAME_BOUNDS
作为属性,以检索窗口矩形。
您还可以使用GetWindowRect ,但这个函数不是 DpiAware(而且有点旧:),在特定条件下它可能会返回错误的大小。
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
native 方法:
<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
关于vb.net - 如何制作表单后面窗口的屏幕截图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65315020/