1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Oscar

Beiträge von Oscar

  • List View

    • Oscar
    • 24. Juni 2022 um 18:19

    Das ständige einlesen eines Verzeichnisses ist gar nicht notwendig, um Veränderungen mitzubekommen. Windows bietet dafür eine eventbasierte Möglichkeit. So wird das Verzeichnis nur bei Veränderungen neu eingelesen.

    Hier mal ein (sehr ausführliches) Beispiel:

    AutoIt
    #include <APIShellExConstants.au3>
    #include <Date.au3>
    #include <FileConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiImageList.au3>
    #include <GuiListView.au3>
    #include <GuiStatusBar.au3>
    #include <ListViewConstants.au3>
    #include <StructureConstants.au3>
    #include <WinAPIConv.au3>
    #include <WinAPIFiles.au3>
    #include <WinAPILocale.au3>
    #include <WinAPIRes.au3>
    #include <WinAPIShellEx.au3>
    #include <WinAPIShPath.au3>
    #include <WinAPISysWin.au3>
    
    
    Global $g_sPath = @ScriptDir ; <- hier das zu ueberwachende Verzeichnis eintragen
    If StringRight($g_sPath, 1) <> '\' Then $g_sPath &= '\'
    
    Global $g_iID = 0, $g_bStart = False
    Global $g_hBusyCur = _WinAPI_LoadCursorFromFile(@WindowsDir & '\Cursors\aero_busy_xl.ani') ; Busy-Animation-Cursor laden
    OnAutoItExitRegister('_OnAutoItExit')
    
    _WinAPI_FileIconInit()
    Global $g_bLargeIcons = True ; ob grosse oder kleine Icons benutzt werden sollen
    Global $g_hSystemImgList = _WinAPI_ShellGetImageList(Not $g_bLargeIcons) ; System-Imagelist holen
    
    Global $g_hGui = GUICreate('Verzeichnisüberwachung "' & $g_sPath & '"', 800, 600)
    
    Global $g_idFilelist = GUICtrlCreateListView('Name|Größe (Bytes)|Datum|Attr', 5, 5, 790, 565)
    GUICtrlSetFont(-1, 9 + $g_bLargeIcons * 3, 400, 0, 'Arial')
    GUICtrlSetBkColor(-1, 0xF8F8F8)
    _GUICtrlListView_SetColumnWidth($g_idFilelist, 0, 360)
    _GUICtrlListView_SetColumnWidth($g_idFilelist, 1, 150)
    _GUICtrlListView_SetColumnWidth($g_idFilelist, 2, 170)
    _GUICtrlListView_SetColumnWidth($g_idFilelist, 3, 70)
    _GUICtrlListView_JustifyColumn($g_idFilelist, 1, 1)
    _GUICtrlListView_SetImageList($g_idFilelist, $g_hSystemImgList, 1)
    
    Global $g_hStatus = _GUICtrlStatusBar_Create($g_hGui)
    
    Local $g_iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY')
    GUIRegisterMsg($g_iMsg, '_WM_SHELLCHANGENOTIFY')
    $g_iID = _WinAPI_ShellChangeNotifyRegister($g_hGui, $g_iMsg, $SHCNE_ALLEVENTS, _
            BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT), $g_sPath, False)
    
    GUISetState(@SW_SHOW, $g_hGui)
    _GetFilesFolder($g_idFilelist, $g_sPath) ; Bei Programmstart die Verzeichnisse/Dateien einlesen
    
    While True
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
        EndSwitch
    WEnd
    
    Func _OnAutoItExit()
        If $g_iID Then _WinAPI_ShellChangeNotifyDeregister($g_iID)
        If $g_hBusyCur Then _WinAPI_DestroyCursor($g_hBusyCur)
        _GUIImageList_Destroy($g_hSystemImgList)
    EndFunc   ;==>_OnAutoItExit
    
    Func _WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam)
        #forceref $hWnd, $iMsg, $wParam, $lParam
        If Not $g_bStart Then ; es koennen mehrere Events "gleichzeitig" erfolgen
            $g_bStart = True ; um dabei ein mehrfaches Einlesen zu verhindern
            AdlibRegister('_StartReading', 100) ; wird das Einlesen erst nach 100 ms aufgerufen
        EndIf
    EndFunc   ;==>_WM_SHELLCHANGENOTIFY
    
    Func _StartReading()
        AdlibUnRegister('_StartReading')
        _GetFilesFolder($g_idFilelist, $g_sPath)
        $g_bStart = False
    EndFunc   ;==>_StartReading
    
    Func _GetFilesFolder($idLV, $sPath)
        Local $tNUMBERFMT, $hOldCur, $aFolder, $aFiles, $iIndex
        $tNUMBERFMT = _WinAPI_CreateNumberFormatInfo(0, 1, 3, '', '.', 1)
        _GUICtrlListView_BeginUpdate($idLV)
        _GUICtrlListView_DeleteAllItems($idLV)
        $hOldCur = _WinAPI_SetCursor($g_hBusyCur)
        $aFolder = _WinAPI_EnumFiles($sPath, 2) ; Erst alle Verzeichnisse einlesen
        If Not @error Then
            Local $aNewItems[$aFolder[0][0]][5] ; 'Name|Groesse|Attr'
            For $i = 1 To $aFolder[0][0]
                $iIndex = _GUIImageList_GetFileIconIndex($sPath & $aFolder[$i][0], $g_bLargeIcons, True)
                $aNewItems[$i - 1][0] = $iIndex
                $aNewItems[$i - 1][1] = $aFolder[$i][0]
                $aNewItems[$i - 1][2] = '<DIR>'
                $aNewItems[$i - 1][3] = _DateTimeFormat(_GetDateTime($aFolder[$i][3]), 0)
                $aNewItems[$i - 1][4] = _GetAttrChars($aFolder[$i][6])
            Next
            _GUICtrlListView_AddArrayEx($idLV, $aNewItems)
        EndIf
        $aFiles = _WinAPI_EnumFiles($sPath, 1) ; danach alle Dateien einlesen
        If Not @error Then
            Local $aNewItems[$aFiles[0][0]][5] ; 'Name|Groesse|Attr'
            For $i = 1 To $aFiles[0][0]
                $iIndex = _GUIImageList_GetFileIconIndex($sPath & $aFiles[$i][0], $g_bLargeIcons, False)
                $aNewItems[$i - 1][0] = $iIndex
                $aNewItems[$i - 1][1] = $aFiles[$i][0]
                $aNewItems[$i - 1][2] = _WinAPI_GetNumberFormat(0, $aFiles[$i][4], $tNUMBERFMT)
                $aNewItems[$i - 1][3] = _DateTimeFormat(_GetDateTime($aFiles[$i][3]), 0)
                $aNewItems[$i - 1][4] = _GetAttrChars($aFiles[$i][6])
            Next
            _GUICtrlListView_AddArrayEx($idLV, $aNewItems)
        EndIf
        _WinAPI_SetCursor($hOldCur)
        _GUICtrlListView_EndUpdate($idLV)
        _GUICtrlStatusBar_SetText($g_hStatus, StringFormat('Letzte Änderung: %02i.%02i.%04i  %02i:%02i:%02i\r\n', @MDAY, @MON, @YEAR, @HOUR, @MIN, @SEC))
    EndFunc   ;==>_GetFilesFolder
    
    Func _GetAttrChars($iAttr)
        Local Const $aFA[][2] = [[$FILE_ATTRIBUTE_READONLY, 'R'], [$FILE_ATTRIBUTE_ARCHIVE, 'A'], _
                [$FILE_ATTRIBUTE_SYSTEM, 'S'], [$FILE_ATTRIBUTE_HIDDEN, 'H']]
        Local $sAttr = ''
        For $i = 0 To UBound($aFA) - 1
            $sAttr &= BitAND($iAttr, $aFA[$i][0]) ? $aFA[$i][1] : '-'
        Next
        Return $sAttr
    EndFunc   ;==>_GetAttrChars
    
    Func _GetDateTime($iDWord)
        Local $tFILETIME = DllStructCreate($tagFILETIME), $tLOCAL
        DllStructSetData($tFILETIME, 1, _WinAPI_LoDWord($iDWord))
        DllStructSetData($tFILETIME, 2, _WinAPI_HiDWord($iDWord))
        $tLOCAL = _Date_Time_FileTimeToLocalFileTime($tFILETIME)
        Return _Date_Time_FileTimeToStr($tLOCAL, 1)
    EndFunc   ;==>_GetDateTime
    
    Func _GUIImageList_GetFileIconIndex($sFilePath, $bLargeIcons = False, $bForceLoadFromDisk = False)
        Local $tFileInfo = DllStructCreate($tagSHFILEINFO)
        Local $iFlags = BitOR($SHGFI_SYSICONINDEX, _
                $bLargeIcons ? $SHGFI_LARGEICON : $SHGFI_SMALLICON, _
                $bForceLoadFromDisk ? 0 : $SHGFI_USEFILEATTRIBUTES)
        Local $ret = _WinAPI_ShellGetFileInfo($sFilePath, $iFlags, $FILE_ATTRIBUTE_NORMAL, $tFileInfo)
        If $ret Then Return DllStructGetData($tFileInfo, 'iIcon')
        Return SetError(1, 0, -1)
    EndFunc   ;==>_GUIImageList_GetFileIconIndex
    
    ; Bei dieser Version von _GUICtrlListView_AddArray kann man auch den Image-Index angeben
    Func _GUICtrlListView_AddArrayEx($hWnd, ByRef $aItems)
        Local $fUnicode, $tItem, $pItem, $tBuffer, $pBuffer, $iLastItem
        $fUnicode = _GUICtrlListView_GetUnicodeFormat($hWnd)
        $tItem = DllStructCreate($tagLVITEM)
        $pItem = DllStructGetPtr($tItem)
        If $fUnicode Then
            $tBuffer = DllStructCreate('wchar Text[4096]')
        Else
            $tBuffer = DllStructCreate('char Text[4096]')
        EndIf
        $pBuffer = DllStructGetPtr($tBuffer)
        DllStructSetData($tItem, 'Mask', BitOR($LVIF_TEXT, $LVIF_IMAGE)) ; <- $LVIF_IMAGE hinzugefügt
        DllStructSetData($tItem, 'Text', $pBuffer)
        DllStructSetData($tItem, 'TextMax', 4096)
        $iLastItem = _GUICtrlListView_GetItemCount($hWnd)
        For $i = 0 To UBound($aItems) - 1
            DllStructSetData($tItem, 'Item', $i + $iLastItem)
            DllStructSetData($tItem, 'SubItem', 0)
            DllStructSetData($tItem, 'Image', $aItems[$i][0]) ; <- Den Image-Index als Element 0 im Array
            DllStructSetData($tBuffer, 'Text', $aItems[$i][1])
            If $fUnicode Then
                GUICtrlSendMsg($hWnd, $LVM_INSERTITEMW, 0, $pItem)
            Else
                GUICtrlSendMsg($hWnd, $LVM_INSERTITEMA, 0, $pItem)
            EndIf
            For $j = 2 To UBound($aItems, 2) - 1
                DllStructSetData($tItem, 'SubItem', $j - 1)
                DllStructSetData($tBuffer, 'Text', $aItems[$i][$j])
                If $fUnicode Then
                    GUICtrlSendMsg($hWnd, $LVM_SETITEMW, 0, $pItem)
                Else
                    GUICtrlSendMsg($hWnd, $LVM_SETITEMA, 0, $pItem)
                EndIf
            Next
        Next
        $tItem = 0
        $tBuffer = 0
    EndFunc   ;==>_GUICtrlListView_AddArrayEx
    Alles anzeigen
  • Zeichensatz-Probleme beim Schreiben in MariaDB

    • Oscar
    • 24. Juni 2022 um 16:09

    Sorry, der Thread sollte gar nicht gelöscht werden. Es ging um den Thread von Johannes in "Übersetzung der Hilfe-Datei ins Deutsche".

    Irgendwie ist dabei (versehentlich) dieser Thread mit gelöscht worden. Große Entschuldigung an alle Teilnehmer!

  • Ip Aktualsierung funktionieert nicht

    • Oscar
    • 10. Juni 2022 um 18:55

    $IPLABEL wird nach Return deklariert (Lokal) und ist ganz sicher kein Label. Drei Fehler auf einmal.

    Statt dieses RBoxCreate zu benutzen, erstelle die GUI am Anfang mit globalen Variablen, dann sind sie überall verfügbar.

  • Ip Aktualsierung funktionieert nicht

    • Oscar
    • 10. Juni 2022 um 16:29

    Also diese Zeile GUICtrlSetData(_ActiveIP()) ist ja schon mal totaler Unsinn!

    Zum Einen muss die Ctrl-ID angegeben werden und zum Zweiten fabrizierst Du damit eine rekursive Endlosschleife (Abbruch mit Error, wegen Rekursionstiefe).

    Also überlege Dir welches Control-Element (Ctrl-ID) Du ansprechen willst und welchen Wert dieses bekommen soll.

  • Ip Aktualsierung funktionieert nicht

    • Oscar
    • 9. Juni 2022 um 18:33
    Zitat von casi4712

    Der isolierte Code sieht folgendermaßen aus:

    Echt jetzt?

    Da fehlt doch das ganze Script! Mit diesem Schnipsel kann man gar nichts anfangen.

    Wenn Du irgendwelche Fremd-UDFs einbindest, musst Du auch Diese mitposten.

    Und die vollständige Fehlermeldung (die bei Dir auftritt) fehlt auch, wie Moombas schon bemerkte.

  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 8. Juni 2022 um 05:17
    Zitat von HansJ54

    _GUICtrlListView_SetColumnWidth($__g_idArrayShow2D_LV, $iCol, $LVSCW_AUTOSIZE)

    Damit wird anscheinend automatisch die Spaltenbreite gesetzt, richtig?

    Ja!

    Zitat von HansJ54

    Was muss ich ändern, um da noch eine minimale Spaltenbreite vorzugeben?

    Einfach das $LVSCW_AUTOSIZE durch eine Pixelanzahl ersetzen.

    Oder ein Array mit den gewünschten Werten für jede Spalte.

  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 3. Juni 2022 um 05:05
    Zitat von HansJ54

    Ich würde Dich gerne zu einem Glas Bier (oder auch 2) einladen!

    Nett von Dir, aber dafür wohnen wir doch etwas weit auseinander. :)

    So toll ist meine Lösung auch gar nicht. Als UDF taugt sie nicht, wegen der globalen Variablen und der Benutzung von GUIRegisterMsg.

    Und es wird das angeklickte SubItem nicht markiert (optische Schwachstelle). Als Notlösung vielleicht trotzdem brauchbar.

  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 2. Juni 2022 um 19:33
    Zitat von HansJ54

    aber vielleicht gibt es ja eine Erweiterung von Zeile auf Feld?

    Naja, da wird's haarig!

    Man muss bei den SubItems dann tricksen:

    AutoIt
    #include <Array.au3>
    #include <AutoItConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <StructureConstants.au3>
    #include <WinAPIFiles.au3>
    #include <WinAPIShellEx.au3>
    #include <WindowsConstants.au3>
    
    Global $__g_idArrayShow2D_LV
    
    Local $aData = _WinAPI_EnumFiles(@SystemDir, 1, '*') ; als Beispiel fuer ein 2D-Array
    If @error Then Exit
    _ArrayDelete($aData, 0) ; Count in Array[0][0] entfernen
    _ArrayShow2D($aData, '0,4,6', 'Filelist') ; nur die Spalten 0, 4 und 6 anzeigen
    ;~ _ArrayDisplay($aData, 'Filelist')
    
    Func _ArrayShow2D_WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
        #forceref $hWnd, $iMsg, $wParam
        Local $tNMHDR, $iIDFrom, $iCode, $tNMITEMACTIVATE, $iIndex, $hParent, $iSubItem, $sToClip
        $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
        $iIDFrom = DllStructGetData($tNMHDR, 'IDFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')
        Switch $iIDFrom
            Case $__g_idArrayShow2D_LV
                Switch $iCode
                    Case $NM_DBLCLK
                        $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                        $iIndex = DllStructGetData($tNMITEMACTIVATE, 'Index')
                        If $iIndex > -1 Then
                            $hParent = _WinAPI_GetParent(GUICtrlGetHandle($__g_idArrayShow2D_LV))
                            $iSubItem = DllStructGetData($tNMITEMACTIVATE, 'SubItem')
                            $sToClip = ControlListView($hParent, '', $__g_idArrayShow2D_LV, 'GetText', $iIndex, $iSubItem)
                            ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sToClip = ' & $sToClip & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
                            ClipPut($sToClip)
                        EndIf
                EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
    EndFunc   ;==>_ArrayShow2D_WM_NOTIFY
    
    Func _ArrayShow2D(ByRef $aData, $sCols = '', $sTitle = 'ArrayShow2D')
        If UBound($aData, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(1, 0, 0)
        Local $aCols[1], $sHeader = _CreateColumnHeader($aData, $aCols, $sCols)
        Local $iH = @DesktopHeight - 100, $sItem, $iMode = Opt('GUIOnEventMode', 0)
        Local $hGui = GUICreate($sTitle, 800, $iH)
        $__g_idArrayShow2D_LV = GUICtrlCreateListView($sHeader, 5, 5, 790, $iH - 10, $LVS_SHOWSELALWAYS)
        Local $idContextmenu = GUICtrlCreateContextMenu($__g_idArrayShow2D_LV)
        Local $idCtxCopy = GUICtrlCreateMenuItem('Copy selected item(s) to clipboard', $idContextmenu)
        _GUICtrlListView_BeginUpdate($__g_idArrayShow2D_LV)
        For $iIndex = 0 To UBound($aData, $UBOUND_ROWS) - 1
            $sItem = 'Row ' & $iIndex & '|'
            For $iCol = 0 To UBound($aCols) - 1
                $sItem &= $aData[$iIndex][$aCols[$iCol]] & '|'
            Next
            GUICtrlCreateListViewItem(StringTrimRight($sItem, 1), $__g_idArrayShow2D_LV)
        Next
        For $iCol = 0 To UBound($aCols) - 1
            _GUICtrlListView_SetColumnWidth($__g_idArrayShow2D_LV, $iCol, $LVSCW_AUTOSIZE)
        Next
        _GUICtrlListView_EndUpdate($__g_idArrayShow2D_LV)
        GUISetState()
        GUIRegisterMsg($WM_NOTIFY, '_ArrayShow2D_WM_NOTIFY')
        Local $sSelIndices, $aIndices, $sToClip
        While True
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    ExitLoop
                Case $idCtxCopy
                    $sSelIndices = ControlListView($hGui, '', $__g_idArrayShow2D_LV, 'GetSelected', 1)
                    If $sSelIndices Then
                        $aIndices = StringSplit($sSelIndices, '|', 2)
                        $sToClip = ''
                        For $iItem In $aIndices
                            $sToClip &= _GUICtrlListView_GetItemTextString(GUICtrlGetHandle($__g_idArrayShow2D_LV), $iItem) & @CRLF
                        Next
                        ClipPut($sToClip)
                    EndIf
            EndSwitch
        WEnd
        GUIDelete($hGui)
        Opt('GUIOnEventMode', $iMode)
    EndFunc   ;==>_ArrayShow2D
    
    Func _CreateColumnHeader(ByRef $aData, ByRef $aCols, $sCols)
        Local $sHeader = 'Row|'
        If $sCols = '' Then
            ReDim $aCols[UBound($aData, $UBOUND_COLUMNS)]
            For $i = 0 To UBound($aData, $UBOUND_COLUMNS) - 1
                $aCols[$i] = $i
            Next
        Else
            $aCols = StringSplit($sCols, ',', 2)
        EndIf
        For $i = 0 To UBound($aCols) - 1
            $sHeader &= 'Col' & $aCols[$i] & '|'
        Next
        Return StringTrimRight($sHeader, 1)
    EndFunc   ;==>_CreateColumnHeader
    Alles anzeigen
  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 2. Juni 2022 um 14:14
    Zitat von HansJ54

    Wenn wir schon mal dabei sind: in einigen Fällen wäre es hilfreich, wenn ich einen Eintrag markieren und kopieren könnte. Das geht mit diesem Beispiel nicht, gibt es da noch eine Möglichkeit?

    Klar! Sind nur ein paar Zeilen mehr:

    AutoIt
    #include <Array.au3>
    #include <AutoItConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <WinAPIFiles.au3>
    
    Local $aData = _WinAPI_EnumFiles(@SystemDir, 1, '*') ; als Beispiel fuer ein 2D-Array
    If @error Then Exit
    _ArrayDelete($aData, 0) ; Count in Array[0][0] entfernen
    _ArrayShow2D($aData, '0,4,6', 'Filelist') ; nur die Spalten 0, 4 und 6 anzeigen
    ;~ _ArrayDisplay($aData, 'Filelist')
    
    Func _ArrayShow2D(ByRef $aData, $sCols = '', $sTitle = 'ArrayShow2D')
        If UBound($aData, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(1, 0, 0)
        Local $aCols[1], $sHeader = _CreateColumnHeader($aData, $aCols, $sCols)
        Local $iH = @DesktopHeight - 100, $sItem, $iMode = Opt('GUIOnEventMode', 0)
        Local $hGui = GUICreate($sTitle, 800, $iH)
        Local $idLV = GUICtrlCreateListView($sHeader, 5, 5, 790, $iH - 10, $LVS_SHOWSELALWAYS)
        Local $idContextmenu = GUICtrlCreateContextMenu($idLV)
        Local $idCtxCopy = GUICtrlCreateMenuItem('Copy selected item(s) to clipboard', $idContextmenu)
        _GUICtrlListView_BeginUpdate($idLV)
        For $iIndex = 0 To UBound($aData, $UBOUND_ROWS) - 1
            $sItem = 'Row ' & $iIndex & '|'
            For $iCol = 0 To UBound($aCols) - 1
                $sItem &= $aData[$iIndex][$aCols[$iCol]] & '|'
            Next
            GUICtrlCreateListViewItem(StringTrimRight($sItem, 1), $idLV)
        Next
        For $iCol = 0 To UBound($aCols) - 1
            _GUICtrlListView_SetColumnWidth($idLV, $iCol, $LVSCW_AUTOSIZE)
        Next
        _GUICtrlListView_EndUpdate($idLV)
        GUISetState()
        Local $sSelIndices, $aIndices, $sToClip
        While True
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    ExitLoop
                Case $idCtxCopy
                    $sSelIndices = ControlListView($hGui, '', $idLV, 'GetSelected', 1)
                    If $sSelIndices Then
                        $aIndices = StringSplit($sSelIndices, '|', 2)
                        $sToClip = ''
                        For $iItem In $aIndices
                            $sToClip &= _GUICtrlListView_GetItemTextString(GUICtrlGetHandle($idLV), $iItem) & @CRLF
                        Next
                        ClipPut($sToClip)
                    EndIf
            EndSwitch
        WEnd
        GUIDelete($hGui)
        Opt('GUIOnEventMode', $iMode)
    EndFunc   ;==>_ArrayShow2D
    
    Func _CreateColumnHeader(ByRef $aData, ByRef $aCols, $sCols)
        Local $sHeader = 'Row|'
        If $sCols = '' Then
            ReDim $aCols[UBound($aData, $UBOUND_COLUMNS)]
            For $i = 0 To UBound($aData, $UBOUND_COLUMNS) - 1
                $aCols[$i] = $i
            Next
        Else
            $aCols = StringSplit($sCols, ',', 2)
        EndIf
        For $i = 0 To UBound($aCols) - 1
            $sHeader &= 'Col' & $aCols[$i] & '|'
        Next
        Return StringTrimRight($sHeader, 1)
    EndFunc   ;==>_CreateColumnHeader
    Alles anzeigen
  • GUI flackert

    • Oscar
    • 30. Mai 2022 um 07:53
    Zitat von Tweaky

    Wenn man das Skript startet ist zu Beginn ganz ganz kurz die Lupe weiß und zeigt dann erst das Bild an.

    Was hast Du für einen langsamen Rechner? SCNR ;)

    Ich musste erstmal ein Sleep(1000) einfügen, um zu verstehen, was Du meinst.

    Also falls Dich das wirklich stört, kannst Du eine zusätzliche Zeile einfügen:

    AutoIt
    [...]    
    Local $aOldPos[4] = [$iVSX, $iVSY, 0, 0], $aInfo[5], $aSelCoord[4] = [0, 0, 0, 0], $iX, $iY
    _ShowMagnifier($hMagnifier, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY) ; <- die hier
    [...]
  • GUI flackert

    • Oscar
    • 28. Mai 2022 um 11:08
    Zitat von Velted

    Dazu ist mir nach längerem Herumprobieren wieder eingefallen, dass es auch ohne GDI-Bitmap geht, wenn man anstelle der GDIP-Bitmap eine GDI-DIBSECTION verwendet.

    Ah, sehr interessant! :thumbup:

    Ich habe das mal übernommen und noch eine Capture-Funktion zum testen der Koordinaten eingebaut:

    AutoIt
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <ScreenCapture.au3>
    #include <SendMessage.au3>
    #include <StaticConstants.au3>
    #include <StructureConstants.au3>
    #include <WinAPIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <WinAPIGdiDC.au3>
    #include <WinAPIGdiInternals.au3>
    #include <WinAPIHObj.au3>
    #include <WinAPIInternals.au3>
    #include <WinAPISysInternals.au3>
    #include <WinAPISysWin.au3>
    #include <WindowsConstants.au3>
    
    _GDIPlus_Startup()
    
    Global $aSelect = _SelectRange() ; Rueckgabe: Array[Left, Top, Width, Height]
    ;~ _ArrayDisplay($aSelect)
    
    _Testfunc($aSelect)
    
    _GDIPlus_Shutdown()
    
    Func _Testfunc($aSelect)
        Local $hHBitmap, $iW = 1280, $iH = 960, $hShowGui, $idPic, $hPic
        Local $hImage, $hResize, $aDim, $iScaleF = 1, $iScaleW, $iScaleH, $hBMP, $hPrevImage
        $hHBitmap = _ScreenCapture_Capture('', $aSelect[0], $aSelect[1], $aSelect[0] + $aSelect[2], $aSelect[1] + $aSelect[3], False)
        _ScreenCapture_SaveImage(@ScriptDir & '\TestCapture.jpg', $hHBitmap, False)
        $hShowGui = GUICreate('Test', $iW, $iH)
        $idPic = GUICtrlCreatePic('', 0, 0, $iW, $iH)
        $hPic = GUICtrlGetHandle($idPic)
        $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
        $aDim = _GDIPlus_ImageGetDimension($hImage)
        If ($iW < $aDim[0] Or $iH < $aDim[1]) Then
            $iScaleW = $iW / $aDim[0]
            $iScaleH = $iH / $aDim[1]
            $iScaleF = ($iScaleW > $iScaleH ? $iScaleH : $iScaleW)
        EndIf
        $hResize = _GDIPlus_ImageScale($hImage, $iScaleF, $iScaleF)
        $hBMP = _GDIPlus_BitmapCreateDIBFromBitmap($hResize)
        $hPrevImage = _SendMessage($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP)
        If $hPrevImage Then _WinAPI_DeleteObject($hPrevImage)
        _GDIPlus_BitmapDispose($hResize)
        _GDIPlus_ImageDispose($hImage)
        GUISetState(@SW_SHOW, $hShowGui)
        Do
        Until GUIGetMsg() = -3
        _WinAPI_DeleteObject($hHBitmap)
    EndFunc   ;==>_Testfunc
    
    Func _SelectRange($iCrossW = 3, $iCrossColor = 0xFF0000FF, $iSelColor = 0x40FFFF00)
        Local Const $iVSX = _WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN)
        Local Const $iVSY = _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN)
        Local Const $iVSW = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN)
        Local Const $iVSH = _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)
    
        Local $hBgGui = GUICreate('FullScreen', $iVSW, $iVSH, $iVSX, $iVSY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_LAYERED))
        Local $hMagnifier = GUICreate('Magnifier', 200, 200, 0, 0, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW, $hBgGui)
    
        Local $hSrcDC = _WinAPI_CreateCompatibleDC(0)
        Local $hDIB = _WinAPI_CopyImage(_WinAPI_CreateBitmap($iVSW, $iVSH, 1, 32), $IMAGE_BITMAP, 0, 0, BitOR($LR_COPYDELETEORG, $LR_CREATEDIBSECTION))
        Local $hOld = _WinAPI_SelectObject($hSrcDC, $hDIB)
        If $hOld Then _WinAPI_DeleteObject($hOld)
        Local $pGraphics = _GDIPlus_GraphicsCreateFromHDC($hSrcDC)
    
        Local $hPen = _GDIPlus_PenCreate($iCrossColor, $iCrossW)
        Local $hBrush = _GDIPlus_BrushCreateSolid($iSelColor)
        Local $hPen2 = _GDIPlus_PenCreate(BitXOR($iSelColor, 0xFFFFFF))
    
        Local $tSize = DllStructCreate($tagSIZE)
        Local $pSize = DllStructGetPtr($tSize)
        $tSize.X = $iVSW
        $tSize.Y = $iVSH
        Local $tPtSrc = DllStructCreate($tagPOINT)
        Local $pPtSrc = DllStructGetPtr($tPtSrc)
        $tPtSrc.X = 0
        $tPtSrc.Y = 0
        Local $tBlend = DllStructCreate($tagBLENDFUNCTION)
        Local $pBlend = DllStructGetPtr($tBlend)
        $tBlend.Alpha = 255
        $tBlend.Format = 1
    
        GUISetCursor(16, 1, $hBgGui)
        GUISetCursor(16, 1, $hMagnifier)
        GUISetState(@SW_SHOW, $hBgGui)
        GUISetState(@SW_SHOW, $hMagnifier)
    
        Local $aOldPos[4] = [$iVSX, $iVSY, 0, 0], $aInfo[5], $aSelCoord[4] = [0, 0, 0, 0], $iX, $iY
        Do
            $aInfo = GUIGetCursorInfo($hBgGui)
            If $aInfo[2] Then ; wenn linke Maustaste gedrueckt
                If Not $aOldPos[2] Then ; wenn vorher nicht gedrueckt
                    $aOldPos[2] = 1
                    $aSelCoord[0] = $aInfo[0]
                    $aSelCoord[1] = $aInfo[1]
                EndIf
                $aSelCoord[2] = Abs($aInfo[0] - $aSelCoord[0])
                $aSelCoord[3] = Abs($aInfo[1] - $aSelCoord[1])
                $iX = $aInfo[0] > $aSelCoord[0] ? $aSelCoord[0] : $aSelCoord[0] - $aSelCoord[2]
                $iY = $aInfo[1] > $aSelCoord[1] ? $aSelCoord[1] : $aSelCoord[1] - $aSelCoord[3]
            Else ; wenn linke Maustaste losgelassen
                $aOldPos[2] = 0
            EndIf
            If $aInfo[0] <> $aOldPos[0] Or $aInfo[1] <> $aOldPos[1] Then
                $aOldPos[0] = $aInfo[0]
                $aOldPos[1] = $aInfo[1]
                If $aInfo[0] < 200 And $aInfo[1] < 200 Then
                    If $aOldPos[3] = 0 Then
                        WinMove($hMagnifier, '', @DesktopWidth - 202, 0)
                        $aOldPos[3] = 1
                    EndIf
                Else
                    If $aOldPos[3] = 1 Then
                        WinMove($hMagnifier, '', 0, 0)
                        $aOldPos[3] = 0
                    EndIf
                EndIf
                _GDIPlus_GraphicsClear($pGraphics, 0x08FFFFFF)
                _GDIPlus_GraphicsFillRect($pGraphics, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hBrush)
                _GDIPlus_GraphicsDrawRect($pGraphics, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hPen2)
                _GDIPlus_GraphicsDrawLine($pGraphics, $iVSX, $aInfo[1], $iVSW, $aInfo[1], $hPen)
                _GDIPlus_GraphicsDrawLine($pGraphics, $aInfo[0], $iVSY, $aInfo[0], $iVSH, $hPen)
                _WinAPI_UpdateLayeredWindow($hBgGui, 0, 0, $pSize, $hSrcDC, $pPtSrc, 0, $pBlend, $ULW_ALPHA)
                _ShowMagnifier($hMagnifier, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY)
            EndIf
            Sleep(10)
        Until $aInfo[3] ; warten, bis rechte Maustaste gedrueckt
        Do
            $aInfo = GUIGetCursorInfo($hBgGui)
        Until Not $aInfo[3] ; warten, bis rechte Maustaste wieder losgelassen
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_PenDispose($hPen2)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_GraphicsDispose($pGraphics)
        _WinAPI_DeleteObject($hDIB)
        _WinAPI_DeleteDC($hSrcDC)
        GUIDelete($hBgGui)
        GUIDelete($hMagnifier)
        $aSelCoord[0] = $iX + $iVSX
        $aSelCoord[1] = $iY + $iVSY
        Return $aSelCoord
    EndFunc   ;==>_SelectRange
    
    Func _ShowMagnifier($hWnd, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY)
        Local $iRight = $iVSX + $iVSW, $iBottom = $iVSY + $iVSH
        Local $hSrcDC, $hDestDC, $iLeft, $iTop
        $hDestDC = _WinAPI_GetDC($hWnd)
        If @error Then Return
        $hSrcDC = _WinAPI_GetDC(0)
        If Not @error Then
            $iLeft = $aInfo[0] - 25 + $iVSX
            If $iLeft < $iVSX Then $iLeft = $iVSX
            If $iLeft + 50 > $iRight Then $iLeft = $iRight - 50
            $iTop = $aInfo[1] - 25 + $iVSY
            If $iTop < $iVSY Then $iTop = $iVSY
            If $iTop + 50 > $iBottom Then $iTop = $iBottom - 50
            _WinAPI_StretchBlt($hDestDC, 0, 0, 200, 200, $hSrcDC, $iLeft, $iTop, 50, 50, $SRCCOPY)
            _WinAPI_ReleaseDC(0, $hDestDC)
        EndIf
        _WinAPI_ReleaseDC($hWnd, $hSrcDC)
    EndFunc   ;==>_ShowMagnifier
    Alles anzeigen

    Edit: Da war noch ein Fehler drin! Bei den Koordinaten stimmten die Werte nicht, wenn man die Auswahl nicht von oben/links vorgenommen hat.

  • GUI flackert

    • Oscar
    • 26. Mai 2022 um 15:04
    Zitat von Velted

    ein Vorschlag zur Synchronisierung (es läuft damit jedenfalls auf meinem Rechner besser):

    Ja, Du hast recht! Damit läuft es besser. :thumbup:

    Und damit die Prozessorlast noch etwas runtergeht, kann man das Update auch nur bei einer Bewegung ausführen (reicht ja):

    AutoIt
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <StructureConstants.au3>
    #include <WinAPIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <WinAPIGdiDC.au3>
    #include <WinAPIHObj.au3>
    #include <WinAPISysInternals.au3>
    #include <WinAPISysWin.au3>
    #include <WindowsConstants.au3>
    
    _GDIPlus_Startup()
    
    Global $aSelect = _SelectRange() ; Rueckgabe: Array[Left, Top, Width, Height]
    ;~ _ArrayDisplay($aSelect)
    
    _GDIPlus_Shutdown()
    
    Func _SelectRange($iCrossW = 3, $iCrossColor = 0xFF0000FF, $iSelColor = 0x40FFFF00)
        Local $iVSX = _WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN)
        Local $iVSY = _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN)
        Local $iVSW = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN)
        Local $iVSH = _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)
    
        Local $hBgGui = GUICreate('FullScreen', $iVSW, $iVSH, $iVSX, $iVSY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_LAYERED))
        Local $hMagnifier = GUICreate('Magnifier', 200, 200, 0, 0, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW, $hBgGui)
    
        Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hBgGui)
        Local $hBuffer = _GDIPlus_BitmapCreateFromGraphics($iVSW, $iVSH, $hGraphic)
        Local $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBuffer)
        Local $hPen = _GDIPlus_PenCreate($iCrossColor, $iCrossW)
        Local $hBrush = _GDIPlus_BrushCreateSolid($iSelColor)
        Local $hPen2 = _GDIPlus_PenCreate(BitXOR($iSelColor, 0xFFFFFF))
    
        Local $tSize = DllStructCreate($tagSIZE)
        Local $pSize = DllStructGetPtr($tSize)
        DllStructSetData($tSize, "X", $iVSW)
        DllStructSetData($tSize, "Y", $iVSH)
        Local $tSource = DllStructCreate($tagPOINT)
        Local $pSource = DllStructGetPtr($tSource)
        DllStructSetData($tSource, "X", 0)
        DllStructSetData($tSource, "Y", 0)
        Local $tBlend = DllStructCreate($tagBLENDFUNCTION)
        Local $pBlend = DllStructGetPtr($tBlend)
        DllStructSetData($tBlend, "Alpha", 255) ; $iOpacity
        DllStructSetData($tBlend, "Format", 1)
        Local $hScrDC = _WinAPI_GetDC($hBgGui)
        Local $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
        Local $hBitmap, $hOld
    
        GUISetCursor(16, 1, $hBgGui)
        GUISetCursor(16, 1, $hMagnifier)
        GUISetState(@SW_SHOW, $hBgGui)
        GUISetState(@SW_SHOW, $hMagnifier)
    
        Local $aOldPos[4] = [$iVSX, $iVSY, 0, 0], $aInfo[5], $aSelCoord[4] = [0, 0, 0, 0], $iX, $iY
        Do
            $aInfo = GUIGetCursorInfo($hBgGui)
            If $aInfo[2] Then ; wenn linke Maustaste gedrueckt
                If Not $aOldPos[2] Then ; wenn vorher nicht gedrueckt
                    $aOldPos[2] = 1
                    $aSelCoord[0] = $aInfo[0]
                    $aSelCoord[1] = $aInfo[1]
                EndIf
                $aSelCoord[2] = Abs($aInfo[0] - $aSelCoord[0])
                $aSelCoord[3] = Abs($aInfo[1] - $aSelCoord[1])
                $iX = $aInfo[0] > $aSelCoord[0] ? $aSelCoord[0] : $aSelCoord[0] - $aSelCoord[2]
                $iY = $aInfo[1] > $aSelCoord[1] ? $aSelCoord[1] : $aSelCoord[1] - $aSelCoord[3]
            Else ; wenn linke Maustaste losgelassen
                $aOldPos[2] = 0
            EndIf
            If $aInfo[0] <> $aOldPos[0] Or $aInfo[1] <> $aOldPos[1] Then
                $aOldPos[0] = $aInfo[0]
                $aOldPos[1] = $aInfo[1]
                If $aInfo[0] < 200 And $aInfo[1] < 200 Then
                    If $aOldPos[3] = 0 Then
                        WinMove($hMagnifier, '', @DesktopWidth - 202, 0)
                        $aOldPos[3] = 1
                    EndIf
                Else
                    If $aOldPos[3] = 1 Then
                        WinMove($hMagnifier, '', 0, 0)
                        $aOldPos[3] = 0
                    EndIf
                EndIf
                _GDIPlus_GraphicsClear($hGfxBuffer, 0x08FFFFFF)
                _GDIPlus_GraphicsFillRect($hGfxBuffer, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hBrush)
                _GDIPlus_GraphicsDrawRect($hGfxBuffer, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hPen2)
                _GDIPlus_GraphicsDrawLine($hGfxBuffer, $iVSX, $aInfo[1], $iVSW, $aInfo[1], $hPen)
                _GDIPlus_GraphicsDrawLine($hGfxBuffer, $aInfo[0], $iVSY, $aInfo[0], $iVSH, $hPen)
                $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBuffer)
                $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
                _WinAPI_UpdateLayeredWindow($hBgGui, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
                _ShowMagnifier($hMagnifier, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY)
            EndIf
            If $hOld Then _WinAPI_DeleteObject($hOld)
            Sleep(10)
        Until $aInfo[3] ; warten, bis rechte Maustaste gedrueckt
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_PenDispose($hPen2)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_GraphicsDispose($hGfxBuffer)
        _GDIPlus_BitmapDispose($hBuffer)
        _GDIPlus_GraphicsDispose($hGraphic)
        _WinAPI_DeleteObject($hBitmap)
        _WinAPI_ReleaseDC($hBgGui, $hScrDC)
        _WinAPI_DeleteDC($hMemDC)
        GUIDelete($hBgGui)
        GUIDelete($hMagnifier)
        $aSelCoord[0] += $iVSX
        $aSelCoord[1] += $iVSY
        Return $aSelCoord
    EndFunc   ;==>_SelectRange
    
    Func _ShowMagnifier($hWnd, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY)
        Local $iRight = $iVSX + $iVSW, $iBottom = $iVSY + $iVSH
        Local $hSrcDC, $hDestDC, $iLeft, $iTop
        $hDestDC = _WinAPI_GetDC($hWnd)
        If @error Then Return
        $hSrcDC = _WinAPI_GetDC(0)
        If Not @error Then
            $iLeft = $aInfo[0] - 25
            If $iLeft < 0 Then $iLeft = 0
            If $iLeft + 50 > $iRight Then $iLeft = $iRight - 50
            $iTop = $aInfo[1] - 25
            If $iTop < 0 Then $iTop = 0
            If $iTop + 50 > $iBottom Then $iTop = $iBottom - 50
            _WinAPI_StretchBlt($hDestDC, 0, 0, 200, 200, $hSrcDC, $iLeft, $iTop, 50, 50, $SRCCOPY)
            _WinAPI_ReleaseDC(0, $hDestDC)
        EndIf
        _WinAPI_ReleaseDC($hWnd, $hSrcDC)
    EndFunc   ;==>_ShowMagnifier
    Alles anzeigen
  • GUI flackert

    • Oscar
    • 25. Mai 2022 um 18:12
    Zitat von Velted

    ich meinte das so. Es beruht allerdings auf einer Version ohne Lupe:

    Ok, das ist super!

    Ich habe mal noch die Lupe hinzugefügt und den Cursor entfernt (wird ja eigentlich nicht gebraucht bei dem Fadenkreuz):

    AutoIt
    #include <Array.au3>
    #include <GDIPlus.au3>
    #include <StructureConstants.au3>
    #include <WinAPIConstants.au3>
    #include <WinAPIGdi.au3>
    #include <WinAPIGdiDC.au3>
    #include <WinAPIHObj.au3>
    #include <WinAPISysInternals.au3>
    #include <WinAPISysWin.au3>
    #include <WindowsConstants.au3>
    
    _GDIPlus_Startup()
    
    Global $aSelect = _SelectRange() ; Rueckgabe: Array[Left, Top, Width, Height]
    ;~ _ArrayDisplay($aSelect)
    
    _GDIPlus_Shutdown()
    
    Func _SelectRange($iCrossW = 3, $iCrossColor = 0x800000FF, $iSelColor = 0x40FF0000)
        Local $iVSX = _WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN)
        Local $iVSY = _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN)
        Local $iVSW = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN)
        Local $iVSH = _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)
    
        Local $hBgGui = GUICreate('FullScreen', $iVSW, $iVSH, $iVSX, $iVSY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_LAYERED))
        Local $hMagnifier = GUICreate('Magnifier', 200, 200, 0, 0, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW, $hBgGui)
    
        Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hBgGui)
        Local $hBuffer = _GDIPlus_BitmapCreateFromGraphics($iVSW, $iVSH, $hGraphic)
        Local $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBuffer)
        Local $hPen = _GDIPlus_PenCreate($iCrossColor, $iCrossW)
        Local $hBrush = _GDIPlus_BrushCreateSolid($iSelColor)
        Local $hPen2 = _GDIPlus_PenCreate(BitXOR($iSelColor, 0xFFFFFF))
    
        Local $tSize = DllStructCreate($tagSIZE)
        Local $pSize = DllStructGetPtr($tSize)
        DllStructSetData($tSize, "X", $iVSW)
        DllStructSetData($tSize, "Y", $iVSH)
        Local $tSource = DllStructCreate($tagPOINT)
        Local $pSource = DllStructGetPtr($tSource)
        DllStructSetData($tSource, "X", 0)
        DllStructSetData($tSource, "Y", 0)
        Local $tBlend = DllStructCreate($tagBLENDFUNCTION)
        Local $pBlend = DllStructGetPtr($tBlend)
        DllStructSetData($tBlend, "Alpha", 255) ; $iOpacity
        DllStructSetData($tBlend, "Format", 1)
        Local $hScrDC = _WinAPI_GetDC($hBgGui)
        Local $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
        Local $hBitmap, $hOld
    
        GUISetCursor(16, 1, $hBgGui)
        GUISetCursor(16, 1, $hMagnifier)
        GUISetState(@SW_SHOW, $hBgGui)
        GUISetState(@SW_SHOW, $hMagnifier)
    
        Local $aOldPos[4] = [$iVSX, $iVSY, 0, 0], $aInfo[5], $aSelCoord[4] = [0, 0, 0, 0], $iX, $iY
        Do
            $aInfo = GUIGetCursorInfo($hBgGui)
            If $aInfo[0] <> $aOldPos[0] Or $aInfo[1] <> $aOldPos[1] Then
                $aOldPos[0] = $aInfo[0]
                $aOldPos[1] = $aInfo[1]
                If $aInfo[0] < 200 And $aInfo[1] < 200 Then
                    If $aOldPos[3] = 0 Then
                        WinMove($hMagnifier, '', @DesktopWidth - 202, 0)
                        $aOldPos[3] = 1
                    EndIf
                Else
                    If $aOldPos[3] = 1 Then
                        WinMove($hMagnifier, '', 0, 0)
                        $aOldPos[3] = 0
                    EndIf
                EndIf
                _ShowMagnifier($hMagnifier, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY)
            EndIf
            If $aInfo[2] Then ; wenn linke Maustaste gedrueckt
                If Not $aOldPos[2] Then ; wenn vorher nicht gedrueckt
                    $aOldPos[2] = 1
                    $aSelCoord[0] = $aInfo[0]
                    $aSelCoord[1] = $aInfo[1]
                EndIf
                $aSelCoord[2] = Abs($aInfo[0] - $aSelCoord[0])
                $aSelCoord[3] = Abs($aInfo[1] - $aSelCoord[1])
                $iX = $aInfo[0] > $aSelCoord[0] ? $aSelCoord[0] : $aSelCoord[0] - $aSelCoord[2]
                $iY = $aInfo[1] > $aSelCoord[1] ? $aSelCoord[1] : $aSelCoord[1] - $aSelCoord[3]
            Else ; wenn linke Maustaste losgelassen
                $aOldPos[2] = 0
            EndIf
            _GDIPlus_GraphicsClear($hGfxBuffer, 0x08FFFFFF)
            _GDIPlus_GraphicsFillRect($hGfxBuffer, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hBrush)
            _GDIPlus_GraphicsDrawRect($hGfxBuffer, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hPen2)
            _GDIPlus_GraphicsDrawLine($hGfxBuffer, $iVSX, $aInfo[1], $iVSW, $aInfo[1], $hPen)
            _GDIPlus_GraphicsDrawLine($hGfxBuffer, $aInfo[0], $iVSY, $aInfo[0], $iVSH, $hPen)
            $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBuffer)
            $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
            _WinAPI_UpdateLayeredWindow($hBgGui, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
            If $hOld Then _WinAPI_DeleteObject($hOld)
            Sleep(1)
        Until $aInfo[3] ; warten, bis rechte Maustaste gedrueckt
        _GDIPlus_PenDispose($hPen)
        _GDIPlus_PenDispose($hPen2)
        _GDIPlus_BrushDispose($hBrush)
        _GDIPlus_GraphicsDispose($hGfxBuffer)
        _GDIPlus_BitmapDispose($hBuffer)
        _GDIPlus_GraphicsDispose($hGraphic)
        _WinAPI_DeleteObject($hBitmap)
        _WinAPI_ReleaseDC($hBgGui, $hScrDC)
        _WinAPI_DeleteDC($hMemDC)
        GUIDelete($hBgGui)
        GUIDelete($hMagnifier)
        $aSelCoord[0] += $iVSX
        $aSelCoord[1] += $iVSY
        Return $aSelCoord
    EndFunc   ;==>_SelectRange
    
    Func _ShowMagnifier($hWnd, $aInfo, $iVSW, $iVSH, $iVSX, $iVSY)
        Local $iRight = $iVSX + $iVSW, $iBottom = $iVSY + $iVSH
        Local $hSrcDC, $hDestDC, $iLeft, $iTop
        $hDestDC = _WinAPI_GetDC($hWnd)
        If @error Then Return
        $hSrcDC = _WinAPI_GetDC(0)
        If Not @error Then
            $iLeft = $aInfo[0] - 25
            If $iLeft < 0 Then $iLeft = 0
            If $iLeft + 50 > $iRight Then $iLeft = $iRight - 50
            $iTop = $aInfo[1] - 25
            If $iTop < 0 Then $iTop = 0
            If $iTop + 50 > $iBottom Then $iTop = $iBottom - 50
            _WinAPI_StretchBlt($hDestDC, 0, 0, 200, 200, $hSrcDC, $iLeft, $iTop, 50, 50, $SRCCOPY)
            _WinAPI_ReleaseDC(0, $hDestDC)
        EndIf
        _WinAPI_ReleaseDC($hWnd, $hSrcDC)
    EndFunc   ;==>_ShowMagnifier
    Alles anzeigen
  • GUI flackert

    • Oscar
    • 24. Mai 2022 um 10:50
    Zitat von Velted

    Man könnte allerdings auf das Dummy-GUI komplett verzichten und die Tranzparenz von Hintergrund, Auswahlrechteck und Fadenkreuz im FullScreen-GUI direkt und auch unterschiedlich vorgeben.

    Das ist mir nicht ganz klar. Wie kann man die Teile unterschiedlich transparent darstellen?

    Ich habe das Script jetzt mal dahingehend umgestellt (Anhang), dass der Mauszeiger als Bitmap auf die Graphic gezeichnet und der Original-Mauszeiger versteckt wird. Das verhindert die Latenz, die durch die AutoIt-Befehle auftreten.

    Dateien

    _SelectRange.au3 5,27 kB – 225 Downloads
  • GUI flackert

    • Oscar
    • 22. Mai 2022 um 16:26
    Zitat von Tweaky

    Ich würde gerne das abdunkeln des Hintergrunds abschalten.

    Hmm...das Auswahlrechteck soll ja halbtransparent sein. Im Moment fällt mir dazu keine Lösung ein.

    Zitat von Tweaky

    Ist es möglich die Lupe ohne das Fadenkreuz darzustellen?

    Wozu? Ich finde es gerade hilfreich, wenn man das Fadenkreuz auch in der Lupe sieht.

    Das "nachlaufen" kann man einfach beheben. Außerdem habe ich mal noch ein paar Fehler beseitigt (Script im Anhang).

    Dateien

    _SelectRange.au3 5,56 kB – 208 Downloads
  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 21. Mai 2022 um 17:18

    Ich habe mal ein Beispiel erstellt:

    AutoIt
    #include <Array.au3>
    #include <AutoItConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>
    #include <ListViewConstants.au3>
    #include <WinAPIFiles.au3>
    
    Local $aData = _WinAPI_EnumFiles(@SystemDir, 1, '*') ; als Beispiel fuer ein 2D-Array
    If @error Then Exit
    _ArrayDelete($aData, 0) ; Count in Array[0][0] entfernen
    _ArrayShow2D($aData, '0,4,6', 'Filelist') ; nur die Spalten 0, 4 und 6 anzeigen
    ;~ _ArrayDisplay($aData, 'Filelist')
    
    Func _ArrayShow2D(ByRef $aData, $sCols = '', $sTitle = 'ArrayShow2D')
        If UBound($aData, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(1, 0, 0)
        Local $aCols[1], $sHeader = _CreateColumnHeader($aData, $aCols, $sCols)
        Local $iH = @DesktopHeight - 100, $sItem, $iMode = Opt('GUIOnEventMode', 0)
        Local $hGui = GUICreate($sTitle, 800, $iH)
        Local $idLV = GUICtrlCreateListView($sHeader, 5, 5, 790, $iH - 10)
        _GUICtrlListView_BeginUpdate($idLV)
        For $iIndex = 0 To UBound($aData, $UBOUND_ROWS) - 1
            $sItem = 'Row ' & $iIndex & '|'
            For $iCol = 0 To UBound($aCols) - 1
                $sItem &= $aData[$iIndex][$aCols[$iCol]] & '|'
            Next
            GUICtrlCreateListViewItem(StringTrimRight($sItem, 1), $idLV)
        Next
        For $iCol = 0 To UBound($aCols) - 1
            _GUICtrlListView_SetColumnWidth($idLV, $iCol, $LVSCW_AUTOSIZE)
        Next
        _GUICtrlListView_EndUpdate($idLV)
        GUISetState()
        Do
        Until GUIGetMsg() = $GUI_EVENT_CLOSE
        GUIDelete($hGui)
        Opt('GUIOnEventMode', $iMode)
    EndFunc   ;==>_ArrayShow2D
    
    Func _CreateColumnHeader(ByRef $aData, ByRef $aCols, $sCols)
        Local $sHeader = 'Row|'
        If $sCols = '' Then
            ReDim $aCols[UBound($aData, $UBOUND_COLUMNS)]
            For $i = 0 To UBound($aData, $UBOUND_COLUMNS) - 1
                $aCols[$i] = $i
            Next
        Else
            $aCols = StringSplit($sCols, ',', 2)
        EndIf
        For $i = 0 To UBound($aCols) - 1
            $sHeader &= 'Col' & $aCols[$i] & '|'
        Next
        Return StringTrimRight($sHeader, 1)
    EndFunc   ;==>_CreateColumnHeader
    Alles anzeigen
  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 21. Mai 2022 um 16:14
    Zitat von HansJ54

    Gibt es dazu irgendwo einen Ansatz, den ich weiterverfolgen kann?

    Wenn Du mal beschreibst, was Du genau anzeigen möchtest, dann schreibe ich Dir ein Beispiel.

    Immer 2 Spalten (welche? oder konfigurierbar?) und alle Zeilen (oder auch nur bestimmte?)?

  • GUI flackert

    • Oscar
    • 21. Mai 2022 um 14:44
    Zitat von Tweaky

    Bei mir flackert dann das rechte untere Eck.

    Bei euch auch?

    Ja, dafür war das Script nicht vorgesehen. Das Label muss verschoben und in der Größe angepasst werden. Das flackert zwangsläufig.

    Ich habe mal eine Version mit GDI+ geschrieben, die dann auch mit mehreren Monitoren zurechtkommt (Anhang).

    Da kannst Du das Auswahlrechteck sowohl von links-oben als auch von rechts-unten starten.

    Dateien

    _SelectRange.au3 4,41 kB – 234 Downloads
  • _ArrayDisplay(): bestimmte nicht nebeneinanderliegende Spalten anzeigen mit $sArrayRange

    • Oscar
    • 20. Mai 2022 um 07:55
    Zitat von HansJ54

    Funktioniert exakt, aber von Verstehen bin ich weit entfernt

    Naja, es ist etwas trickreich, weil hier der Umstand benutzt wird, dass die Funktionen der Timer-UDF quasi parallel weiter laufen, auch wenn das Script durch das ArrayDisplay eigentlich angehalten wird.

    So kann man in der Timer-Funktion die Spalten des ArrayDisplay verstecken.

    Aber statt hier rumzutricksen oder das Array umzukopieren, wäre es hilfreicher einfach eine eigene ArrayDisplay-Funktion zu schreiben.

  • GUI flackert

    • Oscar
    • 20. Mai 2022 um 07:48
    Zitat von Tweaky

    Du verwendet auch die neue Version. Bei dir flackert mein Skript nicht?

    Dein Script "flackert" mal kurz, wenn man die linke Maustaste das erste Mal drückt und das Label aufzieht.


    Zitat von Tweaky

    Dummy -GUI. Ich habe den Kommentar gelesen aber nicht verstanden.

    Die Dummy-Gui verhindert, dass man mit dem Auswahlkreuz in ein darunter liegendes Fenster etwas auswählen kann. Wenn SciTE mit dem Script drunter ist, kann man das sehen.

    Zitat von Tweaky

    Du verwendest GUIGetCursorInfo statt _Ispressed. Warum?

    Ist einfach zum einsparen von _IsPressed und MouseGetPos. Mit GUIGetCursorInfo bekommst Du beides gleichzeitig.

    Zitat von Tweaky

    Du verwendest 1 GUI mit Auswahl, 2x Fadenkreuz und veränderst die Position immer mit GUICtrlSetPos.

    Ja, eine GUI und Fadenkreuz und Auswahl sind Label.

    Vielleicht liegt darin auch schon der Grund für das "flackern", weil bei mir nicht mehrere Fenster "übereinander" liegen!?

    Ok, bei Windows sind alles Fenster, aber eben Childs vom Hauptfenster.

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™