Seite 1 von 1

Gelöst! Runprogram Notepad Position bestimmen?

Verfasst: 07.01.2026 22:49
von EmmJott
Hi Guys!

mein kleines Programm öffnet entweder eine CMD-, eine Powershell- oder eine Notepad-Instanz mittels Runprogramm - so weit so gut.
Leider öffnen sich die Fenster an scheinbar zufälligen Stellen, meistens unter "meinem" Prog-Fenster (welches immer im Vorgrund sein muss).

Kann man die so geöffneten "fremden" Fenster von meinem Programm aus verschieben bzw. verhindern, dass sich die Fenster überlappen?

Re: Runprogram Notepad Position bestimmen?

Verfasst: 08.01.2026 15:44
von Axolotl
Unter Windows kann man das so machen.
1. Fenster Handle suchen.
2. Neue Koordinaten ans Fenster schicken.

Code: Alles auswählen

Procedure EnumWindows(hWnd, *hwndNotepad.INTEGER) 
  Protected tt${#MAX_PATH} 

  If GetClassName_(hWnd, @tt$, #MAX_PATH) And tt$ = "Notepad" 
    *hwndNotepad\i = hWnd 
    ProcedureReturn #False  ; done with the enumeration 
  Else 
    *hwndNotepad\i = 0  
    ProcedureReturn #True   ; next window 
  EndIf 
EndProcedure 


Procedure MoveNotepad(X, Y, W, H) 
  Protected hwndNotepad 

  EnumWindows_(@EnumWindows(), @hwndNotepad)  ; return value is ZERO because of callback returns ZERO, easier to check on hwndNotepad. 
  If hwndNotepad ; <> 0 
    ; Choose Flags from #SWP_SHOWWINDOW|#SWP_NOACTIVATE|#SWP_NOZORDER|#SWP_NOSIZE|#SWP_NOMOVE|#SWP_FRAMECHANGED
    SetWindowPos_(hwndNotepad, 0, X, Y, W, H, #SWP_SHOWWINDOW|#SWP_NOACTIVATE|#SWP_NOZORDER|#SWP_FRAMECHANGED)  
  Else ; do some error handling ?? 
    Debug "Notepad not found" 
  EndIf 
EndProcedure 

; RunProgram() 
; wait for open window 
MoveNotepad(100, 200, 1024, 800) 

Re: Gelöst! Runprogram Notepad Position bestimmen?

Verfasst: 08.01.2026 22:01
von EmmJott
Vielen Dank, Axolotl, für Deine Hilfe! Im Falle von Notepad funktioniert das, bei "Powershell.exe" beispielsweise nicht. Vermute, es liegt daran, dass der Name bei tt$ = "..." nicht korrekt angegeben ist.

Ich hatte gehofft, dass man den Rückgabewert von "Runprogramm" nutzen könnte, um das aufgerufene Programm eindeutig zu ermitteln. (laut Hilfetext: ... ist der Rückgabewert eine Nummer, welche das Programm identifiziert ...)
War wohl ein klarer Fall von Denkste.

Hatte auch überlegt, das Programm nicht "Notepad" starten zu lassen, sondern die entsprechende Datei, damit das System die Standard-App verwendet - aber dann kenne ich den Namen erst recht nicht vorher.

Schade - so wird das nix. Da muss man wohl "mit dem Schmerz leben".

Re: Gelöst! Runprogram Notepad Position bestimmen?

Verfasst: 09.01.2026 14:03
von Axolotl
Du kannst in der EnumProc nicht nur nach dem Classname prüfen, sondern auch nach dem Window Title ....

Code: Alles auswählen

GetWindowText_() ; same syntax as GetClassname_() 
Bei der Console steht dann sowas:

Code: Alles auswählen

WT: "C:\WINDOWS\SYSTEM32\cmd.exe" ●  CN: "CASCADIA_HOSTING_WINDOW_CLASS"
Und bei der PowerShell Console:

Code: Alles auswählen

WT: "Windows PowerShell"  ●  CN: "CASCADIA_HOSTING_WINDOW_CLASS"
Oder du probierst mal (Hat bei mir noch nie geklappt, ???)

Code: Alles auswählen

GetWindowThreadProcessId_(hWnd, @pid)  ; 
ProgNumber = RunProgram(...)   ; acc. to PB-help 
pid = ProgramID(ProgNumber)    ; acc. to PB-help 
Bei der Standard App musste bedenken, dass die Anzeige des WindowTitle konfigurierbar sein kann....
Um diese App herauszufinden brauchste dann sowas:

Code: Alles auswählen

Procedure.s GetAssociatedProgram(Extension$)  
  Protected hKey.l, dataSize.l, pos.l
  Protected KeyValue$, KeyNext$, AssociatedProgram$

  ;: init...
  hKey = 0 : dataSize = 255 : KeyValue$ = Space(dataSize) 
  AssociatedProgram$ = ""  

  If Left(Extension$, 1) <> "." : Extension$ = "."+Extension$ : EndIf 
  If RegOpenKeyEx_(#HKEY_CLASSES_ROOT, Extension$, 0, #KEY_READ, @hKey)  = #ERROR_SUCCESS  
    If RegQueryValueEx_(hKey, "", 0, 0, @KeyValue$, @datasize) = #ERROR_SUCCESS  
      KeyNext$ = Left(KeyValue$, dataSize-1)  
      ;: init...
      hKey = 0 : dataSize = 255 : KeyValue$ = Space(dataSize) 

      If RegOpenKeyEx_(#HKEY_CLASSES_ROOT, KeyNext$+"\Shell\Open\Command", 0, #KEY_READ, @hKey) = #ERROR_SUCCESS  
        If RegQueryValueEx_(hKey, "", 0, 0, @KeyValue$, @dataSize) = #ERROR_SUCCESS  
          AssociatedProgram$ = Left(KeyValue$, dataSize-1)  
        EndIf  
      EndIf  
    EndIf  
  EndIf  
  pos = FindString(LCase(AssociatedProgram$), ".exe", 1)  
  If pos <> 0  
    AssociatedProgram$ = Left(AssociatedProgram$, pos+4)  
    AssociatedProgram$ = RemoveString(AssociatedProgram$, Chr(34), 1)  
  EndIf  
  ProcedureReturn AssociatedProgram$  
EndProcedure  
 
; Debug GetAssociatedProgram("doc")  
; Debug GetAssociatedProgram("xls")  
; Debug GetAssociatedProgram("mdb")  
; Debug GetAssociatedProgram("jpg")  
; Debug GetAssociatedProgram("gif")  
; Debug GetAssociatedProgram("htm")  

Re: Gelöst! Runprogram Notepad Position bestimmen?

Verfasst: 09.01.2026 14:38
von NicTheQuick
Bezüglich des Rückgabewerts von `RunProgram`: Damit erhältst du nur die Prozess-ID. Aber jeder Prozess kann beliebig viele Fenster erzeugen und anzeigen. Deswegen ist es nicht so einfach von der PID zum Window-Handle zu kommen. Und in manchen Fällen wird der Prozess auch wieder direkt beendet. Das einfachste Beispiel dafür ist wohl ein Browser. Den haben viele durchgehend geöffnet, und wenn du jetzt per `RunProgram` den Browser mit einer URL öffnest, dann startet kurzzeitig ein neuer Prozess, aber der stellt dann schnell fest, dass der Browser schon läuft und übergibt dem bereits laufenden Prozess die zu öffnende URL und beendet sich dann selbst wieder. Das heißt mit dieser PID hättest du gar nichts anfangen können, weil der Prozess nie selbst ein Fenster erstellt hat.