Что нового

Захват изображения окна при свёрнутом состоянии

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Нашёл отличный пример передачи потокового (видео)
через интернет от Yashied'a в этой теме.

Но здесь есть проблема, если свернуть окно клиента, то изображение не будет показываться на сервере, точнее будет но не то, есть примеры, можите протестировать:

Client:

Код:
$WM_CAP_START = 0x400
$WM_CAP_UNICODE_START = $WM_CAP_START +100
$WM_CAP_PAL_SAVEA = $WM_CAP_START + 81
$WM_CAP_PAL_SAVEW = $WM_CAP_UNICODE_START + 81
$WM_CAP_UNICODE_END = $WM_CAP_PAL_SAVEW
$WM_CAP_ABORT = $WM_CAP_START + 69
$WM_CAP_DLG_VIDEOCOMPRESSION = $WM_CAP_START + 46
$WM_CAP_DLG_VIDEODISPLAY = $WM_CAP_START + 43
$WM_CAP_DLG_VIDEOFORMAT = $WM_CAP_START + 41
$WM_CAP_DLG_VIDEOSOURCE = $WM_CAP_START + 42
$WM_CAP_DRIVER_CONNECT = $WM_CAP_START + 10
$WM_CAP_DRIVER_DISCONNECT = $WM_CAP_START + 11
$WM_CAP_DRIVER_GET_CAPS = $WM_CAP_START + 14
$WM_CAP_DRIVER_GET_NAMEA = $WM_CAP_START + 12
$WM_CAP_DRIVER_GET_NAMEW = $WM_CAP_UNICODE_START + 12
$WM_CAP_DRIVER_GET_VERSIONA = $WM_CAP_START + 13
$WM_CAP_DRIVER_GET_VERSIONW = $WM_CAP_UNICODE_START + 13
$WM_CAP_EDIT_COPY = $WM_CAP_START + 30
$WM_CAP_END = $WM_CAP_UNICODE_END
$WM_CAP_FILE_ALLOCATE = $WM_CAP_START + 22
$WM_CAP_FILE_GET_CAPTURE_FILEA = $WM_CAP_START + 21
$WM_CAP_FILE_GET_CAPTURE_FILEW = $WM_CAP_UNICODE_START + 21
$WM_CAP_FILE_SAVEASA = $WM_CAP_START + 23
$WM_CAP_FILE_SAVEASW = $WM_CAP_UNICODE_START + 23
$WM_CAP_FILE_SAVEDIBA = $WM_CAP_START + 25
$WM_CAP_FILE_SAVEDIBW = $WM_CAP_UNICODE_START + 25
$WM_CAP_FILE_SET_CAPTURE_FILEA = $WM_CAP_START + 20
$WM_CAP_FILE_SET_CAPTURE_FILEW = $WM_CAP_UNICODE_START + 20
$WM_CAP_FILE_SET_INFOCHUNK = $WM_CAP_START + 24
$WM_CAP_GET_AUDIOFORMAT = $WM_CAP_START + 36
$WM_CAP_GET_CAPSTREAMPTR = $WM_CAP_START + 1
$WM_CAP_GET_MCI_DEVICEA = $WM_CAP_START + 67
$WM_CAP_GET_MCI_DEVICEW = $WM_CAP_UNICODE_START + 67
$WM_CAP_GET_SEQUENCE_SETUP = $WM_CAP_START + 65
$WM_CAP_GET_STATUS = $WM_CAP_START + 54
$WM_CAP_GET_USER_DATA = $WM_CAP_START + 8
$WM_CAP_GET_VIDEOFORMAT = $WM_CAP_START + 44
$WM_CAP_GRAB_FRAME = $WM_CAP_START + 60
$WM_CAP_GRAB_FRAME_NOSTOP = $WM_CAP_START + 61
$WM_CAP_PAL_AUTOCREATE = $WM_CAP_START + 83
$WM_CAP_PAL_MANUALCREATE = $WM_CAP_START + 84
$WM_CAP_PAL_OPENA = $WM_CAP_START + 80
$WM_CAP_PAL_OPENW = $WM_CAP_UNICODE_START + 80
$WM_CAP_PAL_PASTE = $WM_CAP_START + 82
$WM_CAP_SEQUENCE = $WM_CAP_START + 62
$WM_CAP_SEQUENCE_NOFILE = $WM_CAP_START + 63
$WM_CAP_SET_AUDIOFORMAT = $WM_CAP_START + 35
$WM_CAP_SET_CALLBACK_CAPCONTROL = $WM_CAP_START + 85
$WM_CAP_SET_CALLBACK_ERRORA = $WM_CAP_START + 2
$WM_CAP_SET_CALLBACK_ERRORW = $WM_CAP_UNICODE_START + 2
$WM_CAP_SET_CALLBACK_FRAME = $WM_CAP_START + 5
$WM_CAP_SET_CALLBACK_STATUSA = $WM_CAP_START + 3
$WM_CAP_SET_CALLBACK_STATUSW = $WM_CAP_UNICODE_START + 3
$WM_CAP_SET_CALLBACK_VIDEOSTREAM = $WM_CAP_START + 6
$WM_CAP_SET_CALLBACK_WAVESTREAM = $WM_CAP_START + 7
$WM_CAP_SET_CALLBACK_YIELD = $WM_CAP_START + 4
$WM_CAP_SET_MCI_DEVICEA = $WM_CAP_START + 66
$WM_CAP_SET_MCI_DEVICEW = $WM_CAP_UNICODE_START + 66
$WM_CAP_SET_OVERLAY = $WM_CAP_START + 51
$WM_CAP_SET_PREVIEW = $WM_CAP_START + 50
$WM_CAP_SET_PREVIEWRATE = $WM_CAP_START + 52
$WM_CAP_SET_SCALE = $WM_CAP_START + 53
$WM_CAP_SET_SCROLL = $WM_CAP_START + 55
$WM_CAP_SET_SEQUENCE_SETUP = $WM_CAP_START + 64
$WM_CAP_SET_USER_DATA = $WM_CAP_START + 9
$WM_CAP_SET_VIDEOFORMAT = $WM_CAP_START + 45
$WM_CAP_SINGLE_FRAME = $WM_CAP_START + 72
$WM_CAP_SINGLE_FRAME_CLOSE = $WM_CAP_START + 71
$WM_CAP_SINGLE_FRAME_OPEN = $WM_CAP_START + 70
$WM_CAP_STOP = $WM_CAP_START + 68
$cap = ""
$avi = ""
$user = ""

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>

TCPStartup()
$Socket = TCPConnect(@IPAddress1, 8080)

_GDIPlus_Startup()
Global $tEncoder, $pEncoder, $tParams, $pParams, $tQuality
$tEncoder = _WinAPI_GUIDFromString(_GDIPlus_EncodersGetCLSID('jpg'))
$pEncoder = DllStructGetPtr($tEncoder)
$tParams = _GDIPlus_ParamInit(1)
$pParams = DllStructGetPtr($tParams)
$tQuality = DllStructCreate('int')
DllStructSetData($tQuality, 1, 30)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tQuality))

$avi = DllOpen("avicap32.dll")
$user = DllOpen("user32.dll")
$Main = GUICreate("Client",320,240)
$cap1 = DllCall($avi, "int", "capCreateCaptureWindow", "str", "cap", "int", BitOR($WS_CHILD,$WS_VISIBLE), "int", 0, "int", 0, "int", 320, "int",240, "hwnd", $Main, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $cap1[0], "int", $WM_CAP_DRIVER_CONNECT, "int", 0, "int", 0)
DllCall($user, "int", "SendMessage", "hWnd", $cap1[0], "int", $WM_CAP_SET_SCALE, "int", 1, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $cap1[0], "int", $WM_CAP_SET_OVERLAY, "int", 1, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $cap1[0], "int", $WM_CAP_SET_PREVIEW, "int", 1, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $cap1[0], "int", $WM_CAP_SET_PREVIEWRATE, "int", 1, "int", 1)
GUISetState()

Do
$hPos = WinGetPos($Main)	
TCPSend($socket, _GetScreenshot($Main,0, 0, $hPos[2], $hPos[3]))
Until GUIGetMsg() = -3

_GDIPlus_Shutdown()
TCPCloseSocket($Socket)
TCPShutdown()

Func _GetScreenshot($hWnd, $iX = 0, $iY = 0, $iWidth = -1, $iHeight = -1)
    Local $hSrcDC, $hDstDC, $hDstSv, $hBitmap, $hDesktop, $hScreen, $hMemory, $pMemory, $pStream, $tOut, $pOut, $iSize
    If $iWidth = -1 Then
        $iWidth = @DesktopWidth
    EndIf
    If $iHeight = -1 Then
        $iHeight = @DesktopHeight
    EndIf
    $hSrcDC = _WinAPI_GetDC($hWnd)
    $hScreen = _WinAPI_CreateCompatibleBitmap($hSrcDC, $iWidth, $iHeight)
    $hDstDC = _WinAPI_CreateCompatibleDC($hSrcDC)
    $hDstSv = _WinAPI_SelectObject($hDstDC, $hScreen)
    _WinAPI_BitBlt($hDstDC, $iX, $iY, $iWidth, $iHeight, $hSrcDC, $iX, $iY, $SRCCOPY)
    _WinAPI_SelectObject($hDstDC, $hDstSv)
    _WinAPI_DeleteDC($hDstDC)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hScreen)
    _WinAPI_DeleteObject($hScreen)
    $pStream = _WinAPI_CreateStreamOnHGlobal(0)
    _GDIPlus_ImageSaveToStream($hBitmap, $pStream, $pEncoder, $pParams)
    _GDIPlus_BitmapDispose($hBitmap)
    $hMemory = _WinAPI_GetHGlobalFromStream($pStream)
    $pMemory = _MemGlobalLock($hMemory)
    $iSize = _MemGlobalSize($hMemory)
    $tOut = DllStructCreate('dword;dword;byte[' & ($iSize - Mod($iSize, 4) + 4) & ']')
    $pOut = DllStructGetPtr($tOut)
    DllStructSetData($tOut, 1, DllStructGetSize($tOut))
    DllStructSetData($tOut, 2, $iSize)
    _MemMoveMemory($pMemory, $pOut + 8, $iSize)
    _MemGlobalFree($hMemory)
    ConsoleWrite(_WinAPI_StrFormatByteSize($iSize) & @CR)
    Return DllStructGetData(DllStructCreate('byte[' & DllStructGetSize($tOut) & ']', DllStructGetPtr($tOut)), 1)
EndFunc 

Func _GDIPlus_ImageSaveToStream($hImage, $pStream, $pEncoder, $pParams = 0)
    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipSaveImageToStream', 'ptr', $hImage, 'ptr', $pStream, 'ptr', $pEncoder, 'ptr', $pParams)
    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return 1
EndFunc

Server:

Код:
#Include <Constants.au3>
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173

TCPStartup()
$Main = TCPListen(@IPAddress1, 8080)
If @error Then
    Exit
EndIf

GUICreate("Server", 320, 240, -1, -1)
$Pic = GUICtrlCreatePic('', 0, 0, 320, 240)
GUISetState()

Do
    $Socket = TCPAccept($Main)
Until $Socket <> -1

Global $tHeader = DllStructCreate('byte[4]')
Global $pHeader = DllStructGetPtr($tHeader)
Global $bData = 0, $Count = 0

_GDIPlus_Startup()

Do
    If Not IsBinary($bData) Then
        $bData = TCPRecv($Socket, 16384, 1)
        If @error Then
            ExitLoop
        EndIf
    EndIf
    If IsBinary($bData) Then
        If Not $Count Then
            DllStructSetData($tHeader, 1, $bData)
            $tData = DllStructCreate('dword', $pHeader)
            $Size = DllStructGetData($tData, 1)
            $tData = DllStructCreate('byte[' & $Size & ']')
            $pData = DllStructGetPtr($tData)
        EndIf
        $Lenght = BinaryLen($bData)
        $Sum = $Count + $Lenght
        If $Sum > $Size Then
            $dL = $Size - $Count
            $tPart = DllStructCreate('byte[' & $dL & ']', $pData + $Count)
            DllStructSetData($tPart, 1, $bData)
            $tByte = DllStructCreate('byte[' & $Lenght & ']')
            $tRecv = DllStructCreate('byte[' & ($Lenght - $dL) & ']', DllStructGetPtr($tByte) + $dL)
            DllStructSetData($tByte, 1, $bData)
            $bData = DllStructGetData($tRecv, 1)
            $Sum = $Size
        Else
            $tPart = DllStructCreate('byte[' & $Lenght & ']', $pData + $Count)
            DllStructSetData($tPart, 1, $bData)
            $Count = $Sum
            $bData = 0
        EndIf
        If $Sum = $Size Then
            _SetScreenshot($Pic, $tData)
            $Count = 0
        EndIf
    EndIf
Until GUIGetMsg() = -3

_GDIPlus_Shutdown()

TCPCloseSocket($Socket)
TCPShutdown()

Func _SetScreenshot($CtrlID, ByRef $tData, $fUpdate = 0)

    Local $hBitmap, $hPrev, $hScreen, $hMemory, $pMemory, $pStream, $pData, $iSize

    $hWnd = GUICtrlGetHandle($CtrlID)
    If Not $hWnd Then
        Return 0
    EndIf

    $pData = DllStructGetPtr($tData)
    $iSize = DllStructGetData(DllStructCreate('dword', $pData + 4), 1)
    $hMemory = _MemGlobalAlloc($iSize, $GMEM_MOVEABLE)
    $pMemory = _MemGlobalLock($hMemory)
    _MemMoveMemory($pData + 8, $pMemory, $iSize)
    _MemGlobalUnlock($hMemory)
    $pStream = _WinAPI_CreateStreamOnHGlobal($hMemory)
    $hBitmap = _GDIPlus_BitmapCreateFromStream($pStream)
    $hScreen = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _GDIPlus_BitmapDispose($hBitmap)
    _MemGlobalFree($hMemory)
    _WinAPI_DeleteObject(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hScreen))
    $hPrev = _SendMessage($hWnd, $STM_GETIMAGE)
    If $hPrev <> $hScreen Then
        _WinAPI_DeleteObject($hScreen)
    EndIf
    If $fUpdate Then
        _WinAPI_UpdateWindow($hWnd)
    EndIf
    Return 1
EndFunc   ;==>_SetScreenshot

Func _GDIPlus_BitmapCreateFromStream($pStream)

    Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $pStream, 'ptr*', 0)

    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return $Ret[2]
EndFunc   ;==>_GDIPlus_BitmapCreateFromStream
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Кто нибудь знает как сделать, мне этот скрипт срочно нужен, желательно сегодня?!
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Я решил сделать так:

Client:

Код:
Global Const $WM_CAP_START = 0x400
Global Const $WM_CAP_DRIVER_CONNECT = $WM_CAP_START + 10
Global Const $WM_CAP_SET_OVERLAY = $WM_CAP_START + 51
Global Const $WM_CAP_SET_PREVIEW = $WM_CAP_START + 50
Global Const $WM_CAP_SET_PREVIEWRATE = $WM_CAP_START + 52
Global Const $WM_CAP_SET_SCALE = $WM_CAP_START + 53
Global $avi = DllOpen("avicap32.dll")
Global $user = DllOpen("user32.dll")

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GDIPlus.au3>
#Include <Memory.au3>
#Include <WinAPIEx.au3>

TCPStartup()
$Socket = TCPConnect(@IPAddress1, 8080)
_GDIPlus_Startup()
Global $tEncoder, $pEncoder, $tParams, $pParams, $tQuality
$tEncoder = _WinAPI_GUIDFromString(_GDIPlus_EncodersGetCLSID("jpg"))
$pEncoder = DllStructGetPtr($tEncoder)
$tParams = _GDIPlus_ParamInit(1)
$pParams = DllStructGetPtr($tParams)
$tQuality = DllStructCreate("int")
DllStructSetData($tQuality, 1, 80)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tQuality))

$hForm = GUICreate("Client",320,240,-1,-1)
WinSetTrans($hForm, "", 10)
$Cap = DllCall($avi, "int", "capCreateCaptureWindow", "str", "cap", "int", BitOR($WS_CHILD,$WS_VISIBLE), "int", 0, "int", 0, "int", 320, "int",240, "hwnd", $hForm, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $Cap[0], "int", $WM_CAP_DRIVER_CONNECT, "int", 0, "int", 0)
DllCall($user, "int", "SendMessage", "hWnd", $Cap[0], "int", $WM_CAP_SET_SCALE, "int", 1, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $Cap[0], "int", $WM_CAP_SET_OVERLAY, "int", 1, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $Cap[0], "int", $WM_CAP_SET_PREVIEW, "int", 1, "int", 1)
DllCall($user, "int", "SendMessage", "hWnd", $Cap[0], "int", $WM_CAP_SET_PREVIEWRATE, "int", 1, "int", 1)
GUISetState()

Do
    $hPos = WinGetPos($hForm)	
	TCPSend($Socket, _GetScreenshot($hForm, 0, 0, $hPos[2], $hPos[3]))
Until GUIGetMsg() = -3

_GDIPlus_Shutdown()
TCPCloseSocket($Socket)
TCPShutdown()

Func _GetScreenshot($hWnd, $iX = 0, $iY = 0, $iWidth = -1, $iHeight = -1)
    Local $hSrcDC, $hDstDC, $hDstSv, $hBitmap, $hDesktop, $hScreen, $hMemory, $pMemory, $pStream, $tOut, $pOut, $iSize
    If $iWidth = -1 Then
        $iWidth = @DesktopWidth
    EndIf
    If $iHeight = -1 Then
        $iHeight = @DesktopHeight
    EndIf

    $hSrcDC = _WinAPI_GetDC($hWnd)
    $hScreen = _WinAPI_CreateCompatibleBitmap($hSrcDC, $iWidth, $iHeight)
    $hDstDC = _WinAPI_CreateCompatibleDC($hSrcDC)
    $hDstSv = _WinAPI_SelectObject($hDstDC, $hScreen)
    _WinAPI_BitBlt($hDstDC, $iX, $iY, $iWidth, $iHeight, $hSrcDC, $iX, $iY, $SRCCOPY)
    _WinAPI_SelectObject($hDstDC, $hDstSv)
    _WinAPI_DeleteDC($hDstDC)
    $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hScreen)
    _WinAPI_DeleteObject($hScreen)
    $pStream = _WinAPI_CreateStreamOnHGlobal(0)
    _GDIPlus_ImageSaveToStream($hBitmap, $pStream, $pEncoder, $pParams)
    _GDIPlus_BitmapDispose($hBitmap)
    $hMemory = _WinAPI_GetHGlobalFromStream($pStream)
    $pMemory = _MemGlobalLock($hMemory)
    $iSize = _MemGlobalSize($hMemory)
    $tOut = DllStructCreate("dword;dword;byte[" & ($iSize - Mod($iSize, 4) + 4) & "]")
    $pOut = DllStructGetPtr($tOut)
    DllStructSetData($tOut, 1, DllStructGetSize($tOut))
    DllStructSetData($tOut, 2, $iSize)
    _MemMoveMemory($pMemory, $pOut + 8, $iSize)
    _MemGlobalFree($hMemory)
    _WinAPI_StrFormatByteSize($iSize)
    Return DllStructGetData(DllStructCreate("byte[" & DllStructGetSize($tOut) & "]", DllStructGetPtr($tOut)), 1)
EndFunc 

Func _GDIPlus_ImageSaveToStream($hImage, $pStream, $pEncoder, $pParams = 0)
    Local $Ret = DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hImage, "ptr", $pStream, "ptr", $pEncoder, "ptr", $pParams)
    If (@error) Or ($Ret[0]) Then
        Return SetError(@error, @extended, 0)
    EndIf
    Return 1
EndFunc

Подскажите пожалуйста ссылку на то как сделать окно через которое проходит курсор, не могу найти в поиске.


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

Всё, нашёл
 
Верх