Eigene Sizebox
-
Ein mit SBS_SIZEBOX angelegtes Child-Window (SCROLLBAR-Klasse) liefert bei Mausverschiebung automatisch WM_SIZE-Nachrichten an das Parent.
Wie kann man diese Nachrichten von denen unterscheiden, die durch MoveWindow-Aufrufe des Parents provoziert werden?Im Moment sehe ich nur die Möglichkeit, dass ich die Ecke mit einem eigenen Fenster realisiere.
Anmerkung:
Mit SBS_SIZEGRIP erreiche ich eine Unterdrückung der WM_SIZE-Nachrichten, die Ecke wird aber trotzdem bewegt. Außerdem möchte ich die Nachrichten erhalten, aber anders verwerten, sodass SBS_SIZEGRIP ohnehin nicht geeignet wäre.
-
was machst du genau?
-
Bei Benutzer-Aktionen wird WM_MOVING/WM_SIZING gesendet,
WM_SIZE ist immer gleichund letzten Ednesnur die Vollzugsmeldung.
-
@unpräzise:
Ich habe das Problem mit Absicht so eng wie möglich umrissen.
Die Fensterkonstellation der CAD-Anwendung ist sehr komplex, ähnlich wie in Visual Studio 2010:In einem Frame-Window, das über seitliche Ablageflächen beweglich begrenzt ist, befinden sich mehr oder weniger horizontal oder vertikal angeordnete Registerkartengruppen-Fenster, die wiederum beliebig viele View-Fenster besitzen. In dieser gedockten Form darf ein View-Fenster nicht über dessen Sizebox bewegt werden können, sondern nur durch die Bewegungsmanöver der übergeordneten Fenster via MoveWindow. Aber in beiden Fällen trifft eine WM_SIZE-Nachricht ein, die so nicht unterschieden werden kann.
Außerdem kann ein View-Fenster auch aus dem Verband der Registerkartengruppen herausgezogen werden (ungedockt). Es wird dann als Child eines zusätzlichen Popup-Fensters umgehängt. Das Popup-Fenster besitzt dann ein Registerkartengruppen-Fenster als Owner! Auch hier darf das Sizing nur durch die Anwenderinteraktion mit dem Popup-Fenster geschehen, das dann via MoveWindow das View-Fenster steuert.
Ich würde die WM_SIZE-Nachrichten in der View-Prozedur nur dann nutzen wollen, wenn das View-Fenster im Popup-Fenster hängt und das Popup-Fenster in seiner Größe vom Anwender verändert wird. Also nicht, wenn die Sizebox angefasst wird.
Ihr seht, meine anfängliche Beschreibung war schon sehr exakt, und die weitere Beschreibung des Drumherum ist eigentlich nur verwirrend.
@Martin:
Das waren meine ersten Überlegungen. Leider kann im WM_SIZING oder WM_WINDOWPOSCHANGING die Herkunft der Nachricht genauso wenig ermittelt werden: Von MoveWindow oder von der Anwenderbewegung der Sizebox?
Außerdem kann hier nur überwacht und manipuliert werden, das weitere Processing zum WM_SIZE aber nicht unterbrochen werden!Ich denke, die Sizebox ist nur für die einfachste Standardanwendung zu gebrauchen, die dann die Bewegungsnachrichten an das Parent sendet und fertig. Man wird die kleine Ecke wohl selber machen müssen
-
Ich verstehe Dein Problem, aber dazu ist doch genau WM_MOVING und WM_SIZING da.
Dein Fenster wird gefragt: Darf sich das?
Dein Fenster denkt nach und meint: Nö... oder Ja...
WM_SIZE kommt an...Wieso musst Du in WM_SIZE wissen wer was will?
WM_SIZE ist die Meldung des Vollzugs! Und für nicts anderes ist es nutzbar. D.h. Du passt z.B. Dein Layout Deiner Clients an.
-
Die Sizebox-Fläche muss ein Child vom View-Fenster sein, damit es darin sichtbar ist. Das bedeutet, dass eine Bewegung der Sizebox durch den Anwender Nachrichten wie WM_SIZE auch diesem View-Fenster zusendet (von Microsoft in dieser Fensterklasse festgelegt und nicht ohne weiteres abbiegbar). Leider wird dadurch das View-Fenster innerhalb des übergeordneten Popup-Fensters z.B. verkleinert und ist nicht mehr passgenau! (Normalerweise hat man kein passgenaues darumliegendes Fenster. Dann wäre alles klar.)
Eine Größenanpassung erfolgt immer über die Ränder des Popup-Fensters via dessen Fensterprozedur mit WM_SIZE und MoveWindow(Child). Dadurch ist sichergestellt, dass das Child (das View-Fenster) die richtige Passung behält. Die Sizebox funkt aber dazwischen!Ideal wäre es, wenn ich die Sizebox zwar als Child des View-Fensters implementiere, aber dafür sorgen könnte, dass diese WM_SIZE-Nachrichten nicht an das Parent, sondern an das übergeordnete Popup-Fenster gesendet werden. Ich wäre schon froh, wenn diese Sizebox überhaupt keine Nachrichten senden würde und nur als grafische Einheit fungieren würde.
P.S.: Ich bin jetzt aber schon bald fertig mit der Realisierung einer eigenen Fensterecke. Vielen Dank fürs Mitdenken.
-
1. WM_SIZE hat ncihts damit zu tun, und die Sizebox sendet nicht WM_SIZE!
2. MoveWindow/SetWindowPos löst ein WM_SIZE aus.
3. Bst Du sicher, das die Sizebox kein WM_SIZING auslöst und an das Parent sendet?
Alternativ: Wenn Du nicht möchtest dass die Sizebox "eingenmächtig handelt", dann mach ein Subclass auf die Sizebox und analysiere dort was mit Drag&Drop passiert....
-
Wenn eine mit SBS_SIZEBOX erstellte Sizebox mit der Maus bewegt wird, sendet sie definitiv u.a. WM_SIZING und WM_SIZE ans Parent. Leider sind hier eben keine Hinweise auf den Ursprung mit dabei. Wäre schön, wenn bei WM_SIZE in lParam statt der unnötigen Größe, die ja jederzeit mit GetClientRect ermittelt werden kann, weitergehende Infos vorhanden wären.
Wenn die Sizebox mit SBS_SIZEGRIP erstellt wird, sendet sie keine WM_SIZE-Nachrichten, verschiebt die Sizebox aber und ich weiß nichts davon
Eine weitere Manipulation der SCROLLBAR-Klasse lohnt sich nicht, weil ich dann andere einfachere Möglichkeiten habe.
Vielen Dank für die Unterstützung, Martin.
-
Kleiner Nachtrag:
In WM_SIZING kann ich in der Tat, wie du oben gesagt hast, mit
if(wParam==WMSZ_BOTTOMRIGHT)
feststellen, dass die Sizebox und nicht MoveWindow der Urheber ist
Allerdings gelingt es mir nicht, die Sendung von WM_SIZE zu verhindern. Egal ob ich mit TRUE, FALSE oder DefWindowProc zurückgebe. Eine Merkvariable, die diese Feststellung nach WM_SIZE hinüberrettet, ist mir da zu unsicher.
-
Dann setze doch einfach wieder die alten Werte in das RECT ein und es passiert nichts und die Änderung wird verhindert...