onmouseover bei einem static



  • WNDPROC g_wndprocOld;
    
    BOOL CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
    TRACKMOUSEEVENT tme;
    static BOOL bHot = FALSE;
    
        switch (msg) {
            case WM_MOUSEMOVE:
                 if(!bHot)
                 {
                     bHot = TRUE;
    
                     tme.cbSize      = sizeof(tme);
                     tme.dwFlags     = TME_LEAVE;
                     tme.hwndTrack   = hwnd;
                     tme.dwHoverTime = HOVER_DEFAULT;
                     _TrackMouseEvent(&tme);
                     SetFontOfStatic(hwnd, IDC_STATIC_VERGESSEN);
                     InvalidateRect(hWnd, NULL, TRUE);
                 }
                 break;
            case WM_MOUSELEAVE:
                 bHot = FALSE;
                 InvalidateRect(hWnd, NULL, TRUE);
                 break;
        }
      return(CallWindowProc(g_wndprocOld, hwnd, msg, wp, lp));
    }
    

    Setzen dann so:

    g_wndprocOld = (WNDPROC)SetWindowLong(GetDlgItem(hw, IDC_STATIC_VERGESSEN), GWL_WNDPROC, (LONG)StaticWndProc);
    

    Ich habe aber nichts getestet!



  • Hi!

    Vielen Dank!!! Leider klappt es so nicht. D.h. er springt in diese CASE Anweisungen gar nicht rein. Komisch. In meinem Code hat er es ja wenigstens noch gemacht...

    THX,

    CQ.



  • WM_MOUSEMOVE wird auch an das Parent des Statics gesendet, wenn die Maus über dem Static bewegt wird. Dann könnte man doch testen, ob sich der Cursor im WindowRect des Statics befindet per PtInRect(). Man könnte sich das SubClassing also sparen.



  • Genaugenommen habe ich über Spy++ gerade festgestellt, dass ein Static überhaupt kein WM_MOUSEMOVE empfängt. Aber vielleicht ist es ja anders, wenn es gesubclassed ist? 😕



  • WM_MOUSEMOVE wird auch an das Parent des Statics gesendet,

    Das halte ich für ein Gerücht.

    er springt in diese CASE Anweisungen gar nicht rein

    Wenn Du bei WM_MOUSEMOVE nicht ankommst, bewegst Du entweder nicht die Maus über das static oder Du hast bei SetWindowLong das flasche Fenster angegeben.



  • Genaugenommen habe ich über Spy++ gerade festgestellt, dass ein Static überhaupt kein WM_MOUSEMOVE empfängt.

    Unsinn.



  • Wenn ich mich richtig erinnere haben wir dazu ein Beispiel auf unserer HP (Link untenstehend).
    Allerdings bezieht sich das auf das Einbauen eines Hyperlinks in ein Fenster.
    Ist im Prinzip aber gleich. Dort ändert der Mauszeiger sich beim Überfahren..



  • Original erstellt von -King-:
    [quote]Genaugenommen habe ich über Spy++ gerade festgestellt, dass ein Static überhaupt kein WM_MOUSEMOVE empfängt.

    **
    Unsinn.**[/QUOTE]
    Na, dann mach das doch mal selber, verdammt noch mal! Jetzt bin ich wirklich ein bisschen böse. Ich habe ein Fenster mit einem WS_CHILD | WS_VISIBLE-Static darauf. OHNE SubClassing. UND DAS EMPFÄNGT LAUT SPY++ KEIN WM_MOUSEMOVE!!! 😡



  • Original erstellt von -King-:
    [quote]WM_MOUSEMOVE wird auch an das Parent des Statics gesendet,

    **Das halte ich für ein Gerücht.
    **[/QUOTE]
    Ich kann nur wiederholen: probier's selber aus! Spy++ sagt mir bestimmt nicht nur aus Spaß, dass WM_MOUSEMOVE an das Parent geschickt wird.



  • Mein Spy zeigt alles an, so wie es sich gehört. So schwierig ist das Programm doch auch gar nicht zu bedienen ...



  • 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 ;-).


Anmelden zum Antworten