MDI ohne MFC
-
tagchen,
hab mir jetzt mal einfach, weil ich wissen wollte, wie MDI ohne MFC aussieht,
die MSDN hergenommen und einen kleinen Editor mit der Windows-API geschrieben.jetzt meine Frage:
wie bekomme ich es hin, dass immer wenigstens ein MDI-Child offen ist?
also dass der Nutzer nie alle schließen kann?thx schonmal für die Antworten xD
MfG DrakoXP
-
Schlagt mich nicht, wenn ich was falsches schreibe, aber..:
Jedes MDI-Fenster bekommt doch auch ein Handle. Beim Schließen eines Dokumentfensters muß sich also anhand der Handels überprüfen lassen, ob noch andere Doku-Fenster geöffnet sind (da gibts eine Funktion "GetNextWindow"()). Falls nicht, wird das Schließen des letzten Fensters verhindert, indem man WM_CLOSE abfängt.
-
Du solltest selber eine Verwaltung aufbauen, die sich alle entsprechenden MDI-Child Windows merkt.
Wir Du richtig gesehen hast kannst Du alle Child-Windows des MDI-Frames auch mit GetNextWindow enummerieren. Aber Achtung. Es werden mehr Fnster (auch unsichtbare) erzeugt für die minimierte Darstellung im MDI-Frame.
Aber alle sichtbaren Fenster im MDI-Frame entsprechen auch einem Deiner Fenster, die Du mit WM_MDICREATE erzeugt hast.
-
gut, dankse erstmal, das hilft mir schonmal weiter.
jetzt noch ne Frage:
gibt es eine Notification, die meinem Frame-Window sagt, dass das Aktuelle MDI-Child gewechselt wurde?
wie gesagt, es handelt sich um einen Editor und ich würde gerne als Menüpunkt haben: "... speichern",
also wenn die Datei schonmal gespeichert wurde natürlich.
dazu müsste ich den Eintrag natürlich immer aktualisieren, wenn das Child gewechselt wird.selbiges gilt für das schließen von Childs -> wenn kein Child mehr da ist,
sollen entsprechende Menüpunkte ausgegraut werden.gibt es dafür eine Notification dafür?
und wie fange ich die ab?MfG DrakoXP
-
Du bekommst doch WM_SETFOCUS gesendet an Dein Client. Eine andere spezielle Nachricht gibt es nicht. Du kannst aber auch mit WM_MDIGETACTIVE aufrufen um jederzeit, das aktive Fenster zu ermitteln.
-
Die Message heißt WM_MDIACTIVATE. Allerdings bekommt das Hauptfenster sie nicht zu sehen; sie sollte also in der MDIChildProc verarbeitet werden.
Die Nachricht wird sowohl vom aktivierten als auch vom de-aktivierten MDI-Child-Fenster empfangen. In beiden Fällen steht in lParam der Handle zum aktivierten, in wParam zum de-aktivierten Fenster. In der MDIChildProc kann man also mit 'if(lParam==hWnd)' überprüfen, ob man sich gerade im aktivierten oder im de-aktivierten Fenster "befindet".
Ich würde die Programmlogik so aufbauen, dass die Reihenfolge, in der die beiden Childfenster WM_MDIACTIVATE empfangen, keine Rolle spielt. Z.B. indem man alle Aktionen dann durchführt, wenn gerade das aktivierte Fenster die Nachricht verarbeitet (also wenn lParam==hWnd). Wie gesagt, mit wParam hat man ja auch dann Zugriff auf das soeben de-aktivierte Fenster. Das sollte problemlos sein, wenn man Aktionen beim Schließen eines Child-Fensters in WM_CLOSE oder WM_DESTROY statt in WM_MDIACTIVATE durchführt.
Wie Martin R. schrieb, macht es Sinn, eine eigene Verwaltung aufzubauen.
Man könnte z.B. eine Struktur/Klasse 'MDI_KID' definieren, eine Instanz davon für jedes neu erstellte MDI-Child allozieren, und per SetWindowLongPtr() mit dem Childfenster assoziieren. In diese Stuktur kann man alle Daten packen, die man für das jeweilige Child (einschließlich dessen HWND, siehe unten) braucht.
Das macht sich wahrscheinlich spätestens dann bezahlt, wenn man komplexere Features für die MDI-Children implementieren möchte, z.B. eine Tab-Leiste (dann könnte man jeden Tab mit einem Pointer auf die jeweilige MDI_KID-Struktur versehen, und so den Tab mit einem Childfenster verknüpfen, einschließlich dessen HWND), oder eine Seitenleiste, die Daten des aktiven Fensters anzeigen soll...
Wenn man die 'MDI_KID'-Instanzen zu einer Liste verkettet, kann man schön durch sämtliche vorhandenen MDI-Children navigieren. Wenn sowohl der Rückwärts- als auch der Vorwärts-Listenpointer des gerade aktiven MDI_KIDs NULL sind, weiß man, dass nur ein MDIChild existiert, usw.
Walter Z