有没有办法使用PrintWindow和控件? (使用的AutoIt)
我有这个小片剧本的,但是当我在使用PrintWindow它只有返回一个黑色的捕获:有没有办法使用PrintWindow和控件? (使用的AutoIt)
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)
我有这个小片剧本的,但是当我在使用PrintWindow它只有返回一个黑色的捕获:
首先,我不知道你使用的语言,但你的代码的问题是足以让我尝试提供解决方案。
马上蝙蝠,在我看来,你的第二个参数为PrintWindow
是错误的(它是HWND
,但它应该是HDC
)。
其次,您的代码中存在GDI泄漏,但我已更正它 - >在代码中查看我的评论。长话短说,每次你在设备上下文中,你都会在选择之前“推出”“站在那里”的原始对象。该原始对象必须保存并“放回”。如果没有,那么随着时间的推移,你的记忆将被耗尽,你的应用程序将冻结。只是谷歌的“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)
我希望这会有所帮助,如果您还有其他问题请留言,我会尽力帮助。
(或者是有办法来捕获只在中间的窗口或东西的底部?)
是的,但首先我需要知道,如果上面的方法对你的作品。如果你仍然需要这第二部分,并会尽力帮助你,请留下评论。
祝你好运!
最简单 - 拍摄整个窗口的快照,然后剪切图像的所需部分(例如控制)。通过PrintWindow控制黑色图像的原因之一是控件的CS_PARENTDC。
谢谢你,我修复了我的代码,但是我仍然有一个黑色的位图,没有任何可见的东西,我的函数PrintWindow在窗口句柄下工作正常,当我添加控制句柄时它不工作。 – shuji 2014-11-20 23:55:58
hdc参数需要声明为hwnd我不知道为什么和在BitBlt调用之后,我的记事本编辑控件正在填充黑色。 – shuji 2014-11-21 00:16:25
尝试使用以下示例将'memBmp'呈现为文件:[this](http://msdn.microsoft.com/en-us/library/windows/desktop/dd145119(v = vs.85).aspx )和[this](http://msdn.microsoft.com/en-us/library/windows/desktop/dd183402(v = vs.85).aspx)。简单的“Result.bmp”就足够了,只要确保扩展名是'.bmp'!这会告诉我们'PrintWindow'是否运行良好,因为我怀疑编辑控件可能是问题所在...... – AlwaysLearningNewStuff 2014-11-21 01:03:36