www.mikrocontroller.net

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


Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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:
  STARTUPINFO     StartupInfo;
  PROCESS_INFORMATION ProcInfo;
  HWND window[10];
  
  memset(&ProcInfo, 0, sizeof(ProcInfo)); 
  memset(&StartupInfo, 0 , sizeof(StartupInfo));
  
  StartupInfo.cb = sizeof(StartupInfo); // Set structure size 
  StartupInfo.dwX = 100 ; 
  StartupInfo.dwY = 300 ; 
  StartupInfo.wShowWindow = SW_SHOW; 
  StartupInfo.dwFlags = STARTF_USEPOSITION | STARTF_USESHOWWINDOW | STARTF_USESIZE ; 
  
                
  window[0] = CreateProcess(NULL, "anwendung1.exe", NULL, NULL, NULL, 
                          NULL, NULL, NULL, &StartupInfo, &ProcInfo);
Der Maindialog der Applikationen wird in der Resource definiert:
DLG_MAIN DIALOGEX 20, 40, 150, 180
STYLE DS_3DLOOK | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_NOPARENTNOTIFY
/* 
usw.
*/
Weiß jemand woran ich drehen muss, damit das geht?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Timmo H. (masterfx)
Datum:

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

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mmh, das geht irgendwie nicht. Das Handle bleibt leer:
HANDLE prog1;
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?

Autor: Zwie Blum (zwieblum)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Timmo H. (masterfx)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.