Statusbar SB_GETRECT Bug? (war "Merkwürdiges Doppelklick-Verhalten des Statusbars")
-
Hi folks,
ich hab hier ein merkwürdiges Verhalten des Statusbars was Doppelklick auf ein Feld betrifft.Von der Optik her (Aufteilung der Felder, Darstellung der Inhalte) sieht der Statusbar korrekt aus.
Allerdings stimmen die relevanten Rechtecke für ein Doppelklick nicht mit den dargestellten Feldern des Statusbars überein!
Zunächst hier mein stark reduzierter Code:
(Fehlerabfragen habe ich hier ebenfalls entfernt, damit die Übersichtlichkeit nicht darunter leidet. Alle hier verwendeten Funktionen liefern entweder TRUE oder Nonzero zurück, d.h. erfolgreich)int a_felder[3]; int a_felder_ausgelesen[3]; HWND hwnd_frame; //Parent-Fenster HWND hwnd_sbar; //Statusbar als Child-Fenster RECT s_rect; RECT s_rect_client; RECT s_rect_frame; RECT s_rect_sbar; //Zunächst die aktuellen Fensterkoordinaten: GetWindowRect( hwnd_frame, &s_rect_frame ); //liefert left=0, right=1000. GetWindowRect( hwnd_sbar, &s_rect_sbar ); //liefert left=4, right= 996. GetClientRect( hwnd_sbar, &s_rect_client ); //liefert left=0, right= 992. //Position des dritten Statusbar-Feldes (rechtsbündig am Rand): a_felder[2] = s_rect_client.right - GetSystemMetrics( SM_CXBORDER ) - GetSystemMetrics( SM_CXVSCROLL ); //ergibt 974. //Positionen des zweiten und ersten Statusbar-Feldes (rechtsbündig neben dem dritten Feld): a_felder[1] = a_felder[2] - 100; //ergibt 874. a_felder[0] = a_felder[1] - 100; //ergibt 774. SendMessage( hwnd_sbar, SB_SETPARTS, (WPARAM)3, (LPARAM)a_felder ); //Für Debugger: Kontrolle der Rechteck-Koordinaten des dritten Feldes: SendMessage( hwnd_sbar, SB_GETRECT, (WPARAM)2, (LPARAM)&s_rect ); //liefert: left=876, right=956. //Der Vollständigkeit halber die Kontrolle der Positionen aller drei Felder: SendMessage( hwnd_sbar, SB_GETPARTS, (WPARAM)3, (LPARAM)a_felder_ausgelesen); //liefert gleiche Werte wie unter SB_SETPARTS gesetzt.In meiner realen Applikation habe ich eigentlich 5 Statusbar-Felder.
Im geposteten Code habe ich die Zahl auf 3 reduziert.Die im Debugger ausgelesenen Werte der Koordinaten habe ich als Kommentar im Code eingetragen (Windows XP SP3).
Man sieht hier ganz deutlich daß die RECT-Werte des dritten Feldes nicht mit den Randkoordinaten von SB_SETPARTS übereinstimmen (956 vs. 974).
Was zur Folge hat, daß der Doppelklick mit der Maus in diesem Feld nicht korrekt ausgewertet werden kann.Habe ich hier irgendwas übersehen?
Könnt Ihr mir da mit meinem Problem weiterhelfen?
Martin
-
1. Würde ich sagen, dass hier der Trennbalken eingerechnet ist. Du bekommst bei dem Rect aber die größe ohne Trennbalken gesagt,
2. Kannst Du für das letzte Feld -1 als Wert benutzen, dass bedeutet, dass dieses Element bis an den Rand gehen soll.
3. Reserviert ein Statusbar auch ein Gripper Rechteck in der Ecke... das könnte auch hier etwas beeinflussen.
-
Danke für die Info.
Martin Richter schrieb:
1. Würde ich sagen, dass hier der Trennbalken eingerechnet ist. Du bekommst bei dem Rect aber die größe ohne Trennbalken gesagt,
Das ist richtig, in meiner realen Applikation habe ich das bereits berücksichtigt, unter Zuhilfename von SendMessage( SB_GETBORDERS, ... ).
Diese liefert eine Dicke (Breite) zwischen 2 und 4 Pixel (abhängig vom gerade eingestellten Theme).
Man sieht das auch an den im Debugger ermittelten Werten: SB_GETRECT liefert left=876, während ich in SB_SETPARTS den Wert 874 angegeben habe. Die Differenz stammt von der Dicke der Trennbalken.
Aber das erklärt sicher nicht die doch deutliche Abweichung von 974-956=18 Pixel.Martin Richter schrieb:
2. Kannst Du für das letzte Feld -1 als Wert benutzen, dass bedeutet, dass dieses Element bis an den Rand gehen soll.
leider negativ, daran habe ich auch schon gedacht.
Aber ich brauche dummerweise eine fixe Breite, da darin eine Bitmap eingeblendet wird (Ownerdraw).Martin Richter schrieb:
3. Reserviert ein Statusbar auch ein Gripper Rechteck in der Ecke... das könnte auch hier etwas beeinflussen.
Das habe ich bereits berücksichtigt, jedenfalls nach meiner Vorstellung. Hoffe doch, daß es so richtig ist?
Siehe Zeile 19 im Sourcecode: Subtraktion von GetSystemMetrics( SM_CXVSCROLL ).
Dieser SystemMetrics liefert einen Wert zwischen 16 und 20 Pixel (abhängig vom gerade eingestellten Theme).
Die Breite Grippers soll ja gleich der Breite des vertikalen Scrollbalkens sein.Irgendwas muß ich hier ja übersehen haben... nur komme ich hier nicht von alleine drauf
Martin
-
[Nachschlag:]
Unter Windows Vista SP2 stimmen die Werte zwischen SB_GETRECT und SB_GETPARTS exakt überein!
-> Verdacht auf einen Bug in Windows XP, welcher unter Vista beseitigt wurde?Ein anderer User hat vor einiger Zeit (Januar 2005) ein gleiches (ähnliches) Problem geschildert.
Leider hat er damals keinerlei Antwort darauf bekommen:
"StatusBar panels and SB_GETRECT" http://www.tech-archive.net/Archive/VB/microsoft.public.vb.winapi/2005-01/0219.htmlSowohl bei mir als auch bei ihm betrifft die Koordinatenunterschiede nur auf das am weitesten rechts befindliche Panel.
Martin
-
Am Wochenende habe ich mir dank des regnerischen Wetters die Muße genommen und den Sachverhalt ein wenig näher untersucht.

Nun, so langsam festigt sich meine Vermutung daß die Nachricht SB_GETRECT fehlerhaft arbeitet.

Zumindestens unter Windows XP SP3.
Denn unter Windows 98SE und unter Windows Vista SP2 funktioniert SB_GETRECT wie erwartet.Hier der zweite Beweis in Kurzform:
Man nehme eine Statusbar, mit einigen Feldern.
Das letzte Feld ist rechtsbündig angelegt, um die Breite des Sizegrips abgezogen.
Dieses letzte Feld hat gleichzeitig den SBT_OWNERDRAW Stil.Bei der Verarbeitung von WM_DRAWITEM vergleiche ich die RECT-Informationen zwischen SB_GETRECT und (LPDRAWITEMSTRUCT)->rcItem:
Die von der Nachricht WM_DRAWITEM bereitgestellte Strukturinformationen (LPDRAWITEMSTRUCT)->rcItem ist korrekt.
Dagegen ist die mit SendMessage( SB_GETRECT, ...) zurückgegebenen RECT-Werte nicht identisch mit der tatsächlichen Größe!Hier die ermittelten Werte (mit Werten im ersten Post vergleichbar):
Frame-Fenster: left:0, right:1000 Statusbar: left:4, right:996 (LPDRAWITEMSTRUCT)->rcItem: left:917, right:973 SB_GETRECT: left:916, [b]right:956[/b] (FEHLER!, Windows XP SP3) SB_GETRECT: left:916, right:974 (OK, Windows Vista SP2 und Windows 98SE)Offensichtlich subtrahiert SB_GETRECT beim letzten Feld grundsätzlich die Breite des Sizegrips (welche auch 18 Pixel breit ist).
Was zur Folge führt daß Mausklicks (egal ob linke oder rechte Maustaste, ob Einfach- oder Doppelklick) nicht mehr vollständig, sondern nur noch in diesem durch SB_GETRECT verkleinerten Bereich erkannt wird.
Wie ist Eure Meinung dazu?
Ist das tatsächlich ein Windows-Bug?Martin
-
Mmacher schrieb:
Wie ist Eure Meinung dazu?
Ist das tatsächlich ein Windows-Bug?Da sich die Versionen im Verhalten unterscheiden, tippe ich mal auf einen Bug.
Du kannst versuchen einen Support-Request bei MS aufzumachen. Aber ich garantiere Dir zu 100%, dass der im Sande verläuft... Sofern das Problem in Vista und Windows 7 nicht mehr auftritt geht es MS an der Hutschnur vorbei.Vergiss nicht das auch XP schon längst "im Sterben liegt":
Windows XP SP3 ist seit April 2010 aus dem Mainstream-Support gegangen:
http://support.microsoft.com/lifecycle/?LN=en-gb&x=16&y=12&C2=1173
-
Danke für die Info.
Ja, das hatte ich auch schon befürchtet.
Ist ja auch einleuchtend, daß für ein langsam sterbendes OS solche kosmetische Korrekturen nicht mehr notwendig sind.Nun, hab mich einfach damit abgeholfen, indem ich das letzte Feld ein wenig vergrößrt habe.
So fällt der "tote Randbereich" unter Windows XP nicht so arg auf
Damit kann ich leben.Martin