Manuelles resizing eines controls
-
Hiho,
Folgendes Problem:
Ich hab 2 TreeView und 2 ListView im Dialogdesigner mit WS_THICKFRAME ausgestattet (normlerweise nicht vorgesehen) so das sie "resizebale" sind. Nun kann ich die die einzelnen Controls mit der Maus selbst resizen, aber ich kann die WM_SIZE bzw WM_SIZING Nachrichten nicht abfangen über WM_COMMAND oder WM_NOTIFY. Welche möglichkeiten hab ich nun dies abzufangen und die anderen Controls damit mit zu resizen?
Geht das nur über Subclassing (wenn ja wie und wo das Subclassing einbinden) oder gibt es auch andere Möglichkeiten?Vielen Dank schonmal =))
-
WM_SIZE kommt nicht ueber WM_COMMAND oder WM_NOTIFY, es laeuft als eigene message
schau mal mit spy++ nach ob die message ueberhaupt beim parent ankommt, wenn nicht musst du subclassen dann gibts keine altenative
-
WM_SIZE fange ich aber schon für das Window ab, also so das beim Fensterresize die Controls angeordnet werden (vergrößert/verkleinert). Die Controls sollen aber unabhängig resized werdem vom Fenster. Und WM_SIZE enthält leider keine Fensterhandles, oder kann ich die irgendwie abfangen?
Zum Subclassing: Wo muß ich das genau einbinden, sprich welche WM_ und muß ich jedes Control einzeln subclassen?
-
VirtualDreams schrieb:
... welche WM_ und muß ich jedes Control einzeln subclassen?
WM_SIZE - und ja, fuer jedes control einzeln, kannst aber ein und die selbe message mehrfach verwenden {o;
-
Hab es grad mal in der WM_SIZE probiert, wenn ich das Fenster resize kommt die Message an, aber wenn ich die Controls resize nicht.
Es muß doch auch irgendeine Nachricht gesendet werden wenn Controls ihre größe ändern, oder? Die müßten doch auch an das Fenster das die Controls enthält gesendet werden.
-
Die Nachricht kommt natürlich nicht im Parent an, sondern im Child selbst das resized wird.
Da Du vermutlich die Controls in Abhängigkeiten bringen willst würde ich Dir die Verwendung von Splittern eher anraten!
-
An Splitter hatte ich auch schon gedacht, nur da mein Projekt vollkommen dynamisch ist fällt der Einsatz derer aus, da ja bei Splittern wieder static-variablen zum Einsatz kommen.
Hab auch mal die Msg abgefangen die beim resizen so kommen (also bloß die msg vom Fenster geloggt), da kommen WM_PAINT und noch ein WM an mit WM_CTLCOLORirgendwas, vlt hilft mir ja das weiter.
Wie kann ich denn die Controls ohne WM_ subclassen? Müßte ich das schon vor der switch(msg) machen? Könnte aber vlt unperformant werden, oder?
-
deine einzigste moeglichkeit ist die controls einzeln zu subclassen und das WM_SIZE an der haut message weiter zu leiten - so hab cih das bei meinen mit WM_VSCROLL auch gemacht
-
Mr Evil schrieb:
... haut message ...
? ^^
also soll ich noch vor der switchabfrage sozusagen das/die controls subclassen?
-
Also ich hab jetzt das Control gesubclasst. In dieser fange ich das Event WM_NCHITTEST ab und prüfe auf HTBORDER ob ich auf dem Controlrand bin und ändere daraufhin den Mauszeiger auf das Sizingsymbol. Soweit so gut. Das Problem ist jetzt aber wenn die Maus nicht bewegt wird so ändert sich der MAuszeiger wieder auf den Pfeil zurück, erst wenn ich wieder bewege wird es zum Sizing sysmbol. Wie kann ich das anstellen das der Mauszeiger solange ein Sizesymbol bleibt wie die Maus auf dem Border des Controls ist?
Hier mal ein bissel Code dazu:INT_PTR CALLBACK ControlSubclass(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_NCHITTEST: { if(DefWindowProc(hwnd, msg, wParam, lParam) == HTBORDER) { SetCursor(LoadCursor(0, IDC_SIZEALL)); return HTBORDER; } break; } } return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); }Und wie kann ich jetzt wenn die Maus über dem Border ist auf Mausklick die größe verändern, bzw wie bekomme ich raus auf welchem Border ich bin (links, recht, oben oder unten?
Über Hilfe wäre ich sehr Dankbar! =))
-
Der Cursor wird nur in WM_SETCURSOR verändert! Nicht in WM_NCHITEST!
-
und ausserdem, warum faengst du nicht in der subclass WM_SIZE ab, dann bekommst du doch die entsprechenden parameter
INT_PTR CALLBACK ControlSubclass(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_SIZE: { // resize kram; break; } } return CallWindowProc(oldWndProc, hwnd, msg, wParam, lParam); }
-
Also ich hab jetzt alles in der Subclass abgefangen, funktioniert super, sende in der WM_SIZE der Subclass an das Parent eine Msg das sich die anderen Controls auch resizen. Alles wunderbar. =))
Nur ein kleines Problem ist noch im XP-Layout: Es bleiben kleine Grafische fragmente an der Rändern der Controls beim resizen stehen die ich einfach nich wegbekomme. Im Klassischen Layout besteht das problem nicht, jedoch sind die Listviews manchmal nicht aktualisiert, haben also den (grauen)Parenthintergrund.
Das wäre das Letzte meiner Probleme diesbezüglich ^^
PS: Hab die Controls jetzt doch noch mit WS_THICKFRAME und WS_EX_STATICEDGE ausgestattet, so sieht es unter beiden Layouts gut aus und ist resizeable.