Forum: PC-Programmierung [C,WinAPI] Fenster eines anderen (eigenen) Programms verschieben
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?
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.
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?
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?
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.
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.
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.
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.
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.
|