Forum: PC-Programmierung [C,WinAPI] Fenster eines anderen (eigenen) Programms verschieben


von Timmo H. (masterfx)


Lesenswert?

Ich habe folgendes Problem:
Ich habe 3 Anwendungen programmiert (rein WinAPI mit Ressource), die 
über ein weiteres Programm per CreateProcess (oder wie auch immer) zu 
einer dynamischen Anzahl von Instanzen gestartet werden sollen. Damit 
die einzelnen Fenster nicht übereinander liegen wollte ich die Fenster 
schön neben- und untereinander anordnen. Nur leider reagieren die 
Fenster da nicht drauf wenn ich es so mache:
1
  STARTUPINFO     StartupInfo;
2
  PROCESS_INFORMATION ProcInfo;
3
  HWND window[10];
4
  
5
  memset(&ProcInfo, 0, sizeof(ProcInfo)); 
6
  memset(&StartupInfo, 0 , sizeof(StartupInfo));
7
  
8
  StartupInfo.cb = sizeof(StartupInfo); // Set structure size 
9
  StartupInfo.dwX = 100 ; 
10
  StartupInfo.dwY = 300 ; 
11
  StartupInfo.wShowWindow = SW_SHOW; 
12
  StartupInfo.dwFlags = STARTF_USEPOSITION | STARTF_USESHOWWINDOW | STARTF_USESIZE ; 
13
  
14
                
15
  window[0] = CreateProcess(NULL, "anwendung1.exe", NULL, NULL, NULL, 
16
                          NULL, NULL, NULL, &StartupInfo, &ProcInfo);
Der Maindialog der Applikationen wird in der Resource definiert:
1
DLG_MAIN DIALOGEX 20, 40, 150, 180
2
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
3
EXSTYLE WS_EX_NOPARENTNOTIFY
4
/* 
5
usw.
6
*/
Weiß jemand woran ich drehen muss, damit das geht?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das geht anders. Du musst von den laufenden Anwendungen ein 
Fensterhandle bestimmen und an dieses die Nachricht WM_MOVEWINDOW senden 
(mit PostMessage), der Du die zu verwendendenden Koordinaten mitgibst.

von Timmo H. (masterfx)


Lesenswert?

Das heißt ich muss quasi zunächst das Handle des MainDialogs der anderen 
Anwendung bestimmen. Also quasi das Handle das mit
1
 hDialog = CreateDialog (hThisInstance, MAKEINTRESOURCE (DLG_MAIN), 0, (DLGPROC)WindowProcedure);
erzeugt wird? Also irgendwie mit FindWindow oder so, richtig?

von Timmo H. (masterfx)


Lesenswert?

Mmh, das geht irgendwie nicht. Das Handle bleibt leer:
1
HANDLE prog1;
2
prog1 = FindWindow(NULL,"TestProg");
Das zu startende Programm hat aber den Fenstertitel TestProg, von daher 
gibt es das. Eine Class kann man beim arbeiten mit Resourcen nicht 
festlegen zumindest meckert das Programm dann beim starte wenn ich eine 
CLASS eingebe (Error x57f).
Noch eine Idee?

von Zwie B. (zwieblum)


Lesenswert?

FindWindow funzt nicht, das sucht nur in einer Ebene. Du musst dich 
händisch durch den Fenterbaum wühlen.

Zuerst von deinem Fensterchen bis zum Root-Window (oops, kann sein dass 
das Desktop-irgendwas heißt). Da findest du dann mindestens 2 Stück, 
eines vom aktuellen Desktop und eines vom Anmeldemanager (auf das hast 
du normalerweise keine Zugriff). Dann sucht du vom Root-Fenster alle 
Child-Fenster durch.

Lass dir auch mal den Baum ausgeben, der ist ist sehr aufschlussreich 
:-)

Ich hab' vor Ewigkeiten mal ein passendes Programm geschrieben (als ich 
noch Windows hatte), aber ich find' den Code grad' nicht.

von Karl H. (kbuchegg)


Lesenswert?

Auch sehr aufschlussreich:

Aus dem Developer Studios, das Programm Spy++

Sehr gut um zb Window-Handles zu überprüfen bzw. die komplette 
Window-Hierarchie zu durchforsten, bzw. die Handles, die man vom 
FindWindow bekommt in einen Kontext zu stellen.

von Timmo H. (masterfx)


Lesenswert?

Bringt mir aber nichts, weil die Handles immer anders sind, da sie beim 
Aufruf vergeben werden. Aber mir fällt gerade ein, dass ich dem Prozess 
ja einfach die Koordinaten bzw. einen Index als Parameter übergeben 
kann, dass steuert das jeder Prozess für sich selbst.
Vor ein paar Jahren habe ich das aber schonmal hinbekommen, allerdings 
mit Konsolenfestern. Muss ich mal gucken, ob ich da den Quellcode noch 
wiederfinde. Ich glaube da konnte ich das direkt über die StartupInfo 
übergeben. Vielleicht weil das CMD als CW_USEDEFAULT arbeitet. Aber 
eigentlich müsste ich meine Anwendungen dazu ja auch bringen können.

von Karl H. (kbuchegg)


Lesenswert?

Timmo H. schrieb:
> Bringt mir aber nichts, weil die Handles immer anders sind, da sie beim
> Aufruf vergeben werden.

Schon klar.
Aber wenn du dein Programm debuggen willst und wissen willst, welche 
Handles du da überhaupt geliefert bekommst, ist so ein Tool äusserst 
hilfreich.

Auch ist es hilfreich bei einem Testlauf das Handle des interessierenden 
Fensters zu kennen, um dann im Code nachzusehen wo und warum das eben 
nicht geliefert wird.

von Timmo H. (masterfx)


Lesenswert?

So ich habs jetzt ganz stumpf folgendermaßen gemacht:
1
while(!findform && tries < 1000){
2
  tries++;
3
  proc1 = FindWindow(NULL,"TestProg");
4
  if(proc1 != NULL){
5
    SetWindowPos (proc1, NULL, 200, 200, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
6
    findform = 1;
7
  }
8
                   
9
}
Nicht schön, aber funzt :D

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.