#AutoIt3Wrapper_usex64=n
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GUIConstants.au3>
;#include <AssembleIt.au3>
#include <Misc.au3>

#cs
    DeskStream 2 by Sprenger120 & Andy @www.autoit.de
    Version: 1.8 RC 14.05.2011
#ce

AutoItSetOption("MouseCoordMode", 2)

Global $pBitmap, $hBitmap, $ServerIP, $ServerPort, $iConnect, $iFPS = 0
Global $hBitmapDC, $tInfoStruct, $pBitmap, $tPic
Global $iBreite, $iHoehe, $tInput, $ptr_tbuffer, $ilen, $ptr_tinput, $tBuffer, $bitmapsize
Global $sIni = @AppDataDir & "\DeskStream.ini"
Global $Msg[5], $zoomfaktor = 0, $wheelsend = "", $sendflag = True
Global $size_new, $size_old, $mouseup = 0
Global $hDLL_User32 = DllOpen("user32.dll")

Global Const $tagMINMAXINFO = "int ptReserved[2]; int ptMaxSize[2]; int ptMaxPosition[2]; int ptMinTrackSize[2]; int ptMaxTrackSize[2];"

Global $struct_sendstring = DllStructCreate("char newframe;ubyte mouseleftx[3];ubyte mouselefty[3];ubyte mouserightx[3];ubyte mouserighty[3];" & _; beliebig erweiterbar
        "ubyte wheelx[3];ubyte wheely[3];ubyte wheelzoom;ubyte newsizex[3];ubyte newsizey[3];char eof")
Global $sendstring = DllStructCreate("byte[" & DllStructGetSize($struct_sendstring) & "]", DllStructGetPtr($struct_sendstring)) ;um struct komplett in einem Rutsch senden zu können
DllStructSetData($struct_sendstring, "eof", "E") ;end of file

Global $emptystring = DllStructGetData($sendstring, 1)
Global $send = $emptystring

GUIRegisterMsg($WM_MOUSEWHEEL, "_Mousewheel")
GUIRegisterMsg($WM_EXITSIZEMOVE, "WM_SIZEPROC") ; Message nach der Größenändernung
GUIRegisterMsg($WM_size, "WM_SIZEPROC")     ; Message während der Größenändernung
GUIRegisterMsg($WM_GETMINMAXINFO, "WM_SIZEPROC") ; Minimale Größe festlegen

If Not FileExists($sIni) Then
    IniWrite($sIni, "Conf", "ServerIP", "127.0.0.1")
    IniWrite($sIni, "Conf", "ServerPort", 5487)
    IniWrite($sIni, "Conf", "RectW", 800)
    IniWrite($sIni, "Conf", "RectH", 600)
    IniWrite($sIni, "Conf", "HQ", 1)
    IniWrite($sIni, "Conf", "Seitenverhaeltnis", 1)
EndIf

$hGui_ConnectForm = GUICreate("DeskStream 2 RC 1.0 (Client)", 249, 118)
GUICtrlCreateTab(0, 0, 249, 118)

GUICtrlCreateTabItem("Verbinden")
GUICtrlCreateLabel("Server Addrese:", 8, 28, 80, 17)
GUICtrlCreateLabel("Port:", 62, 60, 26, 17)

$cServerIP = GUICtrlCreateInput(IniRead($sIni, "Conf", "ServerIP", "127.0.0.1"), 96, 25, 145, 21)
$cServerPort = GUICtrlCreateInput(IniRead($sIni, "Conf", "ServerPort", 5487), 96, 57, 145, 21, $ES_NUMBER)

$Verbinden = GUICtrlCreateButton("Verbinden", 8, 84, 233, 25)

GUICtrlCreateTabItem("Erweitert")

GUICtrlCreateLabel("Auflösung:", 8, 33, 54, 17)
GUICtrlCreateLabel("x", 123, 33, 9, 17)

$cRectW = GUICtrlCreateInput(IniRead($sIni, "Conf", "RectW", 800), 66, 30, 49, 21, $ES_NUMBER)
$cRectH = GUICtrlCreateInput(IniRead($sIni, "Conf", "RectH", 600), 136, 30, 57, 21, $ES_NUMBER)
$cSchoenerModus = GUICtrlCreateCheckbox("HQ Modus", 8, 56, 70, 17)
Switch IniRead($sIni, "Conf", "HQ", 1)
    Case 1
        GUICtrlSetState(-1, $GUI_CHECKED)
    Case 0
        GUICtrlSetState(-1, $GUI_UNCHECKED)
EndSwitch
$cSeitenverhaeltnis = GUICtrlCreateCheckbox("Seitenverhältnis Server", 95, 56, 135, 17)
Switch IniRead($sIni, "Conf", "Seitenverhaeltnis", 1)
    Case 1
        GUICtrlSetState(-1, $GUI_CHECKED)
    Case 0
        GUICtrlSetState(-1, $GUI_UNCHECKED)
EndSwitch
GUICtrlCreateLabel("Desk Stream 2 by Sprenger120 und Andy @www.autoit.de", 8, 80, 270, 60)

;Startups
Global $hStreamGUI = GUICreate("DeskStream 2", 800, 600, -1, -1, $WS_SIZEBOX)
;Rahmengröße berechnen
$tRECT = _WinAPI_GetClientRect($hStreamGUI)
$X1 = DllStructGetData($tRECT, "Left")
$Y1 = DllStructGetData($tRECT, "Top")
$X2 = DllStructGetData($tRECT, "Right")
$Y2 = DllStructGetData($tRECT, "Bottom")
$tRECT = 0
$aCoord = WinGetPos($hStreamGUI)
Dim $aRahmen[2]
$aRahmen[0] = $aCoord[2] - ($X2 - $X1)
$aRahmen[1] = $aCoord[3] - ($Y2 - $Y1)

TCPStartup()

Global $tCodeBuffer = DllStructCreate("byte[199]") ;reserve Memory for opcodes
DllStructSetData($tCodeBuffer, 1, "0x8B7424048B7C24088B4C240C31D290908B1F0FBAF316733F5181E3FFFF3F000FB64F03568D349E0FB7444F02C1E00566C1E803C0E802C1E00389448EFC83E90175E50FB64703D1E083C0045E01C75929C183F90277BAC30FB74703C1E00566C1E803C0E802C1E0030FBAF31773375681E3FFFF3F003B5C241476045E89D8C38D349E0FB65705C1E20289041683EA0483FA007DF55E83C70683E90683F90A0F876CFFFFFFC381E3FFFF3F003B5C2410760389D8C389049E83C70583E90583F90A0F874AFFFFFFC3") ;write opcodes into memory
$pCode = DllStructGetPtr($tCodeBuffer)
Global $hGUIDC = _WinAPI_GetDC($hStreamGUI)

OnAutoItExitRegister("_Exit")
Opt("GUICloseOnESC", 0)
GUISetState(@SW_SHOW, $hGui_ConnectForm)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case -3
            Exit
        Case $Verbinden
            $ServerIP = GUICtrlRead($cServerIP)
            If StringStripWS($ServerIP, 8) = "" Then
                MsgBox(64, "DeskStream 2 Beta", "Es wurde keine IP angegeben!")
                ContinueLoop
            EndIf
            $ServerPort = GUICtrlRead($cServerPort)
            If StringStripWS($ServerPort, 8) = "" Then
                MsgBox(64, "DeskStream 2 Beta", "Es wurde kein Port angegeben!")
                ContinueLoop
            EndIf

            $iConnect = TCPConnect(TCPNameToIP($ServerIP), $ServerPort)
            If @error Then
                MsgBox(16, "DeskStream 2 Beta", StringFormat("Konnte keine Verbindung zu %s:%s herstellen.", $ServerIP, $ServerPort))
                ContinueLoop
            EndIf

            $iBreite = GUICtrlRead($cRectW)
            If BitAND(GUICtrlRead($cSeitenverhaeltnis), $GUI_CHECKED) And $iBreite <> "" Then ;Seitenverhaeltnis angehakt
                $bxh_server = ""
                While StringLen($bxh_server) < 16;so lange, bis 16 byte empfangen wurden
                    $bxh_server &= TCPRecv($iConnect, 16) ;erhält vom Server die Grösse dessen Desktops
                WEnd
                $iHoehe = Int($iBreite / (Dec(StringLeft($bxh_server, 8)) / Dec(StringRight($bxh_server, 8))));ermittelt höhen/breitenverhältnis
                GUICtrlSetData($cRectH, $iHoehe);errechnete hoehe in gui schreiben
            Else
                $iHoehe = GUICtrlRead($cRectH)
            EndIf

            If $iBreite = "" Or $iHoehe = "" Then
                $iBreite = 800
                $iHoehe = 600
            EndIf

            $iStatus = 0
            If BitAND(GUICtrlRead($cSchoenerModus), $GUI_CHECKED) Then $iStatus = 1;HQ angehakt
            $sData = $iBreite & "x" & $iHoehe & $iStatus
            TCPSend($iConnect, "FF" & StringLen($sData) & "B" & $sData);breite, hoehe und Modus an server senden
            If @error Then
                MsgBox(16, "DekStream 2 Beta", "Konnte keine Daten senden.")
                ContinueLoop
            EndIf

            ;Neue Daten in INI schreiben
            IniWrite($sIni, "Conf", "ServerIP", $ServerIP)
            IniWrite($sIni, "Conf", "ServerPort", $ServerPort)
            IniWrite($sIni, "Conf", "RectW", $iBreite)
            IniWrite($sIni, "Conf", "RectH", $iHoehe)
            If BitAND(GUICtrlRead($cSchoenerModus), $GUI_CHECKED) Then
                IniWrite($sIni, "Conf", "HQ", 1)
            Else
                IniWrite($sIni, "Conf", "HQ", 0)
            EndIf
            If BitAND(GUICtrlRead($cSeitenverhaeltnis), $GUI_CHECKED) Then
                IniWrite($sIni, "Conf", "Seitenverhaeltnis", 1)
            Else
                IniWrite($sIni, "Conf", "Seitenverhaeltnis", 0)
            EndIf

            GUISetState(@SW_HIDE, $hGui_ConnectForm)
            WinMove($hStreamGUI, "", (@DesktopWidth - $iBreite) / 2, (@DesktopHeight - $iHoehe) / 2, $iBreite + $aRahmen[0], $iHoehe + $aRahmen[1])

            GUISetState(@SW_SHOW, $hStreamGUI)
            _Stream()
            GUISetState(@SW_SHOW, $hGui_ConnectForm)
            GUISetState(@SW_HIDE, $hStreamGUI)
    EndSwitch
WEnd

Func _Stream()
    $hBitmapDC = _CreateNewBmp32($iBreite, $iHoehe, $pBitmap, $hBitmap)
    $tInfoStruct = DllStructCreate("byte[" & $iBreite * $iHoehe * 7 & "]")
    $pInfoStruct = DllStructGetPtr($tInfoStruct)
    $tPic = DllStructCreate("byte[" & $iBreite * $iHoehe * 4 & "]", $pBitmap)
    $bitmapsize = $iBreite * $iHoehe

    ;global $ptr_tinput = _MemGlobalAlloc($bitmapsize, 0)
    $tInput = DllStructCreate("byte[" & $bitmapsize * 7 & "]");BinaryLen($bBinary) & "]")
    ;global $ptr_tbuffer = _MemGlobalAlloc($bitmapsize*16, 0)
    $tBuffer = DllStructCreate("byte[" & 16 * $bitmapsize * 5 & "]");DllStructGetSize($tInput) & "]") ; initially oversizing buffer
    $ptr_tbuffer = DllStructGetPtr($tBuffer)
    $ptr_tinput = DllStructGetPtr($tInput)


    AdlibRegister("_FPS", 1000)
    $rcv_timer = TimerInit()
    While 1
        $sendflag = False                   ;wenn am ende der schleife true, dann paket an server senden
        $Msg = GUIGetMsg(1)
        Switch $Msg[0]
            Case -3
                ExitLoop
            Case $GUI_EVENT_PRIMARYUP       ;linke maustaste hoch
                If $mouseup = 0 Then        ;nur wenn nicht vorher das fenster in der Grösse verändert wurde
                    If $Msg[1] = $hStreamGUI Then ;ins fenster geklickt
                        $x = $Msg[3]        ;koordinaten
                        $y = $Msg[4]
                        If $x > 0 And $x < $iBreite And $y > 0 And $y < $iHoehe Then
                            DllStructSetData($struct_sendstring, "mouseleftx", $x)
                            DllStructSetData($struct_sendstring, "mouselefty", $y)
                        EndIf
                    EndIf
                Else
                    $mouseup = 0
                EndIf
            Case $GUI_EVENT_SECONDARYUP     ;rechte maustaste hoch
                If $Msg[1] = $hStreamGUI Then ;ins fenster geklickt
                    $x = $Msg[3]            ;koordinaten
                    $y = $Msg[4]
                    If $x > 0 And $x < $iBreite And $y > 0 And $y < $iHoehe Then
                        DllStructSetData($struct_sendstring, "mouserightx", $x)
                        DllStructSetData($struct_sendstring, "mouserighty", $y)
                    EndIf
                EndIf
        EndSwitch


        $sresv = TCPRecv($iConnect, 1)      ;ein zeichen aus dem puffer holen
        If @error Then                      ;verbindung zum server verloren
            MsgBox(16, "DeskStream 2 Beta", "Verbindung unterbrochen.")
            ExitLoop
        EndIf

        If $sresv = "Q" Then                ;Q=Server lebt noch, sendet aber keine Daten
            $sendflag = True
        EndIf

        If $sresv = "F" Then                ;
            $sresv &= TCPRecv($iConnect, 3) ;
            If $sresv <> "FF01" Then        ;müll aus der pipeline entfernen
                MsgBox(0, "client", "schrott in pipeline, frame anfordern <>Q und <>""" & @CRLF & $sresv, 3)
                $t_rec = TimerInit()
                While TimerDiff($t_rec) < 500 ;eine sekunde warten, so lange, bis keine daten mehr in der pipeline sind
                    If TCPRecv($iConnect, 20480) <> "" Then $t_rec = TimerInit();solange daten in der pipeline sind, timer setzen
                WEnd
                DllStructSetData($struct_sendstring, "newframe", "P")
            Else                            ;kein müll in der pipeline
                $sData = (GetLongInf(False))  ;Daten aus pipeline auslesen
                If $sData <> -1 Then        ;alle Daten wurden empfangen
                    $sData = _LZNTDecompress($sData); daten dekomprimieren
                    $len = @extended        ;länge der dekomprimierten Daten
                    If @error Then MsgBox(0, "client", "fehler beim decompress", 2)
                    If $len > 0 Then        ;Daten wurden ohne Fehler dekomprimiert
                        ;Pixel in Bitmap schreiben
                        DllStructSetData($tInfoStruct, 1, $sData)
                        DllCall($hDLL_User32, "int", "CallWindowProcW", "ptr", $pCode, "ptr", $pBitmap, "ptr", $pInfoStruct, "int", $len, "int", $bitmapsize)
                        ;$_assembleit_flag=0
                        ;$ret = _AssembleIt("int", "SetInfo", "ptr", $pBitmap, "ptr", $pInfoStruct, "int", $len, "int", $bitmapsize)
                        $iFPS += 1          ;Frames pro Sekunde
                        _WinAPI_BitBlt($hGUIDC, 0, 0, $iBreite, $iHoehe, $hBitmapDC, 0, 0, $SRCCOPY)
                        $sendflag = True
                    Else
                        MsgBox(0, "client", "fehler beim dekomprimieren", 3)
                        $t_rec = TimerInit()
                        While TimerDiff($t_rec) < 500 ;eine sekunde warten, so lange, bis keine daten mehr in der pipeline sind
                            If TCPRecv($iConnect, 20480) <> "" Then $t_rec = TimerInit();solange daten in der pipeline sind, timer setzen
                        WEnd
                    EndIf

                Else                        ;fehler aufgetreten beim EMPFANG
                    MsgBox(0, "Client", "Schrott in pipeline, frame anfordern FFo1 else", 2)
                    $t_rec = TimerInit()
                    While TimerDiff($t_rec) < 500 ;eine sekunde warten, so lange, bis keine daten mehr in der pipeline sind
                        If TCPRecv($iConnect, 20480) <> "" Then $t_rec = TimerInit();solange daten in der pipeline sind, timer setzen
                    WEnd                    ;wenn 500 ms keine daten kommen, ist die pipeline leer...hoffentlich
                    DllStructSetData($struct_sendstring, "newframe", "P")
                    $sendflag = True
                EndIf
            EndIf

        EndIf
        $sresv = ""

         _Taste();pfeiltasten und +- abfragen

        $send = DllStructGetData($sendstring, 1)
        If $sendflag = True Then            ;nur wenn daten empfangen wurden, wird
            $sendflag = False

            TCPSend($iConnect, $send);datenpaket senden
            If DllStructGetData($struct_sendstring, "newsizex") <> 0 Then ;neue Fenstergröße an Server geschickt
                $iBreite = Number(DllStructGetData($struct_sendstring, "newsizex"))
                $iHoehe = Number(DllStructGetData($struct_sendstring, "newsizey"))
                _DeleteBitmap32($hBitmapDC, $pBitmap, $hBitmap)
                $tInfoStruct = 0
                $tPic = 0
                $tInput = 0
                $pBitmap = 0
                $hBitmap = 0

                $hBitmapDC = _CreateNewBmp32($iBreite, $iHoehe, $pBitmap, $hBitmap)
                $tInfoStruct = DllStructCreate("byte[" & $iBreite * $iHoehe * 7 & "]")
                $pInfoStruct = DllStructGetPtr($tInfoStruct)
                $tPic = DllStructCreate("byte[" & $iBreite * $iHoehe * 4 & "]", $pBitmap)
                $bitmapsize = $iBreite * $iHoehe
                ;global $ptr_tinput = _MemGlobalAlloc($bitmapsize, 0)
                $tInput = DllStructCreate("byte[" & $bitmapsize * 7 & "]");BinaryLen($bBinary) & "]")
                ;global $ptr_tbuffer = _MemGlobalAlloc($bitmapsize*16, 0)
                $tBuffer = DllStructCreate("byte[" & 16 * $bitmapsize * 5 & "]");DllStructGetSize($tInput) & "]") ; initially oversizing buffer
                $ptr_tbuffer = DllStructGetPtr($tBuffer)
                $ptr_tinput = DllStructGetPtr($tInput)
                ;alle puffer leeren
                $t_rec = TimerInit()
                While TimerDiff($t_rec) < 500 ;eine sekunde warten, so lange, bis keine daten mehr in der pipeline sind
                    If TCPRecv($iConnect, 20480) <> "" Then $t_rec = TimerInit();solange daten in der pipeline sind, timer setzen
                WEnd
                TCPSend($iConnect, "G")     ;erstes frame mit neuer Grösse anfordern

            EndIf

            DllStructSetData($sendstring, 1, $emptystring);string leeren
        EndIf

    WEnd;hauptschleife


    ;Speicher leer putzen
    _DeleteBitmap32($hBitmapDC, $pBitmap, $hBitmap)
    $pInfoStruct = 0
    $tInfoStruct = 0
    $tPic = 0
    $ptr_tbuffer = 0
    $ptr_tinput = 0
    $tBuffer = 0
    $tInput = 0
    AdlibUnRegister("_FPS")
    TCPShutdown()
    TCPStartup()                            ;Verbindung zum Server trennen
EndFunc                                     ;==>_Stream

Func _FPS()
    If $iFPS = 0 Then $iFPS = "keine Veränderung"
    WinSetTitle($hStreamGUI, "", "DeskStream 2 FPS=" & $iFPS & "  Zoom= " & $zoomfaktor)
    $iFPS = 0
EndFunc                                     ;==>_FPS

Func _Exit()
    DllClose($hDLL_User32)
    _WinAPI_ReleaseDC($hStreamGUI, $hGUIDC)
    $pCode = 0
    $tCodeBuffer = 0
    TCPShutdown()
    Exit
EndFunc                                     ;==>_Exit

Func GetLongInf($Binary = True)
    Local $sData = "", $rec = "", $chunk,$err=0
    While 1
        $sData = TCPRecv($iConnect, 8)
        If @error Then Return -1
        $ilen = Dec($sData)
        $sData = TCPRecv($iConnect, 1)
        $chunk = 20480                      ;paketgröße
        If $ilen < $chunk Then $chunk = $ilen
        $mod = Mod($ilen, $chunk)
        Local $rest = $mod + $chunk
        If $sData = "B" Then
            $sData = ""
            $t1 = TimerInit()
            $rec = ""
            Do                              ;genau die menge von $ilen an bytes auslesen
                $a = TCPRecv($iConnect, $chunk,1)
                If @error Then
                    $err = 1
                    ExitLoop
                EndIf
                If $a <> "" Then $rec &= binarytostring($a)
                If StringLen($rec) >= $ilen - $rest Then
                    $rest = Int(($ilen - StringLen($rec)) / 2)
                    $chunk = $rest + 1
                EndIf
            Until StringLen($rec) = $ilen
            If StringLen($rec) = $ilen Then
                $rec=stringtobinary($rec)
                Return $rec
            Else
                MsgBox(0, "client", "falscher recv "&stringleft($rec,100))
                Return -1
            EndIf
        EndIf
    WEnd
EndFunc                                     ;==>GetLongInf

Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    $hcdc = _WinAPI_CreateCompatibleDC(0)   ;Desktop-Kompatiblen DeviceContext erstellen lassen
    $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
	DllStructSetData($tBMI,1, DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI,2, $iwidth)
    DllStructSetData($tBMI,3, -$iheight) ;minus =standard = bottomup
    DllStructSetData($tBMI,4, 1)
    DllStructSetData($tBMI,5, 32) ;32 Bit = 4 Bytes => AABBGGRR
    $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0]                        ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4]                         ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    _WinAPI_SelectObject($hcdc, $hbmp)      ;objekt hbitmap in DC
    Return $hcdc                            ;DC der Bitmap zurückgeben
EndFunc                                     ;==>_CreateNewBmp32

Func _DeleteBitmap32($DC, $ptr, $hbmp)
    _WinAPI_DeleteDC($DC)
    _WinAPI_DeleteObject($hbmp)
    $ptr = 0
EndFunc                                     ;==>_DeleteBitmap32


; #FUNCTION# ;===============================================================================
;
; Name...........: _LZNTDecompress
; Description ...: Decompresses input data.
; Syntax.........: _LZNTDecompress ($bBinary)
; Parameters ....: $vInput - Binary data to decompress.
; Return values .: Success - Returns decompressed binary data.
;                          - Sets @error to 0
;                  Failure - Returns empty string and sets @error:
;                  |1 - Error decompressing.
; Author ........: trancexx
; Related .......: _LZNTCompress
; Link ..........; http://msdn.microsoft.com/en-us/library/bb981784.aspx
;
;==========================================================================================
Func _LZNTDecompress($bBinary)
    DllStructSetData($tInput, 1, $bBinary)
    $ilen=$ilen*2+2

    Local $a_Call = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _
            "ushort", 2, _                  ;2
            "ptr", $ptr_tbuffer, _          ;DllStructGetPtr($tBuffer), _
            "dword", 8 * $ilen, _           ;DllStructGetSize($tBuffer), _
            "ptr", $ptr_tinput, _           ;DllStructGetPtr($tInput), _
            "dword", ($ilen - 2) / 2, _        ;DllStructGetSize($tInput), _
            "dword*", 0)

    If @error Or $a_Call[0] Then
        ConsoleWrite(Hex($a_Call[0]) & @CRLF)
        Return SetError(1, 0, "")           ; error decompressing
    EndIf


    Local $tOutput = DllStructCreate("byte[" & $a_Call[6] & "]", DllStructGetPtr($tBuffer))

    Return SetError(0, $a_Call[6], DllStructGetData($tOutput, 1))

EndFunc                                     ;==>_LZNTDecompress

#cs
Func SetInfo()
    _("use32")
    _("mov esi,dword[esp+4]")               ;Pointer auf die Bitmap
    _("mov edi,dword[esp+8]")               ;Pointer aud die Struct
    _("mov ecx,dword[esp+12]")              ;größe struct
    _("xor edx,edx")                        ;edx=0

    _("align 16")
    _("_schleife:")

    _("mov ebx,[edi]")                      ;adresse in bx

    _("btr ebx,22")                         ;ist das bit für aufeinanderfolgende farben gesetzt?
    _("jnc _keineaufeinanderfolgenden")     ;wenn nicht, _nichtmehrere
    ;aufeinanderfolgende farben gefunden: 3 byte adresse, 1 byte anzahl , 2 byte farbe, 2 byte farbe....
    _("push ecx")
    _("and ebx,0x3FFFFF")                   ;nur 22 bit adresse pixel
    _("movzx ecx,byte[edi+3] ")             ;anzahl der aufeinanderfolgenden farb-words
    _("push esi")
    _("lea esi,[esi+ebx*4]")
    _("_loop:")
    _("movzx eax,word[edi+2+2*ecx]")        ;farbword holen
    _("shl eax,5")                          ;
    _("shr ax,3")                           ;
    _("shr al,2")                           ;
    _("shl eax,3")                          ;farbword zu 32bit-farbe machen
    _("mov [esi+4*ecx-4],eax")              ;farbe an adresse schreiben
    ;  _("mov dword[esi+4*ecx-4],0x00FF00");farbe an adresse schreiben
    _("sub ecx,1")                          ;eins niedriger
    _("jnz _loop")
    _("movzx eax,byte[edi+3] ")             ;anzahl der aufeinanderfolgenden farb-words
    _("shl eax,1")                          ;eine farbe ist 2 bytes lang
    _("add eax,4")                          ;anzahl bytes adresse+anz+farb-words
    _("pop esi")
    _("")
    _("")
    _("add edi,eax")                        ;pointer auf nächsten block
    _("pop ecx")
    _("sub ecx,eax")                        ;verbliebene anzahl bytes in struct
    _("cmp ecx,2")
    _("ja _schleife")                       ;ecx-1 | prüfen ob 0
    _("ret")

    _("_keineaufeinanderfolgenden:")
    _("movzx eax,word[edi+3]")              ;vordere 24 bit= adresse, ax=farbe
    _("shl eax,5")                          ;
    _("shr ax,3")                           ;
    _("shr al,2")                           ;
    _("shl eax,3")
    _("btr ebx,23")                         ;ist das pixel für mehrfach gesetzt?
    _("jnc _nichtmehrere")                  ;wenn nicht, _nichtmehrere
    _("push esi")
    _("and ebx,0x3FFFFF")                   ;nur 22 bit
    _("cmp ebx,dword[esp+20]")              ;adresse innerhalb der bitmapgrösse?
    _("jbe @f")                             ;wenn kleiner,weiter
    _("pop esi")
    _("mov eax,ebx")
    _("ret")                                ;adresse nicht regulär, dann ende
    _("@@:")
    _("lea esi,[esi+ebx*4]")
    _("movzx edx,byte[edi+5]")              ;anzahl der mehrfachen pixel in edx
    _("shl edx,2")                          ;edx=edx*4
    _("_line:")
    ;_("mov dword[esi+edx],0xFF00FF");eax")        ;farbe schreiben oder eax durch 0xFF00FF ersetzen^^
    _("mov dword[esi+edx],eax")             ;farbe schreiben oder eax durch 0xFF00FF ersetzen^^
    _("sub edx,4")
    _("cmp edx,0")
    _("jnl _line")
    _("pop esi")
;~     _("")

    _("add edi,6")                          ;pointer weiterschieben
    _("sub ecx,6")
    _("cmp ecx,10")
    _("ja _schleife")                       ;ecx-1 | prüfen ob 0
    _("ret")

    _("")
    _("")
    _("")
    _("_nichtmehrere:")
    _("and ebx,0x3FFFFF")                   ;nur 22 bit
    _("cmp ebx,dword[esp+16]")              ;adresse innerhalb der bitmapgrösse?
    _("jbe @f")                             ;wenn kleiner,
    _("mov eax,ebx")
    _("ret")                                ;adresse nicht regulär, dann ende
    _("@@:")
    ;_("mov dword[esi+ebx*4],0x00FFFF");eax")    ;farbe schreiben
    _("mov dword[esi+ebx*4],eax")
    _("add edi,5")                          ;pointer weiterschieben
    _("sub ecx,5")
    _("cmp ecx,10")
    _("ja _schleife")                       ;ecx-1 | prüfen ob 0
    _("ret")
EndFunc                                     ;==>SetInfo
#ce

Func _mousewheel($hWnd, $hMsg, $wParam, $lParam)
    #forceref $hMsg, $wParam
    Local $x = MouseGetPos(0)               ;koordinaten
    Local $y = MouseGetPos(1)
    If $x > 0 And $x < $iBreite And $y > 0 And $y < $iHoehe Then
        If $wParam = "0x00780000" Then      ;raufscrollen vergrössern
            If $zoomfaktor < 16 Then
                $zoomfaktor += 1
                DllStructSetData($struct_sendstring, "wheelx", $x)
                DllStructSetData($struct_sendstring, "wheely", $y)
                DllStructSetData($struct_sendstring, "wheelzoom", $zoomfaktor)
            EndIf
        EndIf
        If $wParam = "0xFF880000" Then      ;runterscrollen
            If $zoomfaktor > 0 Then
                $zoomfaktor -= 1
                DllStructSetData($struct_sendstring, "wheelx", $x)
                DllStructSetData($struct_sendstring, "wheely", $y)
                DllStructSetData($struct_sendstring, "wheelzoom", $zoomfaktor)
                If $zoomfaktor = 0 Then Sleep(100)
            EndIf
        EndIf
    EndIf
    Return
EndFunc                                     ;==>_mousewheel



Func WM_SIZEPROC($hWnd, $uMsg, $wParam, $lParam)
    Switch $uMsg
        Case $WM_GETMINMAXINFO              ; Die Fenstergröße abfragen, minimale Größe fürs verkleinern setzen
            Local $MinMax = DllStructCreate($tagMINMAXINFO, $lParam) ; DLLStruct auf den Pointer erstellen, zum bearbeiten der Werte
            DllStructSetData($MinMax, 4, 100, 1) ; Minimal 100 Pixel breit
            DllStructSetData($MinMax, 4, 100, 2) ; Minimal 100 Pixel hoch
        Case $WM_EXITSIZEMOVE               ; nach dem verschieben oder vergrössern
            If $size_old <> $size_new Then  ;nur wenn grösse verändert
                $size_old = $size_new
                $iBreite = Dec(StringLeft($size_new, 6))
                $iHoehe = Dec(StringRight($size_new, 6))
                DllStructSetData($struct_sendstring, "newsizex", $iBreite)
                DllStructSetData($struct_sendstring, "newsizey", $iHoehe)
                ;DllStructSetData($struct_sendstring, "newframe", "P")
                $mouseup = 1
            EndIf
        Case $WM_size                       ; grösse während des sizing
            $size_new = Hex(BitAND($lParam, 0xFFFF), 6) & Hex(BitAND(BitShift($lParam, 16), 0xFFFF), 6) ; Die Breite und Höhe des Fensters auslesen, Lo-und HiWord vom lparam.
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc                                     ;==>WM_SIZEPROC

Func _Taste()
    Local $stepx = 0, $stepy = 0
    $gezoomed = False
    If _IsPressed("25", $hDLL_User32) Then  ;Pfeiltaste links
        $stepx = -(18 - $zoomfaktor)
        $stepy = 0
    ElseIf _IsPressed("27", $hDLL_User32) Then ;Pfeiltaste rechts
        $stepx = (18 - $zoomfaktor)
        $stepy = 0
    ElseIf _IsPressed("26", $hDLL_User32) Then ;Pfeiltaste oben
        $stepx = 0
        $stepy = -(19 - $zoomfaktor)
    ElseIf _IsPressed("28", $hDLL_User32) Then ;Pfeiltaste unten
        $stepx = 0
        $stepy = (18 - $zoomfaktor)
    ElseIf _IsPressed("6B", $hDLL_User32) Then ;numpad +
        $zoomfaktor += 1
        If $zoomfaktor > 16 Then $zoomfaktor = 16
    ElseIf _IsPressed("6D", $hDLL_User32) Then ;numpad -
        $zoomfaktor -= 1
        If $zoomfaktor < 0 Then $zoomfaktor = 0
    Else
        Return                              ;irgendeine andere taste wurde betätigt
    EndIf
    $x = Round(($iBreite + $stepx) / 2)
    $y = Round(($iHoehe + $stepy) / 2)
    DllStructSetData($struct_sendstring, "wheelx", $x)
    DllStructSetData($struct_sendstring, "wheely", $y)
    DllStructSetData($struct_sendstring, "wheelzoom", $zoomfaktor)
    Sleep(100)                              ;tasten entprellen
    $sendflag = True                        ;senden
EndFunc                                     ;==>_Taste