onmouseover bei einem static
-
Aber irgendwie kommen nur die Nachrichten an, wenn man das Static mit dem Style SS_NOTIFY erstellt. Verstehe garnicht wie die das geschafft haben zu verhindern, dass die ganzen Notifications gesendet werden. Gibt's da ne Option beim Registrieren der Klasse oder wie hat Microsoft das gemacht?
-
Aber irgendwie kommen nur die Nachrichten an, wenn man das Static mit dem Style SS_NOTIFY erstellt.
Das ist nun wieder ganz was anderes. SS_NOTIFY bewirkt, daß das static bestimmte Nachrichten an das Parent sendet. WM_MOUSEMOVE wird von Windows versendet und kommt auch beim static an (wie bei jedem Fenster eben).
Verstehe garnicht wie die das geschafft haben zu verhindern, dass die ganzen Notifications gesendet werden. Gibt's da ne Option beim Registrieren der Klasse oder wie hat Microsoft das gemacht?
Von welchen Notifications sprichts Du?
-
@-King-
DU scheinst Schwierigkeiten mit dem Programm zu haben.So, ich hab das jetzt mal explizit ausprobiert. Meine WindowProc (des Parent) sieht jetzt so aus:
static bool bHot; static POINT pt; static RECT rect; switch(msg) { case WM_MOUSEMOVE: pt = Point(LOWORD(Msg.LParam), HIWORD(Msg.LParam)); // Das Static befindet sich an (0,0). Daher gehts auch mit ClientRect ::GetClientRect(hStat, &rect); if(PtInRect(&rect, pt)) { bHot = TRUE; SetWindowText(hStat, "HALLO_OVER"); } else if(bHot) { bHot = FALSE; SetWindowText(hStat, "HALLO"); } break; } // An die Default-Proc weitergeben
Und das funktioniert wunderbar!!! Wenn ich im Static bin, steht da HALLO_OVER, sonst nur HALLO. Auch Könige dürfen sich mal irren, -King-.
[ Dieser Beitrag wurde am 29.08.2002 um 15:31 Uhr von WebFritzi editiert. ]
-
Ok, Du hast recht. Bei mir ist das zwar anders, aber was soll's. Mein Windows scheint kaputt zu sein ...
<edit> .. und das auf drei verschiedenen Rechnern. </edit>
[ Dieser Beitrag wurde am 29.08.2002 um 15:39 Uhr von -King- editiert. ]
-
Bei mir ist es auch so:
Gesubclasstes Static-Control ohne SS_NOTIFY -> erhält keine WM_MOUSEMOVE Nachrichten
Gesubclasstes Static-Control mit SS_NOTIFY -> erhält WM_MOUSEMOVE Nachrichten
Werde es später aber nochmals testen.
-
[ Dieser Beitrag wurde am 29.08.2002 um 15:46 Uhr von -King- editiert. ]
-
@-King-
Gut..., dann gebe ich dir jetzt mal einen kompletten Code, damit du dich nicht bemühen musst einen neuen zu schreiben.Und ich wette, der funktioniert bei dir genauso gut wie bei mir. Du kannst also ganz beruhigt sein. Dein Windows ist nicht im Eimer.
#include <windows.h> //--------------------------------------------------------------------------- #define ID_STAT 1 //--------------------------------------------------------------------------- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int) { char szAppName[] = "Name" ; MSG msg; WNDCLASSEX wndclass; wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_ASTERISK); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon(NULL, IDI_ASTERISK); RegisterClassEx(&wndclass); LONG style = WS_OVERLAPPEDWINDOW|WS_SIZEBOX|WS_CAPTION|WS_SYSMENU|WS_VISIBLE; CreateWindow(szAppName, "Ich bin ein Fenster", style, CW_USEDEFAULT, CW_USEDEFAULT, 250, 200, NULL, NULL, hInstance, NULL) ; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam ; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HINSTANCE hInstance; static HWND hStat; static BOOL bHot = FALSE; static RECT rect; static POINT pt; switch(iMsg) { case WM_CREATE: hInstance = ((CREATESTRUCT*)lParam)->hInstance; hStat = CreateWindow("Static", "HALLO_OUT", WS_CHILD | WS_VISIBLE | WS_BORDER, 0, 0, 100, 25, hwnd, (HMENU)ID_STAT, hInstance, NULL); SendMessage(hStat, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0); break; case WM_MOUSEMOVE: pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); ::GetClientRect(hStat, &rect); if(PtInRect(&rect, pt)) { if(bHot==FALSE) { bHot = TRUE; SetWindowText(hStat, "HALLO_OVER"); } } else if(bHot) { bHot = FALSE; SetWindowText(hStat, "HALLO_OUT"); } break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd, iMsg, wParam, lParam); }
-
Hallöchen!
Wenn ich in meiner
BOOL CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Funktion als return Wert folgendes liefere, dann erhalte ich auch ein WM_MOUSEMOVE...
return DefWindowProc (hwnd, msg, wp, lp) ;
liefere ich hingegen
return (CallWindowProc(g_wndprocOld, hwnd, msg, wp, lp));
erhalte ich keines!
CQ.
-
Ich habe so das ungute Gefühl, wir befinden und in einem Mysterium.
-
Ja, das habe ich auch. Aber irgendwie muß es doch funktionieren! Andere können das ja auch ;-).
-
Was denn? Du hast doch jetzt sogar 2 Möglichkeiten. Entweder du nimmst meine Methode oder die Subclassing-Methode mit DefWindowProc() als Rückgabewert.
-
... das teste ich nochmal!
[ Dieser Beitrag wurde am 29.08.2002 um 16:19 Uhr von CQ editiert. ]
-
... oki, das funktioniert erstmal. Ein kleines Problem bleibt aber noch. Dieses
::GetClientRect(GetDlgItem(hw, IDC_STATIC_VERGESSEN), &rect);
liefert ja leider nicht die richtigen Koordinaten vom Static-Element. Top und Left sind immer 0! Somit stimmt also die Positionsbestimmung nicht und ich erhalte halt das Event zur falschen Zeit bzw. Mausbewegung.
-
Mit der SetWindowLongPtr-Variante kann man allerdings WM_NCHITTEST abfangen
-
@geeky
Jaja, hast ja Recht.@CQ
Das einfachste ist IMHO, die RECT-Struktur direkt nach CreateWindow() des Statics zu füllen.
-
Was hatte -King- denn im Beitrag nach mir geschrieben? Hab's nicht schnell genug mitbekommen :p
-
Hmm, ich habe das jetzt auch mal getestet und die Lösung mittels Sub-Classing
scheint mir eindeutig besser und eleganter zu sein.
Wenn ich mir anschaue wieviele WM_MOUSEMOVE gesendet werden, dann wird
mir schon fast anders beim Gedanken wie oft dort unnötig auf das RECT vom static geprüft wird...
Da ist die Lösung mittels Sub-Classing deutlich besser für die Performance.
-
Also ich habe nun nur einmal die Prüfung des RECTs vom Static drin... und zwar bei WM_INITDIALOG!
-
Original erstellt von TKool:
Hmm, ich habe das jetzt auch mal getestet und die Lösung mittels Sub-Classing
scheint mir eindeutig besser und eleganter zu sein.
Wenn ich mir anschaue wieviele WM_MOUSEMOVE gesendet werden, dann wird
mir schon fast anders beim Gedanken wie oft dort unnötig auf das RECT vom static geprüft wird...
Da ist die Lösung mittels Sub-Classing deutlich besser für die Performance.Nochmal für die Langsamen (;)): man braucht das Rect nicht immer im WM_MOUSEMOVE zu füllen. Das geht auch in WM_CREATE direkt nach CreateWindow(). Insofern ist das "Performance-Problem" gelöst.
-
Original erstellt von CQ:
Also ich habe nun nur einmal die Prüfung des RECTs vom Static drin... und zwar bei WM_INITDIALOG!Äh ja, oder so.