有没有办法使用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) 

我希望这会有所帮助,如果您还有其他问题请留言,我会尽力帮助。

(或者是有办法来捕获只在中间的窗口或东西的底部?)

是的,但首先我需要知道,如果上面的方法对你的作品。如果你仍然需要这第二部分,并会尽力帮助你,请留下评论。

祝你好运!

+0

谢谢你,我修复了我的代码,但是我仍然有一个黑色的位图,没有任何可见的东西,我的函数PrintWindow在窗口句柄下工作正常,当我添加控制句柄时它不工作。 – shuji 2014-11-20 23:55:58

+0

hdc参数需要声明为hwnd我不知道为什么和在BitBlt调用之后,我的记事本编辑控件正在填充黑色。 – shuji 2014-11-21 00:16:25

+0

尝试使用以下示例将'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

最简单 - 拍摄整个窗口的快照,然后剪切图像的所需部分(例如控制)。通过PrintWindow控制黑色图像的原因之一是控件的CS_PARENTDC。

+0

我并不在乎它是否更困难,因为高分辨率显示器需要很长时间才能截取屏幕截图。如果您可以为我想听到的问题想一个解决方案,谢谢。 – shuji 2014-11-21 00:01:34

+0

也许下面的演示对你很有用(按钮“PrintWindow_M”实现我的建议):http://files.rsdn.ru/42164/printlayered.zip(http://files.rsdn.ru/42164/printlayered .JPG)。 – kero 2014-11-21 01:33:04