Что нового

скриншот неактивного окна по координатам

running-frag

why me?
Сообщения
441
Репутация
60
Есть код
Код:
;coded by UEZ 2012
#include <Array.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>


$aWinlist = GetAllWindow()

For $i = 0 To UBound($aWinlist) - 1
    $hWnd = $aWinlist[$i][1]
    If Not WinActive($hWnd) Then ExitLoop
Next
If $i = UBound($aWinlist) Then Exit MsgBox(0, "Info", "No inactive window found", 10)

_GDIPlus_Startup()
$hBitmap = Capture_Window($hWnd, 300, 200)
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Test.jpg")
_GDIPlus_BitmapDispose($hBitmap)
ShellExecute(@ScriptDir & "\Test.jpg")
_GDIPlus_Shutdown()
Exit

Func Capture_Window($hWnd, $w, $h)
    Local $hDC_Capture = _WinAPI_GetWindowDC($hWnd)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local $hObject = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)
    _WinAPI_DeleteDC($hMemDC)
    Local $hObject = _WinAPI_SelectObject($hMemDC, $hObject)
    _WinAPI_ReleaseDC($hWnd, $hDC_Capture)
    Local $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    Return $hBmp
EndFunc   ;==>Capture_Window

Func GetAllWindow() ;code by Authenticity - modified by UEZ
    Local $aWin = WinList(), $aWindows[1][4]
    Local $iStyle, $iEx_Style, $iCounter = 0
    Local $i, $hWnd_state, $aWinPos

    For $i = 1 To $aWin[0][0]
        $iEx_Style = BitAND(_WinAPI_GetWindowLong($aWin[$i][1], $GWL_EXSTYLE), $WS_EX_TOOLWINDOW)
        $iStyle = BitAND(WinGetState($aWin[$i][1]), 2)
        If $iEx_Style <> -1 And Not $iEx_Style And $iStyle Then
            $aWinPos = WinGetPos($aWin[$i][1])
            If $aWinPos[2] > 1 And $aWinPos[3] > 1 Then
                $aWindows[$iCounter][0] = $aWin[$i][0]
                $aWindows[$iCounter][1] = $aWin[$i][1]
                $aWindows[$iCounter][2] = $aWinPos[2]
                $aWindows[$iCounter][3] = $aWinPos[3]
                $iCounter += 1
            EndIf
            ReDim $aWindows[$iCounter + 1][4]
        EndIf
    Next
    ReDim $aWindows[$iCounter][4]
    Return $aWindows
EndFunc   ;==>GetAllWindow

Взят с http://www.autoitscript.com/forum/topic/140948-screenshot-to-a-incative-window/

Подскажите как ему приделать координаты? Ну т.е. хочется получить "участок" окна а не "отсчёт с нуля + ширина\высота".
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Код:
#include <GDIPlus.au3>


$iHandle = WinGetHandle('[CLASS:tSkMainForm]')
$iPos = WinGetPos($iHandle)

_GDIPlus_Startup()
$hBitmap = Capture_Window($iHandle, $iPos[2], $iPos[3])
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Test.jpg")
_GDIPlus_BitmapDispose($hBitmap)
ShellExecute(@ScriptDir & "\Test.jpg")
_GDIPlus_Shutdown()

Func Capture_Window($hWnd, $w, $h)
    Local $hDC_Capture = _WinAPI_GetWindowDC($hWnd)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local $hObj = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)
    _WinAPI_DeleteDC($hMemDC)
    Local $hObject = _WinAPI_SelectObject($hMemDC, $hObj)
    _WinAPI_ReleaseDC($hWnd, $hDC_Capture)
    Local $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    Return $hBmp
EndFunc
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Viktor1703
Ммм, "участок" в смысле хочется функция типа
Код:
Capture_Window ($iHandle, $iX, $iY, $iW, $iH)

Т.е. нужно только от точки отсчёта $iX, $iY небольшая часть на ширину и высоту ($iW, $iH)
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
С помощью

Код:
DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)


не получится, но получится через

Код:
_WinAPI_BitBlt()


Но при этом окно должно быть активно и не выходить за рамки видимости


Добавлено:
Сообщение автоматически объединено:

Код:
#include <GDIPlus.au3>
#include <WinAPIEx.au3>
#include <APIConstants.au3>

$iHandle = WinGetHandle('[CLASS:tSkMainForm]')

_GDIPlus_Startup()
$hBitmap = Capture_Window($iHandle, 30, 30, 100, 100)
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Test.jpg")
_GDIPlus_BitmapDispose($hBitmap)
ShellExecute(@ScriptDir & "\Test.jpg")
_GDIPlus_Shutdown()

Func Capture_Window($hWnd, $l, $t, $w, $h)
    Local $hDC_Capture = _WinAPI_GetWindowDC($hWnd)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    Local $hObj = _WinAPI_SelectObject($hMemDC, $hHBitmap)
	_WinAPI_BitBlt($hMemDC, 0, 0, $w, $h, $hDC_Capture, $l, $t, $SRCCOPY)
    _WinAPI_DeleteDC($hMemDC)
    Local $hObject = _WinAPI_SelectObject($hMemDC, $hObj)
    _WinAPI_ReleaseDC($hWnd, $hDC_Capture)
    Local $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
    _WinAPI_DeleteObject($hHBitmap)
    Return $hBmp
 EndFunc
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Код:
Func _getScreenImage ($sTitle, $iX = 0, $iY = 0, $iW = 100, $iH = 100)
	Local $hWND = 	WinGetHandle 	($sTitle)
					;WinActivate 	($sTitle)
					;WinWaitActive 	($sTitle)
					
					_GDIPlus_StartUp ()

	Local $hGDC = 	_WinAPI_GetWindowDC ($hWND)
	Local $hCDC = 	_WinAPI_CreateCompatibleDC ($hGDC)
	Local $hBMP = 	_WinAPI_CreateCompatibleBitmap ($hGDC, $iW, $iH)
					_WinAPI_SelectObject ($hCDC, $hBMP)
					_WinAPI_BitBlt ($hCDC, 0, 0, $iW, $iH, $hGDC, $iX, $iY, $SRCCOPY)
	
	Local $hIMG = 	_GDIPlus_BitmapCreateFromHBITMAP ($hBMP)
					_GDIPlus_ImageSaveToFile ($hIMG, "screen.bmp")
					_GDIPlus_ImageDispose ($hIMG)
					
					_WinAPI_ReleaseDC ($hWND, $hGDC)
					_WinAPI_DeleteDC ($hCDC)
					_WinAPI_DeleteObject ($hBMP)

					_GDIPlus_ShutDown()
EndFunc
Такой вариант я знаю.

А нельзя "порезать" ту картинку что получилось и достать из неё нужную часть? Или это будет не рационально?
 

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Сделал, щас только доведу до ума и выложу


Добавлено:
Сообщение автоматически объединено:

Код:
#include <GDIPlus.au3>
#include <WinAPIEx.au3>
#include <APIConstants.au3>

$iHandle = WinGetHandle('[CLASS:tSkMainForm]')

_GDIPlus_Startup()
$hBitmap = Capture_Window($iHandle, 30, 100, 200, 200)
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Test.jpg")
_GDIPlus_BitmapDispose($hBitmap)
ShellExecute(@ScriptDir & "\Test.jpg")
_GDIPlus_Shutdown()

Func Capture_Window($hWnd, $l, $t, $w, $h)
    Local $hDC_Capture = _WinAPI_GetWindowDC($hWnd)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
    Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, _WinAPI_GetWindowWidth($hWnd), _WinAPI_GetWindowHeight($hWnd))
    Local $hObj = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)
	Local $hSrcDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
	$hCompatible = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $w, $h)
    $hObj2 = _WinAPI_SelectObject($hSrcDC, $hCompatible)
	_WinAPI_BitBlt($hSrcDC, 0, 0, $w, $h, $hMemDC, $l, $t, $SRCCOPY)
    _WinAPI_DeleteDC($hMemDC)
	_WinAPI_DeleteDC($hSrcDC)
    _WinAPI_SelectObject($hMemDC, $hObj)
	_WinAPI_SelectObject($hSrcDC, $hObj2)
    _WinAPI_ReleaseDC($hWnd, $hDC_Capture)
    Local $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hCompatible)
    _WinAPI_DeleteObject($hHBitmap)
    Return $hBmp
 EndFunc


Если тут что не так и есть утечки, то я не сильно разбираюсь в контекстах, сильно не ругать :smile:
 
Автор
R

running-frag

why me?
Сообщения
441
Репутация
60
Ещё ньюанс. А как сменить точку отсчёта для скрина? Сейчас захватывает с "края рамки". Т.е. рамка присутсвует на скрине. А можно как то без неё?

Ну по принцепу Opt ("PixelCoordMode", 2).
 

eysh

Новичок
Сообщения
16
Репутация
1
Почему в Windows 8.1 и Windows 10 делает черные скрины, через раз?

Код:
#include <GDIPlus.au3>
#include <WinAPIEx.au3>
#include <APIConstants.au3>

$iHandle = WinGetHandle('[CLASS:Notepad]')

_GDIPlus_Startup()
$hBitmap = Capture_Window($iHandle)
_GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\Test.jpg")
_GDIPlus_BitmapDispose($hBitmap)
ShellExecute(@ScriptDir & "\Test.jpg")
_GDIPlus_Shutdown()

Func Capture_Window($hWnd)
	Local $hDC_Capture = _WinAPI_GetWindowDC($hWnd)
	Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture)
	Local $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, _WinAPI_GetWindowWidth($hWnd), _WinAPI_GetWindowHeight($hWnd))
	Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
	DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hWnd, "handle", $hMemDC, "int", 0)
	Local $hBmp = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
	_WinAPI_SelectObject($hMemDC, $hObjectOld)
	_WinAPI_DeleteObject($hHBitmap)
	_WinAPI_DeleteDC($hMemDC)
	_WinAPI_ReleaseDC($hWnd, $hDC_Capture)
	Return $hBmp
EndFunc
 
Верх