Gelöst! Runprogram Notepad Position bestimmen?

Anfängerfragen zum Programmieren mit PureBasic.
EmmJott
Beiträge: 56
Registriert: 25.10.2024 12:23

Gelöst! Runprogram Notepad Position bestimmen?

Beitrag 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?
Zuletzt geändert von EmmJott am 08.01.2026 21:48, insgesamt 1-mal geändert.
Bin aktiv in der rentenvorbereitenden Arbeitslosigkeit - zwangsweise. Auch nach >30 Jahren im Betrieb springst Du über die Klinge, wenn der (Miss-)Manager seinen Hintern retten will. Lasst Euch von euren Arbeitgebern bloß nix von wegen Loyalität erzählen - wenn's drauf ankommt, ist die nix Wert!
Axolotl
Beiträge: 308
Registriert: 31.12.2008 16:34

Re: Runprogram Notepad Position bestimmen?

Beitrag 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) 
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
EmmJott
Beiträge: 56
Registriert: 25.10.2024 12:23

Re: Gelöst! Runprogram Notepad Position bestimmen?

Beitrag 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".
Bin aktiv in der rentenvorbereitenden Arbeitslosigkeit - zwangsweise. Auch nach >30 Jahren im Betrieb springst Du über die Klinge, wenn der (Miss-)Manager seinen Hintern retten will. Lasst Euch von euren Arbeitgebern bloß nix von wegen Loyalität erzählen - wenn's drauf ankommt, ist die nix Wert!
Axolotl
Beiträge: 308
Registriert: 31.12.2008 16:34

Re: Gelöst! Runprogram Notepad Position bestimmen?

Beitrag 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")  
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8831
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Gelöst! Runprogram Notepad Position bestimmen?

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