Kleines asynchrones such Tool für die IDE PBTool 1.0

Du brauchst Grafiken, gute Programme oder Leute die dir helfen? Frag hier.
Benutzeravatar
tft
Beiträge: 553
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Kleines asynchrones such Tool für die IDE PBTool 1.0

Beitrag von tft »

Hallo,

mir ist bewusst das dieses kleine Tool, wirklich nur etwas ganz einfaches ist. Aber erstaunlicher weise
hilft es mir gerade sehr. Bei meinem aktuellen Projekt den überblick zu behalten. Angefangen hat es mit meiner
Frage nach der Möglichkeit in der IDE Hyperlinks einzusetzen. Um schnell bestimmte Stellen in einem
Projekt zu finden. Zum Beispiel den Ort wo eine Variable Definiert wurde und in welcher Projet Datei.

Dabei ist dann nach wenigen Tagen, dieses kleine Stück Code entstanden. Ich habe es sogar zu einem WatshDog
erweitert. Den Code dazu werde ich jetzt nicht extra entfernen.

Ich benutze das Tool jetzt seid einiger Zeit selber. Daher habe ich die meisten Bugs finden können.
Aber wenn ihr Ungereimtheiten bei der Such Funktion findet. Bin ich gerne bereit Anpassungen vorzunehmen.

Also ..... was mache ich mit dem Tool.

Ich suche nach dem String den ich mit ctrl + c vom Editor in das ClipBoard kopiert habe, in den Inklude Dateien
die durch das Projektfile definiert sind. Gebe den Namen der Datei aus und die Zeile wo es zu finden ist mit dem
Inhalt der gesamtem Zeile. Der Suchtext ist dabei farbig markiert. Zu mindestens in der Consolen Ausgabe.

Als Optinen zum suchen gibt es zur zeit folgende Möglichkeiten.

CTRL + C : übernimmt den String aus der Zwischenablage.
CTRL + 1 : Sucht nach einer Konstante und gibt deren Inhalt aus , der String muss mit einer Raute beginnen.
CTRL + 3 : Sucht allgemein nach dem Text in allen Inklude Files des Projektes und gibt die Treffer aus.
CTRL + 4 : Sucht nach der Define Anweisung einer Variablen

Über schlechtes und gutes Feedback freue ich mich immer. Auch Vorschläge was noch alles eingebaut werden
könnte höre ich mir gerne an.

Code: Alles auswählen

;
; PBTool 1.0 By TFT | Temuçin SourceMagic | Bahnhofstr.15 | CH-8447 Dachsen/Zürich/Schweiz
;
; Letztes UpDate 10.4.2021 : 12:00
;
; Das programm arbeitet simultan. Es nimmt den Text aus dem Clipboard und sucht in allen .pbi Dateien
; des Projekt nach dem Text. Wo es gefunden wird gibt es eine Ausgabe mit zeilen nummer und in welcher
; Datei es sich befindet.
; Ich nutze es um zu sehen wo überall bestimmte Strings zu finden sind. Wenn ich eine variable suche oder
; widermal beim Code aufräumen bin. 
; Wenn ich mal wider nicht weis wo ich eine Varaible oder einen Befehl wider überall verwende.
; Das gute daran ist. Das es unabhängig vom Editor funktioniert.
;
; Bei ctrl + C , werden nach 500 ms die Text Daten aus dem Clipboard geholt und mit ctrl + 3
; wird in allen Dateien die im ProjetFile definiert sind danach gesucht und im DebugFenster
; einer Console ausgegeben. ctrl + 1 sucht in den Resurces von PB nach einer Konstante und
; gibt diese aus. ctrl + 4 sucht nach der "Define " eienr Variablen.
;

EnableExplicit

#MainWIndow = 0
#MainName = "PBTools"

;- Start einstellungen ------------------------------------------------
;-
#ComplierPfad  = "c:\Program Files\PureBasic\Compilers\pbcompiler.exe" ;- Pfad zur Compiler Exe "pbcompiler.exe"
#ResurcenPfad1 = "c:\Program Files\PureBasic\Residents\PureBasic.res"  ;- Pfade zu der Resurcen Dateien
#ResurcenPfad2 = "c:\Program Files\PureBasic\Residents\Windows.res"    ;- "PureBasic.res" "Windows.res"
Define ProjektFile.s = "_Project_3dx2mesh.pbp"                         ;- Name der Project Datei

#OutPutConsoleX = -800                                                 ;- Position X des Consolen Fensters
#OutPutConsoleY = 20                                                   ;- Position Y des Consolen Fensters
#OutPutDebugerX = -1900                                                ;- Position X des Debug Fensters
#OutPutDebugerY = 20                                                   ;- Position Y des Debug Fensters
                                                                       ;- Bei mehreren Bidschirmen kann natürlich auch 
                                                                       ;- eine Negativer wert benutzt werden.
#OutPutConsole = 1                                                     ;- OutPut auf die Console JA/NEIN
#OutPutDebuger = 1                                                     ;- OutPut auf das Debugger Fenster JA/NEIN
;-
;- Einstellung Ende --------------------------------------------------
;-

#RunWatshDog = 0
#PRG_BINDUNG   = "3dx2mesh"

#WD_Start           = 0
#WD_Close           = 1
#WD_ThreadIsRunning = 2
#WD_Print           = 3

;{ Consolen ausgabe & Font ändern

; Aufrufen nach öffnen der Console mit "ConsoleFont(#Null,#Null,"Lucida Console",20)"
Import "kernel32.lib"
  SetCurrentConsoleFontEx.i(hConsoleOutput.i,bMaximumWindow.i,*lpConsoleCurrentFontEx)
EndImport

Structure CONSOLE_FONT_INFO_EX
  cbSize.l
  nFont.l
  dwFontSize.COORD
  FontFamily.l
  FontWeight.l
  FaceName.w[#LF_FACESIZE]
EndStructure

Procedure.i ConsoleFont(*Buffer,BufferSize.i,FontName.s,FontSize.i)
  Protected cfiex.CONSOLE_FONT_INFO_EX
  Protected res.i
  Protected length.i
  Protected font_resource.i
  With cfiex
    length = Len(FontName)
    If length < #LF_FACESIZE
      \cbSize = SizeOf(CONSOLE_FONT_INFO_EX)
      \nFont = #Null
      \dwFontSize\x = #Null
      \dwFontSize\y = FontSize
      \FontFamily = #FF_DONTCARE
      \FontWeight = #FW_DONTCARE
      If *Buffer And BufferSize
        AddFontMemResourceEx_(*Buffer,BufferSize,#Null,@res)
      EndIf
      length << 1
      CopyMemory(@FontName,@\FaceName[0],length)
      ProcedureReturn SetCurrentConsoleFontEx(GetStdHandle_(#STD_OUTPUT_HANDLE),#False,@cfiex)
    EndIf
    ProcedureReturn #False
  EndWith
EndProcedure
;}

If #OutPutConsole = 1 : OpenConsole("OnError") : ConsoleFont(#Null,#Null,"Lucida Console",12) : EndIf

#OutPutModus_EVER = 0 ; Gibt den Text immer aus
#OutPutModus_PINT = 1 ; PrintItNewText , es wird nur dan audgegeben, wenn es ungleich des vorherigen Textes war

Declare OutPut(text.s,arg1.s = "",modus= 0)
Declare Error(text.s,arg1.s="",arg2.s="")

Macro ER
  "Error in Line ("+Str(#PB_Compiler_Line)+")"
EndMacro

Procedure Error(text.s,arg1.s="",arg2.s="")
  
  Protected t.s = text+" arg1 = ("+arg1+")"+" arg2 = ("+arg2+")"
  
  If #OutPutConsole = 0 : OpenConsole("OnError") : EndIf
  
  OutPut(text)
  OutPut("arg1 = ("+arg1+")")
  OutPut("arg2 = ("+arg2+")")
  
  OutPut("Enter key to exit")
  
  Input()
  CloseConsole()
  End
  
EndProcedure
Procedure OutPut(text.s,arg1.s = "",modus= 0)
  
  Static told.s
  Protected p0, p1, p2, p3, ts.s
  
    If #OutPutDebuger = 1 : Debug text : EndIf
    If #OutPutConsole = 1 
      If arg1<>""
        
        p0 = Len(Text)
        p1 = Len(arg1)
        p2 = 1
        p3 = 1
        
        p2 = FindString(text,arg1,p3,#PB_String_NoCase) 
        If p2 > p3
          
          ; den vorderen Teil des String ausgeben sofern es vorne einen teil gibt
          ConsoleColor(7,0)
          ts = Mid(text,1,p2-1)
          Print(ts)        
          
          While p2 > 0
            ConsoleColor(7,0)        
            ;p2 = FindString(text,arg1,p3,#PB_String_NoCase) 
            If p2 > p3
              ts = Mid(text,p2,p1)
              ConsoleColor(14,1) 
              Print(ts) 
              ConsoleColor(7,0)
              ;Debug ts
            EndIf
            p3 = p2 + p1
            p2 = FindString(text,arg1,p3,#PB_String_NoCase )
            If p2 > 0
              ts = Mid(text,p3,p2-p3)
              ConsoleColor(7,0)
              Print(ts)
            EndIf
            
            ;Debug p3
          Wend        
          ConsoleColor(7,0)
          PrintN(Mid(text,p3,p0-p3+1))
          
        Else
          ConsoleColor(7,0)
          PrintN("Fehler bei der Suchfunktion")
        EndIf 
      Else
        ConsoleColor(7,0) 
        If Modus = #OutPutModus_PINT
          If told <> text 
            PrintN(text)
            told = text
          EndIf        
        Else
          PrintN(text)
          told = text
        EndIf
        
      EndIf
    EndIf
    
  EndProcedure
  
  ;{ Send Key 
  
; Posted 07 April 2003 by Danilo on german forum

;SendKeys(handel,Window$,Keys$) 

;Handel ......... ist ein Handel zu einen Fenster bekommst du wenn du das Fenster erzeugst. 
;Window$ ........ Ist der Name des Fesnters, wenn du den Handel nicht kennst. In dem Fall gibt man dan Handel = 0 an. 
;Keys$ .......... Sind die Tasten die du schicken möchtest, wobei du Sondertasten in {} Einschliest (zb. {CONTROLDOWN}) 

; SendKeys procedure by PB -- do whatever you want with it. :) 
; Syntax: r=SendKeys(handle,window$,keys$) ; r = 0 for failure. 
; Specify either a handle or window$ title to type to, but not both! 
; You cannot type curly braces { } as part of the keystrokes, sorry! 
; 
Procedure SendKeys(handle,window$,keys$) 
  
  Protected thread1,thread2,r,vk$,s,s$,vk,shifted
  
  If window$<>"" : handle=FindWindow_(0,window$) : EndIf ; Use window$ instead of handle. 
   If IsWindow_(handle)=0 ; Does the target window actually exist? 
      ProcedureReturn 0 ; Nope, so report 0 for failure to type. 
   Else 
   ; This block gives the target window the focus before typing. 
   thread1=GetWindowThreadProcessId_(GetForegroundWindow_(),0) 
   thread2=GetWindowThreadProcessId_(handle,0) 
   If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#True) : EndIf 
      SetForegroundWindow_(handle) ; Target window now has the focus for typing. 
      Delay(125) ; 1/8 second pause before typing, to prevent fast CPU problems. 
      ; Now the actual typing starts. 
      For r=1 To Len(keys$) 
          vk$=Mid(keys$,r,1) 
          If vk$="{" ; Special key found. 
             s=FindString(keys$,"}",r+1)-(r+1) ; Get length of special key. 
             s$=Mid(keys$,r+1,s) ; Get special key name. 
             Select s$ ; Get virtual key code of special key. 
                Case "ALTDOWN" : keybd_event_(#VK_MENU,0,0,0) ; Hold ALT down. 
                Case "ALTUP" : keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT. 
                Case "BACKSPACE" : vk=#VK_BACK 
                Case "CONTROLDOWN" : keybd_event_(#VK_CONTROL,0,0,0) ; Hold CONTROL down. 
                Case "CONTROLUP" : keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL. 
                Case "DELETE" : vk=#VK_DELETE 
                Case "DOWN" : vk=#VK_DOWN 
                Case "END" : vk=#VK_END 
                Case "ENTER" : vk=#VK_RETURN 
                Case "T" : vk=#VK_T 
                Case "A" : vk=#VK_A 
                Case "D" : vk=#VK_D 
                Case "X" : vk=#VK_X 
                Case "V" : vk=#VK_V 
                Case "F1" : vk=#VK_F1 
                Case "F2" : vk=#VK_F2 
                Case "F3" : vk=#VK_F3 
                Case "F4" : vk=#VK_F4 
                Case "F5" : vk=#VK_F5 
                Case "F6" : vk=#VK_F6 
                Case "F7" : vk=#VK_F7 
                Case "F8" : vk=#VK_F8 
                Case "F9" : vk=#VK_F9 
                Case "F10" : vk=#VK_F10 
                Case "F11" : vk=#VK_F11 
                Case "F12" : vk=#VK_F12 
                Case "ESCAPE" : vk=#VK_ESCAPE 
                Case "HOME" : vk=#VK_HOME 
                Case "INSERT" : vk=#VK_INSERT 
                Case "LEFT" : vk=#VK_LEFT 
                Case "PAGEDOWN" : vk=#VK_NEXT 
                Case "PAGEUP" : vk=#VK_PRIOR 
                Case "PRINTSCREEN" : vk=#VK_SNAPSHOT 
                Case "RETURN" : vk=#VK_RETURN 
                Case "RIGHT" : vk=#VK_RIGHT 
                Case "SHIFTDOWN" : shifted=1 : keybd_event_(#VK_SHIFT,0,0,0) ; Hold SHIFT down. 
                Case "SHIFTUP" : shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT. 
                Case "TAB" : vk=#VK_TAB 
                Case "UP" : vk=#VK_UP 
             EndSelect 
             If Left(s$,3)<>"ALT" And Left(s$,7)<>"CONTROL" And Left(s$,5)<>"SHIFT" 
                keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the special key. 
             EndIf 
             r=r+s+1 ; Continue getting the keystrokes that follow the special key. 
          Else 
             vk=VkKeyScanEx_(Asc(vk$),GetKeyboardLayout_(0)) ; Normal key found. 
             If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,0,0) : EndIf ; Due to shifted character. 
             keybd_event_(vk,0,0,0) : keybd_event_(vk,0,#KEYEVENTF_KEYUP,0) ; Press the normal key. 
             If vk>304 And shifted=0 : keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) : EndIf ; Due to shifted character. 
          EndIf 
      Next 
      If thread1<>thread2 : AttachThreadInput_(thread1,thread2,#False) : EndIf ; Finished typing to target window! 
      keybd_event_(#VK_MENU,0,#KEYEVENTF_KEYUP,0) ; Release ALT key if user forgot. 
      keybd_event_(#VK_CONTROL,0,#KEYEVENTF_KEYUP,0) ; Release CONTROL key if user forgot. 
      keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0) ; Release SHIFT key if user forgot. 
      ProcedureReturn 1 ; Report successful typing! :) 
   EndIf 
EndProcedure   

;}

  OutPut("") 
  OutPut("PBTool by TFT | (C) by Temucin SourceMagic") 
  OutPut("Bahnhofstrasse 15 | 8447 Dachens Schweiz") 
  OutPut("")
  OutPut("LeftControl + H : Print Help to Console") 
  OutPut("")
  
;{ Load Project File Name

Structure ListText
  text.s
EndStructure

NewList LT.ListText()

Define result, arg1.s, arg2.s, t.s, p1, p2

arg1 = GetCurrentDirectory()+ProjektFile.s
result = FileSize(arg1)   : If result < 1 : Error(ER,arg1) : EndIf
result = ReadFile(0,arg1) : If result < 1 : Error(ER,arg1) : EndIf

ClearList(LT())
While Eof(0)=0
  t = ReadString(0)
  If FindString(t,"<file name=",1)
    ;Debug("Project Files to Search "+t)
    p1= FindString(t,"=",1)+1
    p2 = FindString(t,">",1)
    t = Mid(t,p1+1,p2-p1-2)
    AddElement(LT())
    LT()\text = t
  EndIf  
Wend
CloseFile(0)

;}

Define VK_LCONTROL_VK_C_SET = 0
Define VK_LCONTROL_VK_3_SET = 0
Define VK_LCONTROL_VK_1_SET = 0
Define VK_LCONTROL_VK_4_SET = 0
Define VK_LCONTROL_VK_H_SET = 0

Define Quit, Event
Define Text.s, LineCount, Aktuelles_SuchFile.s, EintragGefunden

Define st.Point
Define xold, yold, told

;{ Shared Memory für Nachrichten übermittlung mittel Window Handler

#MsgRemote = #WM_USER + 500   ; (INT 1025) (HEX 0400) + 500
#TimeOut = 6000

Structure myhwnds
  hWnd.i
  text.s{256}
EndStructure

Define HandleMapCreate, HandleMapOpen, *memOpen.myhwnds, *memCreate.myhwnds , Time_.q

Procedure CreateSharedMemory(Name.s, Size)
  Shared HandleMapCreate
  HandleMapCreate = CreateFileMapping_(#INVALID_HANDLE_VALUE, 0, #PAGE_READWRITE|#SEC_COMMIT|#SEC_NOCACHE, 0, Size, @Name)
  If HandleMapCreate
    ProcedureReturn MapViewOfFile_(HandleMapCreate, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
  EndIf
EndProcedure

Procedure OpenSharedMemory(Name.s)
  Shared HandleMapOpen
  HandleMapOpen = OpenFileMapping_(#FILE_MAP_ALL_ACCESS, 0, @Name)
  If HandleMapOpen
    ProcedureReturn MapViewOfFile_(HandleMapOpen, #FILE_MAP_ALL_ACCESS, 0, 0, 0)
  EndIf
EndProcedure

Procedure CloseSharedMemory(MemoryAddress)
 Shared HandleMapOpen ,HandleMapCreate
  UnmapViewOfFile_(MemoryAddress)
  If HandleMapOpen > 0
    CloseHandle_(HandleMapOpen)
  EndIf
  If HandleMapCreate > 0
    CloseHandle_(HandleMapCreate)
  EndIf
EndProcedure

; ; Als erstes Versuchen wir Kontakt aufzunehmen, indem wir versuchen den SharedMemory zu öffnen
; time_ = ElapsedMilliseconds() + #TimeOut
; Repeat
;   *memOpen = OpenSharedMemory(WatshDogName.s)
;   Delay(10)
; Until *memOpen Or ElapsedMilliseconds() > time_
; 
; If Not *memOpen
;   BreakCode(DL(),"WatshDog nicht gefunden") 
; Else
;   DebugLog(DL(),"WatshDog gefunden")
; EndIf

;}

;{ Load Konstanten .res

;Daten Aufbau
;
; Konstanten fangen mit "PB_" = 50 42 5F (HEX)
; Der String ändet mit 00
; Gefolgt von eimem Byte das den DatenType danach an gibt.
;
; -1 -1 -1 -1 Quad    00 08
; -1 -1 -1 -1 Ascii   00 01
; -1 -1 -1 -1 Integer 00 08
; -1 -1 -1 -1 Word    00 02
; -1 -1 -1 -1 Long    00 04
; -1 -1 -1 -1 Double  00 08
; -1 -1 -1 -1 Float   00 04
; -1 -1 -1 -1 String  00 08
; -1 -1 -1 -1 
;
; 00 = 1 Byte
; 01 = 2 Byte
; 02 = 4 Byte
; 05 = 4 Byte  Flieskomme
;
; 30 = Struktur Daten
; 
; -1 -1 -1 -1 T  S  N  C  4  
; FF FF FF FF 54 53 4E 43 34 84 00 00 = Anfangs Kennung für die Konstanten
; 
;                P  R  O  T  .  .  .  .
; Letzer eintrag 50 52 4F 54 00 00 00 00 
; 
Define FS = FileSize(#ResurcenPfad1)
Define WS = FileSize(#ResurcenPfad2)
If FS > 0 And WS > 0
  OutPut("Read Data from "+#ResurcenPfad1)
  OutPut("Read Data from "+#ResurcenPfad2)
  Define *sp = AllocateMemory(WS+FS+4)
  OutPut("Allocate Mem "+Str(WS + FS + 4)+" Byte")
  If *sp > 0
    ReadFile(0,#ResurcenPfad1)
    FS = Lof(0)
    ReadData(0,*sp,FS)
    CloseFile(0)
    ReadFile(0,#ResurcenPfad2)
    WS = Lof(0)
    ReadData(0,*sp+FS,WS)
    CloseFile(0)    
  EndIf
Else
  OutPut("Konte "+#ResurcenPfad1+" nicht laden") 
EndIf

;}

; #OFN_ENABLESIZING       = $800000

;{ System Filerequester

Structure OPENFILENAME_EX Extends OPENFILENAME
  pvReserved.l
  dwReserved.l
  FlagsEx.i
EndStructure   
 
Procedure.s OpenFileRequester_Ex(Title$,Pattern$,Defdir$,Deffile$)
  
    Protected *Buffer = AllocateMemory(StringByteLength(Pattern$)+2), i, file$, of.OPENFILENAME_EX

    For i = 0 To StringByteLength(Pattern$)     
      PokeB(*Buffer+i,PeekB(@Pattern$+i))
      If PeekB(@Pattern$+i) = 124
        PokeB(*Buffer+i,0)
      EndIf
    Next
    
    of\lStructSize = SizeOf(of)
    of\lpstrTitle = @Title$
    of\lpstrInitialDir = @Defdir$
    of\lpstrFilter = *Buffer
    of\nMaxFile = #MAX_PATH
    of\lpstrFile = @Deffile$
    of\lCustData = 0
    of\Flags     = #OFN_EXPLORER | #OFN_LONGNAMES | #OFN_CREATEPROMPT | #OFN_ENABLEHOOK| #OFN_ENABLESIZING
    of\FlagsEx   = 0
    
    If GetOpenFileName_(of)
      File$ = PeekS(of\lpstrFile)
    EndIf
    
    ProcedureReturn File$
    
EndProcedure   
 
Define Title$   = "Please choose file to Open"
Define Pattern$ = "Text (*.txt)|*.txt;*.bat|PureBasic (*.pb)|*.pb|All files (*.*)|*.*"
Define Defdir$  = GetCurrentDirectory()
Define Deffile$ = Space(250)

;Define File$ = OpenFileRequester_Ex(Title$,Pattern$,Defdir$,Deffile$)
;Debug File$

;}

Define WDTimer.q = ElapsedMilliseconds() + 2000

If OpenWindow(#MainWIndow,-205,20,200,100,#MainName)
  Delay(200)
  
  ;{ SharedMemory erzeugen
  ; wir erstellen ein SharedMemory der auf den Namen "myfernseher" hört
  *memCreate = CreateSharedMemory(#MainName, SizeOf(myhwnds))
  ; und belegen den Speicher mit den nötigen Handles
  If *memCreate
    With *memCreate
      \hWnd     = WindowID(#MainWIndow)
    EndWith
  EndIf
  ;}
  ;{ Das OnError COnsolen Fenster finden und verschieben
  
  Define hWnd = 0
  Define cnt = 0
  Repeat
    ;hWnd = FindWindowEx_(0, hWnd, @"NotePad", 0)
    hWnd = FindWindowEx_(0, hWnd, 0, 0)
    If hwnd
      cnt + 1
      Define   title.s = Space(512)
      GetWindowText_(hWnd, @title, 512)
      If title = "OnError"
        Debug "" + cnt + ": " + title+" hwnd "+Str(hwnd)
        MoveWindow_(hWnd,#OutPutConsoleX,#OutPutConsoleY,600,600,1)
      ElseIf FindString(title,"Debugger-Ausgabe - "+#MainName,1)
        Debug "" + cnt + ": " + title+" hwnd "+Str(hwnd)
        MoveWindow_(hWnd,#OutPutDebugerX,#OutPutDebugerY,600,600,1)
      EndIf
      
    EndIf
  Until hWnd = 0
  
;}
  
  ; SendKeys(0,"WatshDog","A")
  
  Repeat
    
    ;{ Event Handling
    Event = WindowEvent()
    While Event <> 0
      Select Event
        Case #MsgRemote
          Select EventwParam()
            Case #WD_Print 
              OutPut("Print Comand","",#OutPutModus_EVER)
              ;Define TEX.S = Space(256)
              ;TEX.S=PeekS(*memOpen\text,#PB_Ascii  )
              ;OutPut(">"+tex,"",#OutPutModus_EVER)
            Case #WD_Start
               ; Als erstes Versuchen wir Kontakt aufzunehmen, indem wir versuchen den SharedMemory zu öffnen
              WDTimer = ElapsedMilliseconds() + 2000
              If *memOpen = 0
                time_ = ElapsedMilliseconds() + #TimeOut
                 Repeat
                   *memOpen = OpenSharedMemory(#PRG_BINDUNG)
                   Delay(10)
                 Until *memOpen Or ElapsedMilliseconds() > time_
                 
                 If Not *memOpen
                   OutPut("Programm nicht gefunden") 
                 Else
                   OutPut("Programm gefunden")
                 EndIf 
               EndIf
            Case #WD_ThreadIsRunning
              OutPut("WatshDog reset","",#OutPutModus_PINT)
              WDTimer = ElapsedMilliseconds() + 2000
            Case #WD_Close 
              Quit = 1  
          EndSelect                  
        Case #PB_Event_CloseWindow  
          Quit = 1
        Case #WM_KEYUP 
          Select EventwParam()
            Case #ESC                   ; Programm beenden bei drücken der ESC Taste
              ;Quit = 1
          EndSelect
        Case #WM_CLOSE 
          Quit = 1
          ;OutPut("Nachricht erhalten") 
        Default
      EndSelect      
      Event = WindowEvent()
    Wend
    ;}
    ;{ Auf globale tasten und mouse ereignisse reagieren
    If GetAsyncKeyState_(#VK_LCONTROL) <> 0
      ;{ LC + H : Ausgabe eines kurzen Hilfstextes
      If GetAsyncKeyState_(#VK_H) <> 0 
        If VK_LCONTROL_VK_H_SET = 0 
          VK_LCONTROL_VK_H_SET = 1
          OutPut("") 
          OutPut("PBTool by TFT | (C) by Temucin SourceMagic") 
          OutPut("Bahnhofstrasse 15 | 8447 Dachens Schweiz") 
          OutPut("") 
          OutPut("LeftControl + C : Copy Text to ClipBoard") 
          OutPut("LeftControl + 1 : Suche und gebe den Wert der Konstante aus.")
          OutPut("LeftControl + 3 : Suche und zeige wo überall der Text im Project zu finden ist.")
          OutPut("LeftControl + 4 : Suche dehr Ort wo eine Variable Defineiert wird durch <Define >")
          OutPut("")
 
        EndIf
     Else
       VK_LCONTROL_VK_H_SET = 0
     EndIf
     ;}     
      ;{ LC + C : Holt den Text aus dem Clipboard
      If GetAsyncKeyState_(#VK_C) <> 0 
        If VK_LCONTROL_VK_C_SET = 0 
          VK_LCONTROL_VK_C_SET = 1
          Delay(400)
          Text = GetClipboardText()
          OutPut("Get Text from Clipboard = " + Text) 
        EndIf
      Else
        VK_LCONTROL_VK_C_SET = 0
      EndIf
      ;}
      ;{ LC + 3 : Sucht allgemein nach dem Text innerhakb des Purebasic Projektes
      If GetAsyncKeyState_(#VK_3) <> 0 
        If VK_LCONTROL_VK_3_SET = 0 
          VK_LCONTROL_VK_3_SET = 1          
          If Text <> ""
            OutPut(" Suche nach einträgen für (" + Text + ")")         
            If FirstElement(LT())
              ForEach LT() 
                ;OutPut("Suche ("+Text+") in ("+LT()\text+")")
                Aktuelles_SuchFile.s = LT()\text
                EintragGefunden = 0
                If ReadFile(0,GetCurrentDirectory()+LT()\text)
                  LineCount = 1
                  While Eof(0) = 0
                    t = ReadString(0) 
                    ;Debug t
                    If FindString(t, Text,#PB_String_NoCase )
                      If EintragGefunden = 0
                        OutPut("  Eintrag gefunden in ("+Aktuelles_SuchFile.s+")")
                      EndIf                      
                      EintragGefunden = 1
                      OutPut("   Line ("+Str(LineCount)+")>"+t,text) 
                    EndIf
                    LineCount = LineCount + 1
                  Wend
                  CloseFile(0)
                Else
                  OutPut("Cant Read File")
                EndIf              
              Next            
            EndIf 
          EndIf
        EndIf
      Else
        VK_LCONTROL_VK_3_SET = 0
      EndIf
      ;}
      ;{ LC + 4 : Sucht im Purebasic Projekt nach dem Begriff "Define "+ dem Suchbegriff.
                ; Damit kann man im Projekt finden vo überall eine Variable Definiert wird.
      If GetAsyncKeyState_(#VK_4) <> 0 
        If VK_LCONTROL_VK_4_SET = 0 
          VK_LCONTROL_VK_4_SET = 1  
          If Text <> ""
            OutPut(" Suche nach einträgen für (Define " + Text + ")")         
            If FirstElement(LT())
              ForEach LT() 
                ;OutPut("Suche ("+Text+") in ("+LT()\text+")")
                Aktuelles_SuchFile.s = LT()\text
                EintragGefunden = 0
                If ReadFile(0,GetCurrentDirectory()+LT()\text)
                  LineCount = 1
                  While Eof(0) = 0
                    t = ReadString(0) 
                    ;Debug t
                    If FindString(t, "Define " )
                      If FindString(t, Text,#PB_String_NoCase )
                        If EintragGefunden = 0
                          OutPut("  Eintrag gefunden in ("+Aktuelles_SuchFile.s+")")
                        EndIf                      
                        EintragGefunden = 1
                        OutPut("   Line ("+Str(LineCount)+")>"+t,text) 
                      EndIf
                    EndIf
                    LineCount = LineCount + 1
                  Wend
                  CloseFile(0)
                Else
                  OutPut("Cant Read File")
                EndIf              
              Next            
            EndIf 
          EndIf          
        EndIf
        
      Else
        VK_LCONTROL_VK_4_SET = 0
      EndIf  
      ;}
      ;{ LC + 1 : Sucht nach der Konstanten aus den Resurcen Files von PB. Aber nur PureBAsic und Windows.
      If GetAsyncKeyState_(#VK_1) <> 0 
        If VK_LCONTROL_VK_1_SET = 0 
          VK_LCONTROL_VK_1_SET = 1     
          If Text <> ""
            If Left(text,1)= "#"
              Define l1 = Len(text)-1
              text = Right(text,l1)
              OutPut(" Suche nach Konstante (#" + Text + ")") 
              If *sp > 0
                Define i = 0
                Define i1 = 0
                Repeat
                  While i1 < FS+WS
                    Define by = PeekB(*sp+i1)
                    If by = Asc(Left(text,1)) ; nach dem ersten Zeichen des suchstring suchen 
                      Define te.s = PeekS(*sp+i1,-1,#PB_Ascii  ) 
                      ;Debug te
                      If te = text 
                        i1 = i1 + Len(te)
                        Define w = PeekB(*sp+i1)
                        ;If w = 0
                          ;Debug "Kennung "+Hex(w,#PB_Byte)
                          Define w = PeekB(*sp+i1+1)
                          Define h.s = Hex(w,#PB_Byte)
                          ;Debug "Kennung "+h
                          Define in.i
                          Define in1.i
                          Define inf.f
                          Define ins.s = ""
                          Define b.s   = ""
                          If w = 0
                            in = PeekB(*sp+i1+2)
                            ins = "(INT "+Str(in)+")"
                            h.s = " (HEX "+RSet(Hex(in,#PB_Byte),2, "0")+")"
                            b   = " (BIN "+RSet(Bin(in,#PB_Byte),8, "0")+")"
                          ElseIf w = 1
                            in = PeekW(*sp+i1+2)
                            h.s = " (HEX "+RSet(Hex(in,#PB_Word),4, "0")+")"
                            ins = "(INT "+Str(in)+")"
                            b   = " (BIN "+RSet(Bin(in,#PB_Word),16, "0")+")"
                          ElseIf w = 2
                            in = PeekL(*sp+i1+2)
                            h.s = " (HEX "+RSet(Hex(in,#PB_Long),8, "0")+")"
                            ins = "(INT "+Str(in)+")"
                            b   = " (BIN "+RSet(Bin(in,#PB_Long),32, "0")+")"
                          ElseIf w = 3
                            in = PeekQ(*sp+i1+2)
                            h.s = " (HEX "+RSet(Hex(in,#PB_Quad),16, "0")+")"
                            ins = "(INT "+Str(in)+")"
                            b   = " (BIN "+RSet(Bin(in,#PB_Quad),64, "0")+")"
                          ElseIf w = 6
                            ins = " (STR "+PeekS(*sp+i1+2,-1,#PB_Ascii  )+")"
                            h = ""
                          ElseIf w = 5
                            ; Das funktioniert nicht so.
                            ; ich werde einfach einen String verwenden !!
                            ;in1 = PeekL(*sp+i1+2)
                            ;inf = 3.1415926535897931 ; PI
                            h = ""
                            ;PokeF(*sp+i1+2,inf)
                            ;in = PeekL(*sp+i1+2)
                            ;PokeL(*sp+i1+2,in)
                            ;inf.f = PeekF(*sp+i1+2)
                            ;Debug inf
                            ;ins = "FLOAT "+StrF(inf)
                            ;h.s = " HEX "+Hex(in,#PB_Long)
                            inf = ValF("3.14159274101257")
                            ins = "FLOAT "+StrF(inf)
                          EndIf
                          OutPut("  Gefunden "+ins+h+b)
                          Break 2
                        ;EndIf
                      Else
                        ;Debug "("+te+")"
                        i1 = i1 + Len(te) + 1
                      EndIf                     
                    Else
                      i1 = i1 + 1
                    EndIf                
                  Wend
                  OutPut("Keine Konstante gefunden")
                  Break
                ForEver
              EndIf              
            Else
              OutPut("Konstanten beginnen mit einer #")
            EndIf
          EndIf          
        EndIf        
      Else
        VK_LCONTROL_VK_1_SET = 0
      EndIf
      ;}
    Else
      ;{ Impulse kennung zurücksetzen
      VK_LCONTROL_VK_C_SET = 0
      VK_LCONTROL_VK_3_SET = 0
      VK_LCONTROL_VK_1_SET = 0
      VK_LCONTROL_VK_4_SET = 0
      VK_LCONTROL_VK_H_SET = 0
      ;}
    EndIf    
    ;{ Asynkrone Mouse Position holen
    GetCursorPos_(st.POINT) 
    If st\x <> xold Or st\y <> yold
      ;Debug " Mouse Position "+Str(st\x )+"/"+Str(st\y)
      xold = st\x 
      yold = st\y
    EndIf 
    ;}
    ;}
    ;{ WatshDog Funktion
    If #RunWatshDog = 1
      If WDTimer < ElapsedMilliseconds()
        WDTimer = ElapsedMilliseconds() + 2000
        OutPut("Zeitüberschreitung","",#OutPutModus_PINT)
        
        hWnd = 0
        cnt = 0
        Repeat
          ;hWnd = FindWindowEx_(0, hWnd, @"NotePad", 0)
          hWnd = FindWindowEx_(0, hWnd, 0, 0)
          If hwnd
            cnt + 1
            title.s = Space(512)
            GetWindowText_(hWnd, @title, 512)
            Debug "" + cnt + ": " + title+" hwnd "+Str(hwnd)
            If FindString(title, "PureBasic 5.73 LTS (x64)") ; 5.73 LTS (x64)
              Debug "" + cnt + ": " + title+" hwnd "+Str(hwnd)            
              MoveWindow_(hWnd,-1900,620,1900,450,1)  
              Delay(200)
              MessageRequester("Error Request","Der Render Thread/Prozess läuft nicht mer")
              MoveWindow_(hWnd,0,0,1900,1000,1) 
              Quit = 1
            EndIf          
          EndIf
        Until hWnd = 0
    
        If *memOpen
          If *memOpen\hWnd
            ;CloseWindow_(*memOpen\hWnd)
          EndIf        
        EndIf
        
      EndIf
    EndIf
    ;}
    
    Delay(1)
    
  Until Quit = 1
  
  If #OutPutConsole = 1 : CloseConsole() : EndIf
  CloseWindow(#MainWIndow)
  
  If *memCreate : CloseSharedMemory(*memCreate) : EndIf
  
EndIf

End

TFT

W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)