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

  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 26. Juni 2020 um 09:47

    Das klassische TimerInit() / TimerDiff() aus AutoIt, allerdings in Nanosekunden Genauigkeit:

    Code
    import times, os
    
    type
      Timer = object
        t0: Time
    
    proc timerInit(): Timer = 
      var t = Timer(t0: getTime())
      return t
    
    proc timerDiff(t: Timer, unit: string = "ns", T: type = int): T =
      let 
        t1 = getTime()
        td = int((t1 - t.t0).inNanoseconds)
      case unit
        of "ns": return T(td)
        of "µs": return T(td / 1_000)
        of "ms": return T(td / 1_000_000)
        of "s": return T(td / 1_000_000_000)
        else: return T(td)
    
    
    
    let start = timerInit()
    sleep(2500)
    echo "diff ns: ", start.timerDiff()
    echo "diff µs: ", start.timerDiff("µs")
    echo "diff ms: ", start.timerDiff("ms")
    echo "diff  s: ", start.timerDiff("s", float)
    
    #==>:
    #==> diff ns: 2500143000
    #==> diff µs: 2500143
    #==> diff ms: 2500
    #==> diff  s: 2.500143
    Alles anzeigen
  • RegExp: Space um Zeichen setzen - mehrfache Spaces ersetzen - Zeilen mit Begriff behalten

    • BugFix
    • 25. Juni 2020 um 14:11

    Als Erstes: Du hast dir alle deine Fragen schon richtig beantwortet.

    Zitat von Professor Bernd

    aber ist es auch richtig?

    Für Regex gibt es kein globales richtig. Es führen so viele Wege zum Ziel. Oft ist das von der Gewohnheit des Anwenders abhängig. Es gibt ein paar Dinge , die man im Auge haben sollte (z.B. "greedy" nur wenn nötig verwenden), aber ansonsten zählt das Ergebnis. ;)

  • Wie kann man etwas in der MainLoop ausführen?

    • BugFix
    • 25. Juni 2020 um 13:50

    Ich denke mal, das sollte auch mit asyncdispatch zu lösen sein. Leider sind die Beispiele nicht sehr hilfreich, basieren alle auf client-server Geschichten.

    Ich habe das so verstanden.

    - Mann benötigt ein Future-Objekt, das den Wert enthält der erreicht werden soll um die Async-Proc zu starten. Ich habe kein Bsp. gefunden, wie man newFutureVar den Zielwert zuweisen kann.

    - In der Async-Proc warte ich dann darauf, dass Future erreicht wird (so etwa: await future). "await" pausiert nur die Async-Proc.

    - die Async-Proc wird gestartet mit asyncCheck procXY()

    Aber ich habe hin-und herprobiert. Die Arbeit mit Future geht immer irgendwo daneben, Typ passt nicht oder Instanzierung der Prozedur nicht möglich. X(

  • Wie kann man etwas in der MainLoop ausführen?

    • BugFix
    • 24. Juni 2020 um 17:55

    Da hatte ich auch schon mal gesucht.

    mainLoop() (wApp.nim #212) verwaltet nur die eigentliche Schleife: messageLoop() (wApp.nim #181).

    Aber wie man dort eigenes Handling einbringen kann....:?:

    Ich vermute, dass man alles über eigene Events regeln muss, die dann mit frame.wEvent_Irgendwas ausgeführt werden.

  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 24. Juni 2020 um 14:17

    Angeregt durch einen Beitrag von Oscar habe ich eine Art AdlibRegister erstellt. Ist allerdings an ein Fenster gebunden, da das Timer-Event über das Fenster registriert wird.

    Funktionen:

    • TimedProcRegister - Registriert eine (parameterlose) Funktion zum Intervallaufruf

    • TimedProcUnRegister - Löscht die Funktion aus der Aufrufverwaltung

    • TimedProcPause - Pausiert den Aufruf einer zuvor registrierten Funktion

    • TimedProcResume - Setzt die Ausführung einer zuvor pausierten Funktion fort

    • TimedProcGet - Gibt den Index für das gespeicherte Objekt in der Aufrufverwaltung zurück

    • TimedProcChangeTime - Ändert das Zeitintervall des Aufrufs

    EDIT:

    Alle Prozeduren (ausser ..Register) können jetzt wahlweise über den Prozedurnamen oder die Timer-ID aufgerufen werden.

    Neue Funktion zum Ändern der Timerdauer.

    Code
    import wNim/[wApp, wFrame]
    
    # ============ TIMER MANAGEMENT ============================================= #
    type
      TimedProcedure = object
        tpPause: bool   # marks procedure timer as paused (only for information)
        tpFrame: wFrame # the frame, which holds the timer
        tpID: int       # Timer-Id
        tpProc: proc()  # timed procedure
        tpTime: float   # poll time in sec
    
    var 
      sTimer = newSeq[TimedProcedure]() # sequence with registered procedures
      timerID = int(wIdUser)            # the last assigned timerID
    
    
    # returns the index of the object in the management sequence by the procedure
    # if the procedure is'nt registered, the return is: -1
    proc TimedProcGet(tProc: proc): int =
      for i in 0..sTimer.len - 1:
        if sTimer[i].tpProc == tProc: return i
      return -1
    
    # same as above, but works with ID as parameter
    proc TimedProcGet(tID: int): int =
      for i in 0..sTimer.len - 1:
        if sTimer[i].tpID == tID: return i
      return -1
    # ----------------------------------------------------------------------------
    
    # registers a procedure (parameterless) for timed call
    proc TimedProcRegister(fr: wFrame, tProc: proc, fsec: float): int {.discardable.} =
      timerID += 1
      sTimer.add(TimedProcedure(tpPause: false, tpFrame: fr,
                 tpID: timerID, tpProc: tProc, tpTime: fsec))
      fr.startTimer(fsec, timerID)
      result = timerID
    # ----------------------------------------------------------------------------
    
    # deletes a registered  procedure from management
    proc TimedProcUnRegister_Main(idx: int): bool {.discardable.} =
      sTimer[idx].tpFrame.stopTimer(sTimer[idx].tpID)
      sTimer.delete(idx)
      return true
    
    # call with procedure
    proc TimedProcUnRegister(tProc: proc): bool {.discardable.} =
      let idx = TimedProcGet(tProc)
      if idx == -1: return false
      return TimedProcUnRegisterMain(idx)
    
    # call with timer ID
    proc TimedProcUnRegister(tID: int): bool {.discardable.} =
      let idx = TimedProcGet(tID)
      if idx == -1: return false
      return TimedProcUnRegisterMain(idx)
    # ----------------------------------------------------------------------------
    
    # pauses the timed call of a registered procedure
    proc TimedProcPause_Main(idx: int): bool {.discardable.} =
      sTimer[idx].tpFrame.stopTimer(sTimer[idx].tpID)
      sTimer[idx].tpPause = true
      return true
    
    # call with procedure
    proc TimedProcPause(tProc: proc): bool {.discardable.} =
      let idx = TimedProcGet(tProc)
      if idx == -1: return false
      return TimedProcPauseMain(idx)
    
    # call with timer ID
    proc TimedProcPause(tID: int): bool {.discardable.} =
      let idx = TimedProcGet(tID)
      if idx == -1: return false
      return TimedProcPauseMain(idx)
    # ----------------------------------------------------------------------------
    
    # continues a previously paused procedure
    proc TimedProcResume_Main(idx: int): bool {.discardable.} =
      sTimer[idx].tpFrame.startTimer(sTimer[idx].tpTime, sTimer[idx].tpID)
      sTimer[idx].tpPause = false
      return true
    
    # call with procedure
    proc TimedProcResume(tProc: proc): bool {.discardable.} =
      let idx = TimedProcGet(tProc)
      if idx == -1: return false
      return TimedProcResumeMain(idx)
    
    # call with timer ID
    proc TimedProcResume(tID: int): bool {.discardable.} =
      let idx = TimedProcGet(tID)
      if idx == -1: return false
      return TimedProcResumeMain(idx)
    # ----------------------------------------------------------------------------
    
    # stops the timed procedure, sets the new time and starts again
    proc TimedProcChangeTime_Main(idx: int, fsec: float): bool {.discardable.} =
      sTimer[idx].tpFrame.stopTimer(sTimer[idx].tpID)
      sTimer[idx].tpTime = fsec
      sTimer[idx].tpFrame.startTimer(fsec, sTimer[idx].tpID)
      return true
    
    # call with procedure
    proc TimedProcChangeTime(tProc: proc, fsec: float): bool {.discardable.} =
      let idx = TimedProcGet(tProc)
      if idx == -1: return false
      return TimedProcChangeTimeMain(idx, fsec)
    
    # call with timer ID
    proc TimedProcChangeTime(tID: int, fsec: float): bool {.discardable.} =
      let idx = TimedProcGet(tID)
      if idx == -1: return false
      return TimedProcChangeTimeMain(idx, fsec)
    # =========================================================================== #
    
    let
      app = App()
      frame = Frame(title="Timed Call",size=(300,300))
    
    proc every2sec() = echo "2 sec finished"
    proc every3sec() = echo "3 sec finished"
    proc every5sec() = echo "5 sec finished"
    
    let
      id2 = frame.TimedProcRegister(every2sec, 2.0)
      id3 = frame.TimedProcRegister(every3sec, 3.0)
      id5 = frame.TimedProcRegister(every5sec, 5.0)
    
    var counter = 0
    
    
    frame.wEvent_Timer do (event: wEvent): # hier wird der Timer-Event ausgewertet
      counter += 1
      let 
        id = event.getTimerId()
        idx = TimedProcGet(id)
    
      if counter == 5:
        TimedProcPause(every2sec)
        echo "[PAUSED] 2 sec"
      elif counter == 8:
        TimedProcPause(every3sec)
        echo "[PAUSED] 3 sec"
      elif counter == 10:
        TimedProcResume(every2sec)
        TimedProcResume(every3sec)
        echo "[RESUMED] 2 sec"
        echo "[RESUMED] 3 sec"
      elif counter == 15:
        TimedProcUnRegister(every3sec)
        TimedProcUnRegister(every5sec)
        echo "[UNREGISTERED] 3 sec"
        echo "[UNREGISTERED] 5 sec"
      elif counter == 18:
        TimedProcChangeTime(id2, 4.0)
        echo "[TIME_CHANGED] 2 sec >> 4 sec"
      else:
        sTimer[idx].tpProc()
    
    frame.show()
    app.mainLoop()
    Alles anzeigen
  • NSI Nim-SciTE-Interface - Projekt

    • BugFix
    • 23. Juni 2020 um 18:30

    Ich poste hier mal meine weiteren Schritte in diesem Projekt. Dann könnt ihr bei Bedarf auch experimentieren.

    Momentan sind es 3 Dateien ("sciteConstants.nim", "nsiface.nim", "main.nim") im Projekt (den Anhang in einen gemeinsamen Ordner entpacken). Stört euch nicht an "UnusedImport" in der main. Zum Testen braucht man die Imports dann doch, somit lasse ich sie immer drin.

    Hier mal die "main"

    Code
    import nsiface, sciteConstants, strutils
    import wNim/[wApp, wFrame, wPanel, wTextCtrl]
    
    
    ClearOutput()
    
    CurrentFile()
    OutputConsole(">> Current file: " & received & r"\n")
    
    #                    Lua-Func,  Func-Parse-Result, Type-Parse-Result
    let lcp = LuaFuncGet(LuaCurrPos, ParseLuaCurrPos, EditorPosition)
    OutputConsole("+> CurrentPosition Data: " & $lcp)
    
    #                    Lua-Func,  Func-Parse-Result, Type-Parse-Result, Pos.
    let lcp2 = LuaFuncGet(LuaCurrPos, ParseLuaCurrPos, EditorPosition, $(lcp.pos - 50))
    OutputConsole(r"\n+> CurrentPosition -50 Data: " & $lcp2)
    
    let hScite = MyFindWindow("SciTEWindow")
    SetForegroundWindow(hScite)
    
    nsiFrame.center()
    nsiFrame.show()
    nsiApp.mainLoop()
    Alles anzeigen

    Ich habe eine Prozedur LuaFuncGet zum Aufrufen von Lua-Funktionen (LuaCurrPos) mit Rückgabewert und wahlweise Übergabe von Parametern (2.ter Aufruf $(lcp.pos - 50).

    Für das Parsen des Returnwertes ist eine Funktion erforderlich (ParseLuaCurrPos), ebenso wird der Datentyp benötigt (EditorPosition) in dem der geparste Return gespeichert ist.

    Was mir fast den Nerv geraubt hat, war das Einbringen der Lua-Funktion. In meiner AutoIt-Version des Interfaces lief diese anstandslos. 1:1 übertragen und immer meckerte Lua, es würde ein "end" am Dateiende fehlen. Das ist erfahrungsgemäß ein Fehler der kommt, wenn z.B. versucht wird eine UTF8BOM-Datei in Lua zu verwenden, aber auch wenn vergessen wurde ordentlich zu maskieren. Das traf hier aber nicht zu. -- Die Lösung: In Nim darf der String mit der Lua-Funktion keine Zeilenumbrüche enthalten!

    Dateien

    NimSciteInterface.zip 5,36 kB – 525 Downloads
  • NSI Nim-SciTE-Interface - Projekt

    • BugFix
    • 22. Juni 2020 um 16:15

    Ich habe das jetzt zur Verwendung mit den Interface-Funktionen angepasst. Das Ergebnis einer Funktion wird in der Variablen "received" abgelegt.

    Code
    include winim/[inc\winuser]
    import re
    import wNim/[wApp, wFrame]
    
    let           
      nsiApp = App() 
      nsiFrame = Frame(title="Nim-SciTE interface", size=(320,220))
    
    proc MyFindWindow(class = "", title = ""): HWND = 
      let 
        className = newWideCString(class, class.len)
        titleName = newWideCString(title, title.len)
      result = FindWindowW(if class.len > 0: cast[LPWSTR](className) else: nil,
                           if title.len > 0: cast[LPWSTR](titleName) else: nil)
    
    
    let hRecv = nsiFrame.handle
    
    var 
      received: string  # enthält Ergebnis einer Abfrage
      pattern: Regex    # Pattern zum Aufbereiten von received
    
    nsiFrame.connect(WM_COPYDATA) do (event: wEvent):
      var 
        cds: PCOPYDATASTRUCT = cast[PCOPYDATASTRUCT](event.lParam)
        len: int = cds.cbData
        ret: cstring = cast[cstring](cds.lpData)
      received = $ret
      received.setLen(len)
      received = received.replace(pattern)
    
    
    proc SendCommand(hwnd: HWND, cmd: string, recv: bool = false): bool {.discardable.} =
      if hwnd == 0: return false
      let hScite = MyFindWindow(class = "DirectorExtension")
      var
        cmdScite = ":" & $hwnd & ":" & cmd
        cds: COPYDATASTRUCT
      cds.dwData = 1
      cds.cbData = DWORD(cmdScite.len + 1)
      cds.lpData = cmdScite[0].addr
      received = ""
      SendMessage(hScite, WM_COPYDATA, cast[WPARAM](hwnd), cast[LPARAM](cds.addr))
      return true
    
    
    proc CurrentFile(hwnd: HWND): bool {.discardable.} =
      pattern = re"^:\d+:[^:]+:"
      result = hwnd.SendCommand("askfilename:", true)
    
    proc GetProperty(hwnd: HWND, property: string): bool {.discardable.} =
      pattern = re"^:\d+:([^:]+:){2}"
      result = hwnd.SendCommand("askproperty:" & property, true)
    
    proc OutputConsole(hwnd: HWND, value: string): bool {.discardable.} =
      result = hwnd.SendCommand("output:" & value)
    
    proc MenuCmd(hwnd: HWND, cmdID: int): bool {.discardable.} =
      result = hwnd.SendCommand("menucommand:" & $cmdID)
    
    proc ClearOutput(hwnd: HWND): bool {.discardable.} =
      result = hwnd.SendCommand("extender:dostring do output:ClearAll() end")
    
    
    
    hRecv.ClearOutput()
    
    hRecv.CurrentFile()
    echo "File: ", received
    hRecv.OutputConsole(">> current file: " & received & r"\n")
    
    hRecv.GetProperty("UDFCreator")
    echo "Prop: ", received
    hRecv.OutputConsole(">> UDF-Creator:  " & received)
    
    
    nsiFrame.center()
    nsiFrame.show()
    nsiApp.mainLoop()
    Alles anzeigen

    Jetzt kann ich mal ein wenig spielen und AddOns, die ich in Lua erstellt hatte, mit Nim ausführen.

  • NSI Nim-SciTE-Interface - Projekt

    • BugFix
    • 22. Juni 2020 um 13:48

    Meinen aller<3lichsten Dank! :thumbup:

    Das bringt mich eine ganze Ecke weiter.

  • NSI Nim-SciTE-Interface - Projekt

    • BugFix
    • 21. Juni 2020 um 22:19

    Ich habe nun versucht mein SciTEInterface auf Nim Basis auszuführen.

    Das Übertragen in Richtung SciTE klappt. Aber ich bekomme es nicht gebacken, die Callbackfunktion zu installieren. Sie muss vom Typ SENDASYNCPROC sein - das bekomme ich nicht umgesetzt. Die entsprechenden Bereiche sind auskommentiert.

    Zum Testen muss SciTE geöffnet sein, ich habe noch keine Fehlerbehandlung drin und gehe davon aus, dass ich ein Handle bekomme.

    Vielleicht habt ihr einen zündenden Gedanken .

    Code
    # Nim-SciTE-Interface
    
    include winim/[inc\winuser]
    import wNim/[wApp, wFrame, wPanel, wTextCtrl]
    import strformat, strutils, os, re
    
    
    
    type
      WndID = object
        pid, tid: int
      EnumWnd = object
        hwnd: HWND
        class: WideCStringObj
        title: WideCStringObj
        pid, tid: int
    
    var 
      received: string
      sEnumWnd = newSeq[EnumWnd]()
      lp: LPARAM
      classfilter = newWideCString("", 256)
      titlefilter = newWideCString("", 4096)
    
    
    proc MyFindWindow(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)) 
    
    
    # Fensteranwendung für Interface
    let           
      nsiApp = App() 
      nsiFrame = Frame(title="Nim-SciTE interface", size=(320,220))
      nsiPanel = Panel(nsiFrame)
      nsiText = TextCtrl(nsiPanel, style=wTeMultiLine, pos=(10,10), size=(300,200))
      hRecv = MyFindWindow(class="wFrame1", title="Nim-SciTE interface")
    
    nsiFrame.wIdExit do ():
      nsiFrame.delete()
    
    
    
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      if GetParent(hwnd) == 0:
        var buflen = GetWindowTextLengthW(hwnd) + 1
        if buflen == 0: return TRUE
    
        var buf = newWideCString("", buflen)
        discard GetWindowTextW(hwnd, cast[LPWSTR](addr buf[0]), buflen)
        if titlefilter.len > 0:
          if fmt"{buf}" != fmt"{titlefilter}": return TRUE
    
        var className = newWideCString("", 4096)
        discard GetClassNameW(hwnd, cast[LPWSTR](className), 4096)
        if classfilter.len > 0:
          if fmt"{className}" != fmt"{classfilter}": return TRUE
    
        var
          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
    
    
    # callback WM_COPYDATA  - verwenden mit SendMessageCallbackW für SciTE-Antwort
    # stimmt so nicht mit Typ: SENDASYNCPROC überein
    # proc my_WMCopyData(hwnd: HWND, msg: UINT, dwData: ptr COPYDATASTRUCT, lresult: LRESULT): VOID {.stdcall.} =
    #   let
    #     cds: COPYDATASTRUCT = dwData[]
    #     recvLen = cds.cbData
    #   var 
    #     buffer: string 
    #   buffer = cast[ptr string](cds.lpData)[]
    #   received = buffer[0..recvLen - 1]
    
    
    proc GetIDByWindow(hWnd: HWND): WndID =
      var 
        pPID: LPDWORD
        pTID = GetWindowThreadProcessId(hWnd, cast[LPDWORD](addr pPID))
      result = WndID(pid: cast[int](pPID), tid: cast[int](pTID))
    
    
    proc GetEnumWindows(cfilter, tfilter: string): int =
      titlefilter = newWideCString(tfilter, tfilter.len + 1)
      classfilter = newWideCString(cfilter, cfilter.len + 1)
      sEnumWnd = newSeq[EnumWnd]()
      EnumWindows(my_WndEnumProc, lp)
      result = sEnumWnd.len
    
    
    proc GetHwndDirectorExtension(): HWND =
      # let hActive = GetForegroundWindow()         # zum Test auskommentiert
      let hScite = MyFindWindow("SciTEWindow")
      # if hActive != hScite: return 0              # zum Test auskommentiert
      let pidScite = GetIDByWindow(hScite).pid
      let dirExtCount = GetEnumWindows("DirectorExtension", "")
      if dirExtCount == 1: result = sEnumWnd[0].hwnd
      else:
        for i in 0..dirExtCount - 1:
          if pidScite == sEnumWnd[i].pid: return sEnumWnd[i].hwnd
    
    
    proc SendCommand(hwnd: HWND, cmd: string, recv: bool = false): bool =
      if hwnd == 0: return false
      var 
        cmdScite = ":" & $hwnd & ":" & cmd
        cds: COPYDATASTRUCT
      cds.dwData = 1
      cds.cbData = int32(cmdScite.len + 1)
      cds.lpData = addr cmdScite[0]
    
      received = ""
      SendMessage(hwnd, WM_COPYDATA, cast[WPARAM](hRecv), cast[LPARAM](addr cds))
      if recv:
        # callback auswerten
        var nWait = 0
        while received == "" or nWait < 100:
          sleep(20)
          nWait += 1    
        if received == "": return false
      return true
    
    
    
    # Editor Funktionen:
    
    proc OutputConsole(hwnd: HWND, value: string): bool {.discardable.} =
      result = hwnd.SendCommand("output:" & value)
    
    proc MenuCmd(hwnd: HWND, cmdID: int): bool {.discardable.} =
      result = hwnd.SendCommand("menucommand:" & $cmdID)
    
    proc ClearOutput(hwnd: HWND): bool {.discardable.} =
      result = hwnd.SendCommand("extender:dostring do output:ClearAll() end")
    
    proc CurrentFile(hwnd: HWND): string =
      if hwnd.SendCommand("askfilename:", true):
        result = received.replace(re"^:\d+:[^:]+:")
      else:
        result = ""
    
    proc GetProperty(hwnd: HWND, property: string): string =
      if hwnd.SendCommand("askproperty:" & property, true):
        result = received.replace(re"^:\d+:([^:]+:){2}")
      else:
        result = ""
    
    
    
    # Ergebnisse im Fenster anzeigen
    proc TextAdd(s: string, nl: bool = true) = 
      var nextline = "\n"
      if not nl: nextline = ""
      nsiText.appendText(s & nextline)
    
    # Scite DirectorExtension
    let hScite = GetHwndDirectorExtension()
    TextAdd("Handle DirectorExtension: 0x" & $toHex(hScite))
    
    
    # WM_COPYDATA mit Receive-Window verknüpfen - aber wie?
    # var 
    #   cdscb: COPYDATASTRUCT
    #   wpcb: WPARAM
    #   lpcb: LPARAM
    # SendMessageCallbackW(hRecv, WM_COPYDATA, wpcb, lpcb, proccb, addr cdscb)
    
    
    TextAdd("ClearOutput: ", false)   # ==> OK
    TextAdd($hScite.ClearOutput())
    
    TextAdd("OutputConsole: ", false) # ==> OK
    TextAdd($hScite.OutputConsole(r"! Das ist ein Test\n- TEST\n> TEST"))
    
    # TextAdd("Get CurrentFile: ", false)
    # TextAdd(hScite.CurrentFile())
    
    nsiFrame.show()
    nsiApp.mainLoop()
    Alles anzeigen
  • If-Abfrage mit mehreren OR funktioniert nicht

    • BugFix
    • 20. Juni 2020 um 13:10
    Zitat von Faultier_1982

    Das bedeutet, wenn ich das "Or" nicht mit Klammern von einander trenne, kann ich es auch gleich weg lassen und habe das gleiche Ergebnis?

    Du musst anders vorgehen.

    - 2 Kombinationen von Abfragen bringen ein gültiges Ergebnis, könne also mit Or verknüpft werden

    - da in jeder Kombination ein And verwendet wird ist die Kombination eindeutig durch Klammersetzung abzugrenzen

    Also: "Ereignis AND Person" stellt die Kombination dar.

    Werden mehrere der Kombinationen abgefragt, muss gesichert werden, dass diese nicht falsch verknüpft werden. Dazu einfach die einzelnen Ausdrücke einklammern.

    Das Or kannst du nicht weglassen, wenn es Bestandteil deiner Logik ist. In deinem Fall war die Abfragelogik einfach falsch.

  • If-Abfrage mit mehreren OR funktioniert nicht

    • BugFix
    • 20. Juni 2020 um 12:21
    Zitat von Faultier_1982

    Ich sehe jetzt den Fehler, verstehe ich aber noch nicht.... Was ändert sich dann an dem Oder durch die Klammern?

    Hier mal deine Befehlszeile, so, wie AutoIt sie Interpretiert (And hat eine höhere Priorität als Or) - s. rote Klammern

    If $Aufgabe_auslesen = "Messer" And StringInStr($sSource, "Max Muster") Or ($Aufgabe_auslesen = "Teller") And StringInStr($sSource, "Dennis")

    Du hast somit ein: If A And B Or C And D

    A & B & D müssen somit wahr sein, damit der gesamte Ausdruck wahr ist. Das Or spielt dadurch keine Rolle

  • If-Abfrage mit mehreren OR funktioniert nicht

    • BugFix
    • 20. Juni 2020 um 11:04

    Du musst beide Or - Blöcke auch voneinander trennen. Im Moment hast du nur EINE Anweisung, die gemischte And/OR enthält. Wenn du diese nach ihrer Wertigkeit auflöst ist das False.

    So gehts:

    AutoIt
    $Aufgabe_auslesen = "Messer"
    $sSource = "bla bla Max Muster bla bla"
    
    If $Aufgabe_auslesen = "Messer" And StringInStr($sSource, "Max Muster") Then MsgBox(0,$Aufgabe_auslesen, "geht doch 1" )
    If ($Aufgabe_auslesen = "Messer" And StringInStr($sSource, "Max Muster")) Or ($Aufgabe_auslesen = "Teller" And StringInStr($sSource, "Dennis")) Then MsgBox(0,$Aufgabe_auslesen, "geht doch 2" )


    EDIT:

    Falls du mehrmals einen gleichartigen Vergleich vornehmen musst, kann es sich auch lohnen, das in eine Funktion auszulagern. Besser lesbar ist es dann meist auch:

    AutoIt
    $Aufgabe_auslesen = "Messer"
    $sSource = "bla bla Max Muster bla bla"
    
    If _Compare("Messer", "Max Muster") Or _Compare("Teller", "Dennis") Then MsgBox(0, $Aufgabe_auslesen, "geht doch 2")
    
    Func _Compare($p1, $p2)
        Return ($Aufgabe_auslesen = $p1) And StringInStr($sSource, $p2)
    EndFunc
  • ​Sammlung: Nim Snippets / Procedures

    • BugFix
    • 20. Juni 2020 um 10:54

    Und nochmals zum Enumerieren der Fenster. In dieser Version kann man class/title wie folgt auflisten:

    Parameter kind

    • "l" (Literal, Standard) Klasse/Titel muss identisch mit übergebenem Text sein
    • "p" (Partial) Klasse/Titel enthält übergebenen Text, Groß-/Kleinschreibung wird ignoriert
    • "r" (Regex) Klasse/Titel wird mit dem übergebenen Pattern gefiltert, Flag reIgnoreCase ist gesetzt
    Code
    import strutils, re 
    include winim/[inc\winuser]
    
    type
      WndID = object
        pid, tid: int
      EnumWnd = object
        hwnd: HWND
        class: string
        title: string
        pid, tid: int
    
    var 
      sEnumWnd = newSeq[EnumWnd]()
      lp: LPARAM
      btop = true  # enum only top windows, may be changed
    
      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
    
    
    proc my_WndEnumProc(hwnd: HWND, lp: LPARAM): WINBOOL {.stdcall.} =
      if btop and GetParent(hwnd) != 0: return TRUE
      var
        buflen = GetWindowTextLengthW(hwnd) + 1
        buf = newWideCString("", buflen)
        className = newWideCString("", 256)
        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), 256)
      if buf.len != 0:
        sEnumWnd.add(EnumWnd(hwnd: hwnd, 
                            class: $className, 
                            title: $buf,
                            pid: oWndID.pid,
                            tid: oWndID.tid))
      return TRUE
    
    # kind: 'l'=literal, 'p'=partial, 'r'=regex
    proc WinList(class: string = "", title: string = "", kind: char = 'l'): seq[EnumWnd] =
      proc IsPart(full, part: string): bool =
        result = full.find(re(escapeRe(part), {reExtended, reStudy, reIgnoreCase})) > -1
    
      proc IsRegex(full, pattern: string): bool =
        let rp = re(pattern, {reExtended, reStudy, reIgnoreCase})
        result = full.find(rp) > -1
    
      proc IsEqual(s1, s2: string): bool =
        result = s1 == s2
    
      EnumWindows(my_WndEnumProc, lp)
      if class == "" and title == "": return sEnumWnd
      var 
        sWnd = newSeq[EnumWnd]()
        # name: string
        compare = IsEqual      # what kind of comparisation will used
      if kind == 'p': compare = IsPart
      elif kind == 'r': compare = IsRegex
    
      for i in 0..sEnumWnd.len - 1:
        if class == "" and title != "":
          if compare(sEnumWnd[i].title, title): sWnd.add(sEnumWnd[i]) 
        elif class != "" and title == "":
          if compare(sEnumWnd[i].class, class): sWnd.add(sEnumWnd[i])
        else:
          if compare(sEnumWnd[i].title, title) and compare(sEnumWnd[i].class, class): sWnd.add(sEnumWnd[i])
      result = sWnd
    
    
    # kind: 'l'
    # let sWinList = WinList(class = "DirectorExtension")
    # ==>
    # 000000000004041A    DirectorExtension    7152
    
    # kind: 'p'
    # let sWinList = WinList(class="scite", kind='p')
    # ==>
    # 00000000000603BE    C:\CODE\AutoIt\TEST\t.au3 - SciTE [15 of 18]    7152
    
    # kind: 'r'
    # alle Fenster mit *.au3 in "..\code\autoit...
    # let sWinList = WinList(title=r"\\code\\autoit.+\.au3", kind='r')
    # ==>
    # 00000000002A0538    C:\CODE\AutoIt\TOOLS\VariableHandler.au3 - Notepad++    14140
    # 00000000000603BE    C:\CODE\AutoIt\TEST\t.au3 - SciTE [15 of 18]    7152
    
    
    for i in 0..sWinList.len - 1: echo toHex(sWinList[i].hwnd), "\t", sWinList[i].title, "\t", sWinList[i].pid
    Alles anzeigen
  • der Neue...

    • BugFix
    • 19. Juni 2020 um 07:18

    Hallo und Willkommen.

    Keine Sorge, dumme Fragen gibt es nicht. Maximal schlecht gestellte. ^^

    Einfach mal diesen Post beachten: Autoit-Anfänger Guide / Wie poste ich richtig?

  • Nim-WindowInfo

    • BugFix
    • 18. Juni 2020 um 18:09
    Zitat von Oscar

    Ich habe "wSetClipboard" gefunden, aber kein Beispiel dazu und alle meine Versuche schlugen fehl.

    Versuch mal Cliptomania

    EDIT:

    Oder du verwendest SetClipboardData / GetClipboardData aus der winuser.nim

  • Fenster aktivieren

    • BugFix
    • 17. Juni 2020 um 23:13
    Zitat von Oscar

    Ich habe noch eine Möglichkeit gefunden, das aktive Fenster zu ermitteln:

    Ja, das scheint tatsächlich zuverlässig zu sein. :theke:

  • GetWindowRect liefert Fehler: Ungültiges Window Handle

    • BugFix
    • 17. Juni 2020 um 16:50
    Zitat von @Oscar

    Genau das stört mich an Nim auch.

    Ich werde mir mal die c2nim genauer anschauen. Vielleicht lässt sich da einiges verwenden um einen eigenen Konverter für einzelne Funktionen / Typen zu erstellen. Oder einen Multicaster basteln, der immer den korrekten Nim Datentyp ausspuckt: mcast(irgendwas) == Nim-Typ. :thumbup:

  • GetWindowRect liefert Fehler: Ungültiges Window Handle

    • BugFix
    • 17. Juni 2020 um 15:40

    Wie es aussieht, wurde die gesamte WinAPI mittels c2nim übersetzt. Dadurch verwendet winim auch die Typen von dort, was dann leicht zu Verwirrungen führt (jedenfalls bei mir). Das blöde ist, dass z.B. ein in winim verwendeter DWORD (in nim: int32) nicht mit einem int32 besetzt werden kann. Ich muss int32 zu DWORD casten, sonst meckert der Compiler.

  • Fenster aktivieren

    • BugFix
    • 17. Juni 2020 um 15:14
    Zitat von Bitnugger

    So bekommst du nur die Windows vom primären Desktop/Monitor.

    Ich beschäftige mich erst mal noch mit Testen aller möglichen Funktionen. Den Luxus mehrerer Monitore habe ich nicht (oder selten) und somit ist das in der Prioritätsliste weit unten. ;)

  • GetWindowRect liefert Fehler: Ungültiges Window Handle

    • BugFix
    • 17. Juni 2020 um 14:47
    Zitat von Oscar

    Ja, aber der Grund ist, dass Du zwar einen Pointer hast, aber der zeigt auf keinen Speicher für das RECT.

    :Face:

    Aber die Fehlermeldung ist ja dann mal seeehr zielführend.

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™