我有一小段脚本,但当我使用 PrintWindow 时,它只返回黑色捕获:
PrintWindow() 对于窗口句柄可以正常工作,但不能与控制句柄一起工作。
(或者有没有办法只捕获窗口的底部或中间的部分,而不需要捕获整个窗口并剪切它?)
AutoIt 脚本:
Local $hWnd = ControlGetHandle("[CLASS:Notepad]","","Edit1")
Local $pos = ControlGetPos($hWnd,"","")
;MsgBox($MB_OK, "OK", $pos[0])
Local $Width = $pos[2]
Local $Height = $pos[3]
Local $hDC = _WinAPI_GetDC($hWnd)
Local $memDC = _WinAPI_CreateCompatibleDC($hDC)
Local $memBmp = _WinAPI_CreateCompatibleBitmap($hDC, $Width, $Height)
_WinAPI_SelectObject ($memDC, $memBmp)
;DllCall("User32.dll","int","PrintWindow","hwnd",$hWnd,"hwnd",$memDC,"int",0)
;_WinAPI_BitBlt($hDC, 0, 0, $Width, $Height, $memDC, 0,0, $SRCCOPY)
_WinAPI_BitBlt($memDC, 0, 0, $Width, $Height, $hDC, 0,0, $SRCCOPY) ;this is working now!
_GDIPlus_Startup()
Local $hBMP=_GDIPlus_BitmapCreateFromHBITMAP($memBmp)
Local $hHBITMAP=_GDIPlus_BitmapCreateHBITMAPFromBitmap($hBMP)
_WinAPI_DeleteObject($hDC)
_WinAPI_ReleaseDC($hWnd, $hDC)
_WinAPI_DeleteDC($memDC)
_WinAPI_DeleteObject ($memBmp)
_WinAPI_DeleteDC($hDC)
$sPath = @ScriptDir & '\capture.bmp'
_WinAPI_SaveHBITMAPToFile($sPath, $hHBITMAP)
最佳答案
I have this little piece of script but when I use PrintWindow it's only returning a black capture:
首先,我不知道您使用的语言,但是您的代码和问题足够清晰,我可以尝试提供解决方案。
马上,在我看来,PrintWindow
的第二个参数是错误的(它是 HWND
但它应该是 HDC
)。
其次,您的代码中存在 GDI 泄漏,但我已更正它 -> 请参阅代码中的评论。长话短说,每次您SelectObject
将某些内容放入设备上下文时,您都会“推出”在该选择之前“站在那里”的原始对象。必须保存该原始对象并“放回”。如果没有,那么您的内存将随着时间的推移而耗尽,并且您的应用程序将卡住。只需 Google 搜索“GDI 泄漏”,您就会找到我所描述内容的详细解释。
第三,当然你会捕获黑色,因为你的初始 HDC 是空的 -> 你需要将 memDC
的内容传输到 hDC
中。为此,您需要使用 BitBlt功能。正如我所说,我不知道您使用的语言,但我尝试在下图中为您提供伪代码,以便您可以了解该怎么做。
Local $hWnd = ControlGetHandle("[CLASS:Notepad]","","Edit1")
Local $pos = ControlGetPos($hWnd,"","")
;MsgBox($MB_OK, "OK", $pos[0])
Local $Width = $pos[2]
Local $Height = $pos[3]
Local $hDC = _WinAPI_GetDC($hWnd)
Local $memDC = _WinAPI_CreateCompatibleDC($hDC)
Local $memBmp = _WinAPI_CreateCompatibleBitmap($hDC, $Width, $Height)
Local $bmpOriginal = _WinAPI_SelectObject ($memDC, $memBmp) ;store original DC bitmap
DllCall("User32.dll","int","PrintWindow","hwnd",$hWnd,
"hdc", ; I think this is an error, this parameter is of type HDC
$memDC,"int",0)
DllCall("User32.dll","int","BitBlt", "hdc", memDC,
... , ; fill in the rest of parameters
"hdc" , hDC,
... ) ; fill in the rest of parameters. Your last parameter should be SRCCOPY!
; when done with the DC, first select back the original bitmap
_WinAPI_SelectObject( $memDC, $bmpOriginal )
; now we can delete memory bitmap since it is no longer needed
_WinAPI_DeleteObject( $memBmp )
; delete memory DC since we performed proper cleanup
_WinAPI_DeleteDC( $memDC )
; release window's DC
_WinAPI_ReleaseDC( $hwnd, $hDC )
希望这对您有所帮助,如果您还有其他问题,请发表评论,我会尽力提供帮助。
(Or is there a way to capture only the bottom part of the window or something in the middle?)
是的,但首先我需要知道上述方法是否适合您。如果您仍然需要第二部分,请发表评论,我们会尽力帮助您。
致以诚挚的问候,祝你好运!
关于winapi - 有没有办法将 PrintWindow 与控件一起使用? (使用 AutoIt),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27045876/