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. BugFix

Beiträge von BugFix

  • Diskussionen etc. zu Snippets

    • BugFix
    • 7. Juni 2020 um 21:36
    Zitat von Bitnugger

    Diese Funktion holt aber wohl alle Windows, auch die Childs bzw. Controls... daran erkennbar, weil etliche Windows dieselbe PID/TID haben.

    Laut MSDN:

    Zitat

    EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.

    Ich habe testweise den DLL-Aufruf nochmal selbst in einer Funktion erstellt - liefert dieselbe Anzahl. Vielleicht verwendet die AutoIt Funktion stattdessen EnumDesktopWindows. Allerdings braucht diese Funktion ein Desktop Handle. Habe ich mir noch nicht weiter angesehen.

    EDIT:

    Habe es mal getestet. Alle mit EnumWindows gefundenen Fenster verwenden dasselbe Desktop-Handle, somit wird EnumDesktopWindows dasselbe Ergebnis liefern.

    EDIT2:

    Ich habe mal noch gefiltert:

    - Parent muss "0" sein

    - Fenster muss Titel haben

    Das schmilzt die Sache deutlich zusammen.

    Code
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      if GetParent(hwnd) == 0:
        var
          buflen = GetWindowTextLengthW(hwnd) + 1
          buf = newWideCString("", buflen)
          className = newWideCString("", 4096)
          pPID: LPDWORD
          pTID = GetWindowThreadProcessId(hwnd, cast[LPDWORD](addr pPID))
          oWndID = WndID(pid: cast[int](pPID), tid: cast[int](pTID))
        discard GetWindowTextW(hwnd, cast[LPWSTR](addr buf[0]), buflen)
        discard GetClassNameW(hwnd, cast[LPWSTR](className), 4096)
        if buf.len != 0:
          sEnumWnd.add(EnumWnd(hwnd: hwnd, 
                              class: className, 
                              title: buf,
                              pid: oWndID.pid,
                              tid: oWndID.tid))
      return TRUE
    Alles anzeigen


    Zitat von Bitnugger

    Ich habe es hin bekommen... er meckert nicht mehr

    :Face:Habe ich schon so oft in den Beschreibungen gelesen: "must be discarded". Einfach auch mal dran denken. ^^

  • Diskussionen etc. zu Snippets

    • BugFix
    • 7. Juni 2020 um 14:43
    Zitat von Bitnugger

    EnumWindows... die beiden Variablen werden sonst an keiner Stelle verwendet... da muss du noch mal gucken...

    Das ist Absicht. In vielen Fällen meckert der Compiler, wenn du den Rückgabewert einer Funktion nicht auffängst. Deshalb habe ich mir das so angenommen.

  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 7. Juni 2020 um 13:42

    Ermitteln des Prozessnamens (Pfades) anhand der Process-ID:

    Code
    import strutils 
    include winim/[inc\winuser]
    
    proc GetProcessByPID(processID: int): LPSTR =
      proc GetModuleFileNameExA(hProcess: HWND, hModule: HMODULE, lpFilename: LPSTR, nSize: DWORD): DWORD {.stdcall, varargs, dynlib: "Psapi", importc: "GetModuleFileNameExA".}
    
      proc OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD): HWND {.stdcall, varargs, dynlib: "Kernel32", importc: "OpenProcess".}
    
      let 
        rights = cast[DWORD](1040)  # PROCESS_QUERY_INFORMATION(1024) | PROCESS_VM_READ(16)
        pid = cast[DWORD](processID)
        hProc = OpenProcess(rights, FALSE, pid)
      var failed: LPSTR
    
      if int(hProc) != 0:
        var 
          buffer: LPSTR = spaces(MAX_PATH)
          bufflen = GetModuleFileNameExA(hProc, 0, buffer, MAX_PATH)
        if bufflen != 0:
          result = buffer
        else:
          result = failed
      else:
        result = failed
    
    
    # example:
    
    echo GetProcessByPID(7152)
    
    # output:
    # C:\Program Files (x86)\AutoIt3\SciTE\SciTE.exe
    Alles anzeigen

    Tags: <Process>, <Process Name>, <Process Path>, <PID>

  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 7. Juni 2020 um 12:58

    EnumWindows (das Gegenstück zu AutoIt WinList mit mehr Inhalt)

    Es werden ermittelt:

    • Fenster Handle
    • ClassName
    • Fenster Titel
    • Process ID
    • Thread ID
    Code
    import strutils
    include winim/[inc\winuser]
    
    type
      WndID = object
        pid, tid: int
      EnumWnd = object
        hwnd: HWND
        class: WideCStringObj
        title: WideCStringObj
        pid, tid: int
    
    var 
      sEnumWnd = newSeq[EnumWnd]()
      lp: LPARAM
    
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      var
        buflen = GetWindowTextLengthW(hwnd) + 1
        buf = newWideCString("", buflen)
        txtlen = GetWindowTextW(hwnd, cast[LPWSTR](addr buf[0]), buflen)
        className = newWideCString("", 4096)
        classlen = GetClassNameW(hwnd, cast[LPWSTR](className), 4096)
        pPID: LPDWORD
        pTID = GetWindowThreadProcessId(hwnd, cast[LPDWORD](addr pPID))
        oWndID = WndID(pid: cast[int](pPID), tid: cast[int](pTID))    
      sEnumWnd.add(EnumWnd(hwnd: hwnd, 
                           class: className, 
                           title: buf,
                           pid: oWndID.pid,
                           tid: oWndID.tid))
      return TRUE
    
    
    EnumWindows(my_WndEnumProc, lp)
    
    
    for i in 0..sEnumWnd.len - 1:
      echo toHex(sEnumWnd[i].hwnd), "\t", sEnumWnd[i].class, "\t", sEnumWnd[i].title, "\t", sEnumWnd[i].pid, "\t", sEnumWnd[i].tid, "\t"
    Alles anzeigen

    EDIT:

    Ich habe mal noch gefiltert:

    - Parent muss "0" sein

    - Fenster muss Titel haben

    Das schmilzt die Sache deutlich zusammen.

    Code

    Code
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      if GetParent(hwnd) == 0:
        var
          buflen = GetWindowTextLengthW(hwnd) + 1
          buf = newWideCString("", buflen)
          className = newWideCString("", 4096)
          pPID: LPDWORD
          pTID = GetWindowThreadProcessId(hwnd, cast[LPDWORD](addr pPID))
          oWndID = WndID(pid: cast[int](pPID), tid: cast[int](pTID))
        discard GetWindowTextW(hwnd, cast[LPWSTR](addr buf[0]), buflen)
        discard GetClassNameW(hwnd, cast[LPWSTR](className), 4096)
        if buf.len != 0:
          sEnumWnd.add(EnumWnd(hwnd: hwnd,
                              class: className,
                              title: buf,
                              pid: oWndID.pid,
                              tid: oWndID.tid))
      return TRUE
    Alles anzeigen

    Weniger anzeigen

    Tags: <Enum Windows>, <Fenster Handle>, <ClassName>, <Fenster Titel>, <Process ID>, <Thread ID>

  • FindWindowW ohne Resultat bei Übergabe Klasse und/oder Titel

    • BugFix
    • 6. Juni 2020 um 22:43
    Zitat

    Hier hast du dich vertan

    Oops ^^

  • FindWindowW ohne Resultat bei Übergabe Klasse und/oder Titel

    • BugFix
    • 6. Juni 2020 um 21:36
    Zitat von Bitnugger

    So funktioniert es bei mir:

    OK, Danke.

    In eine übergeordnete Funktion verpackt, gefällt mir das dann aber besser. :P

    Code
    proc FindWindow(class = "", title = ""): HWND =
      let 
        className = newWideCString(class, class.len)
        wndName = newWideCString(title, title.len)
      if class == "" and title == "":
        result = FindWindowW(nil, nil)
      elif class != "" and title == "":
        result = FindWindowW(cast[LPWSTR](className), nil)  
      elif class == "" and title != "":
        result = FindWindowW(nil, cast[LPWSTR](wndName))
      else:
        result = FindWindowW(cast[LPWSTR](className), cast[LPWSTR](wndName))   
    
    
    echo "hWnd SciTE [ACTIVE]        = ", toHex(FindWindow())
    echo "hWnd SciTE [class]         = ", toHex(FindWindow("SciTEWindow")) 
    echo "hWnd SciTE [class & title] = ", toHex(FindWindow(title = r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]")) 
    echo "hWnd SciTE [title]         = ", toHex(FindWindow("SciTEWindow", r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]")) 
    Alles anzeigen
  • Diskussionen etc. zu Snippets

    • BugFix
    • 6. Juni 2020 um 20:49
    Zitat von Bitnugger

    Das passiert, wenn man das Bsp. nicht testet: 8o

    :whistling: Ich habs korrigiert (so hatte ich es bei mir auch getestet, dachte dann aber - das "o" muss nicht sein - Eigentor :rofl:).

  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 6. Juni 2020 um 16:47
    Code
    # Ermitteln von Process-ID und Thread-ID eines Fensters
    
    include winim/[inc\winuser]
    
    type
      WndID = object
        pid, tid: int
    
    proc GetIDByWindow(hWnd: HWND): WndID =
      # determines the process and thread ID by a window handle
      # returns the object type "WndID" with .pid & .tid
      # requires: include winim/[inc\winuser]
      var 
        pPID: LPDWORD
        pTID = GetWindowThreadProcessId(hWnd, cast[LPDWORD](addr pPID))
      result = WndID(pid: cast[int](pPID), tid: cast[int](pTID))
    Alles anzeigen

    Bsp.:

    Code
    let oWndID = GetIDByWindow(hWnd)
    echo "Process-ID = ", oWndID.pid
    echo "Thread-ID  = ", oWndID.tid
    
    # PID only:
    echo "PID = ", GetIDByWindow(hWnd).pid

    Tags: <Process ID>, <PID>, <Thread ID>

  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 6. Juni 2020 um 16:45

    Ich möchte in diesem Thread eine Sammlung erstellen, von all den nützlichen Dingen, die wir so erstellen (werden). ;)

    Bitte jeden Post mit Tags versehen, das vereinfacht dann auch die Suche. Für jede Prozedur einen eigenen Post erstellen. Bsp. kann - muss aber nicht dabei sein, wenn die Handhabung eindeutig ist.

    Diskussionen und Verbesserungsvorschläge etc. können wir gern hier mit führen. Wenn ein Thema dann abgeschlossen ist, würde ich aber die Diskussion auslagern (oder löschen?).

    INHALT:

    D

    • Drag and Drop (wNim Listview)

    E

    • EnumWindows (Variante1, Variante2, Variante3 Filtern: gleich/teilweise/Regex)

    F

    • Flags - mit Sets
    • Font temporär einbinden

    I

    • Ini-Dateien  /  Ergänzung @Oscar
    • Imagelist System Icon (wNim List-/Treeview)

    J

    • JSON Datei in einer Anwendung erstellen, Daten Hinzufügen/Ändern
    • JSON Datei in Objekt-Table einlesen

    K

    • Kopieren von (Unicode-)Text in die Windows-Zwischenablage

    L

    • Laufwerke als String-Sequenz
    • Levenshtein-Distance
    • ListCtrl - Alternate Colors

    M

    • MouseHover

    N

    • NamedPipe

    O

    • openArray

    P

    • Process-ID und Thread-ID eines Fensters ermitteln
    • Prozessnamen (Pfad) anhand der Process-ID ermitteln

    S

    • SerialComm
    • ShellExecute
    • Sortieren eines Listview ( wNim List-Ctrl )
    • Sound-UDF "winmm.dll" (#1 Funktional, #2 Prozedural, #3 Objekt)

    T

    • TimerInit / TimerDiff in Nanosekundengenauigkeit (OOP Variante)
    • TimedProcedure - eine Art Pendant zu AutoIt's AdlibRegister

    U

    • UNION - Datenstruktur
  • FindWindowW ohne Resultat bei Übergabe Klasse und/oder Titel

    • BugFix
    • 6. Juni 2020 um 15:01

    Da Fenster im Titel durchaus Unicode Zeichen enthalten können, wollte ich statt FindWindowA lieber FindWindowW verwenden.

    Ich caste Klasse und Titel in den erforderlichen Typ - bekomme aber kein Handle. Was läuft da falsch?

    Code
    import strutils 
    include winim/[inc\winuser]
    
    var
      className = cast[LPCWSTR]("SciTEWindow")
      wndName = cast[LPCWSTR](r"C:\CODE\AutoIt\TEST\_1test.au3 - SciTE [1 of 19]")
      hScite0 = FindWindowW(nil, nil)
      hScite1 = FindWindowW(className, nil)
      hScite2 = FindWindowW(className, wndName)
    echo "hWnd SciTE [ACTIVE]        = ", toHex(hScite0) # OK
    echo "hWnd SciTE [class]         = ", toHex(hScite1) # 0
    echo "hWnd SciTE [class & title] = ", toHex(hScite2) # 0
    
    #[ OUTPUT
    hWnd SciTE [ACTIVE]        = 00000000000F06FE
    hWnd SciTE [class]         = 0000000000000000
    hWnd SciTE [class & title] = 0000000000000000
    ]#
    Alles anzeigen
  • Autoit browser Elemente und Windows Ordner

    • BugFix
    • 5. Juni 2020 um 17:07
    Zitat von Bernd Albrecht

    oder Interent Explorer

    Dann kannst du die IE.au3 verwenden, z.B. mit https://www.autoitscript.com/autoit3/docs/l…s/_IEAction.htm

    Zitat von Bernd Albrecht

    über Autoit Ordner auf Windows öffnen, ohne diese Anklicken zu müssen

    https://www.autoitscript.com/autoit3/docs/l…SelectItems.htm

  • Windows Titel auslesen

    • BugFix
    • 1. Juni 2020 um 22:25

    Danke euch beiden. :thumbup:

  • Auslesen, welche geräte sich im WLan befinden

    • BugFix
    • 1. Juni 2020 um 21:03

    Im Allgemeinen bieten die Router eine Seite mit den aktuellen Verbindungen an (zumindest die Fritz.Box kann es) . Die kann man direkt auslesen.

  • IsNumber() und Zahlen in Textvariablen

    • BugFix
    • 1. Juni 2020 um 16:28
    Zitat

    die bei der Eingabe über InputBox entscheidet, ob der User eine Zahl (0-99) oder einen Text eingegeben hat.

    Da haben wir mal wieder ein XY-Problem. Ein Input-Ctrl im Style ES_NUMBER nimmt dir diese Überprüfung ab und lässt nur Zahlenwerte zu.

  • Windows Titel auslesen

    • BugFix
    • 1. Juni 2020 um 13:16

    Mit den folgenden Funktionen kann ich das Window Handle auslesen:

    Code
    import strutils 
    
    # FindWindow by CLASSNAME and TITLE
    proc FindWindow*(lpClass: cstring, lpName: cstring): cint {.cdecl, varargs, importc: "FindWindowA", dynlib: "User32.dll".}
    
    # FindWindow by CLASSNAME
    proc FindWindow*(lpClass: cstring, lpName: cint = 0): cint {.cdecl, varargs, importc: "FindWindowA", dynlib: "User32.dll".}
    
    # FindWindow On Top (ACTIVE Window)
    proc FindWindow*(lpClass: cint = 0, lpName: cint = 0): cint {.cdecl, varargs, importc: "FindWindowA", dynlib: "User32.dll".}
    
    
    # Bsp:
    # let hWnd = FindWindow() # ACTIVE Wnd
    # let hWnd = FindWindow("SciTEWindow", r"C:\CODE\AutoIt\errorTest.au3 - SciTE [9 of 16]")
    let hWnd = FindWindow("SciTEWindow")
    
    echo toHex(hWnd)
    Alles anzeigen

    Nun wollte ich versuchen den Titel auszulesen:

    Code
    proc GetWindowText*(hWnd: cint, lpString: cstring, nMaxCount: int32): int32 {.cdecl, varargs, importc: "GetWindowTextA", dynlib: "User32.dll".}

    Wenn ich die Funktion mit Dll-Aufruf in AutoIt oder Lua ausführe übergebe ich als Buffer (lpString) einfach einen String. Das klappt dort - aber nicht in Nim, der String wird nicht befüllt. Wenn ich statt cstring einen ptr cstring oder ptr string verwende, bleibt der Inhalt nil.

    Wie muss ich hier vorgehen?

  • Daten aus Pointer in Nim Datentyp einlesen

    • BugFix
    • 1. Juni 2020 um 08:56
    Zitat von Oscar

    Ich würde trotzdem von AutoIt aus den Speicher reservieren (DllStructCreate).

    Einfach eine geschätzte Maximalgröße eintragen, den Pointer darauf an Nim übergeben, dort die Änderungen vornehmen und dann (je nach Datenstruktur) ein Int für die Anzahl an AutoIt zurückgeben

    Ja, ist wohl die sinnvollste Variante.

    Wobei ich mich gerade frage, warum ich das nach Autoit zurückgeben will. Die Projekte kann ich doch kpl. in Nim umsetzen. :Face:

    Aber Datenaustausch kann man immer brauchen. Danke nochmal für die "Erleuchtung" :D

  • Daten aus Pointer in Nim Datentyp einlesen

    • BugFix
    • 31. Mai 2020 um 20:21

    Ich übergebe Dateipfade, lese mit Nim die Dateien ein, parse Includes, Variablen, Konstanten, Funktionen und will all diese Daten zurückgeben. Menge ist vorher unbekannt.

    Soll das Grundgerüst werden für mein ManageIncludes und die Überarbeitung von UnusedVars.

  • Daten aus Pointer in Nim Datentyp einlesen

    • BugFix
    • 31. Mai 2020 um 17:23
    Zitat von Oscar

    Wenn Du Strings übergeben willst, pack sie am besten in eine Struktur (mit Nullbyte am Ende) und übergib nur die Pointer auf die Strings

    :thumbup: Fein, wieder einen Schritt weiter.

    Und jetzt kommt gleich der nächste Punkt, wo ich hänge.

    Das bisherige diente dazu um 1..n Dateipfade übergeben zu können. Jetzt verarbeite ich die entsprechenden Dateien mit Nim und will das Ergebnis sofort zurückliefern. Nur weiß ich nicht, wie ich die Datenstruktur zum Empfang des Ergebnisses bereits beim Aufruf übergeben soll, wenn die Anzahl/Länge der Elemente erst zur Laufzeit bestimmt wird (z.B. Variablennamen auslesen o.ä.). Möglich wäre als Return Type cstring zu verwenden mit Trennzeichen zwischen den Werten und in AutoIt durch Splitten in ein Array packen. Halte ich aber für die schlechtere Variante, als wenn ich es in einer Struktur habe, auf die ich sofort ohne Umwandlung zugreifen kann.

    Bei Anwendung von Dll hat man ja oft den Hinweis: "Rufe zuerst mit NULL für den Parameter auf, um die Größe für den Puffer zu erhalten" - Das mag gehen, wenn ich einen Fenstertitel abfrage. Aber ich kann doch nicht 2-mal komplexe Programmabläufe durchführen um beim ersten mal nur die Größe zu erhalten. :rolleyes:

    Bin für Ideen empfänglich. ;)

  • IsNumber() und Zahlen in Textvariablen

    • BugFix
    • 31. Mai 2020 um 17:06

    Vor 12 Jahren hat mich das Thema schon mal beschäftigt: Fehlerhafte Rückgabe der Funktion Number() behoben mit _Number() ;)

  • Daten aus Pointer in Nim Datentyp einlesen

    • BugFix
    • 31. Mai 2020 um 15:15

    Danke, numerische Werte klappen tadellos.

    Jetzt wollte ich Strings übergeben. Strings aus AutoIt sind in Nim cstring. Und da fängt die Misere an. Versuche ich auf string zu casten crasht es. Und auf cstring kann ich nicht mit Range im Index zugreifen. Meine Idee war, Strings zusammenzuhängen und die Länge der Einzelstrings parallel als Array. Dann kann man das hinterher wieder zerlegen.

    AutoIt
    Local $aData[3] = ["Daten #1","Daten Nummer 2","Daten Item #3"]
    Local $sData, $tLen
    
    _CreateDllData($aData, $sData, $tLen)
    
    Local $aRet = DllCall("C:\CODE\nim\_myExamples_\transfer.dll", 'int', 'sendData', 'str', $sData, 'ptr', DllStructGetPtr($tLen))
    If Not @error Then
        ConsoleWrite('Succes: ' & $aRet[0] & @CRLF)
    Else
        ConsoleWrite('Error: ' & @error & @CRLF)
    EndIf
    
    
    Func _CreateDllData($_aData, ByRef $_sData, ByRef $_tLen)
        $_tLen = DllStructCreate('int[' & UBound($_aData) & ']')
        For $i = 0 To UBound($_aData) -1
            $_sData &= $_aData[$i]
            DllStructSetData($_tLen, 1, StringLen($_aData[$i]), $i+1)
        Next
    EndFunc
    Alles anzeigen

    Die DLL

    Code
    proc sendData(sData: cstring, pLen: ptr array[3,int32]): int {.stdcall,exportc,dynlib.} =
      var
        a_len: ptr array[3,int32]
        pos = 0
        # received = cast[string](sData) # ==> Konvertieren zu string: out of memory
        received = sData  
        sStr = newSeq[string]()
      a_len = pLen  
      # echo received  # ==> OK
      for i in 0..2:
        # echo $pos & " .. " & $(pos + a_len[i] - 1)  # ==> Array Pos: OK
        echo received[pos..(pos + aLen[i] - 1)]   # Zugriff mit Range nicht möglich mit cstring
        sStr.add(received[pos..(pos + aLen[i] - 1)])
        pos += a_len[i]
      echo sStr
      result = 1
    Alles anzeigen

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™