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