2016-05-24 9 views
1

Ich habe ein Fenster von CWnd abgeleitet, in dem ich einige OwnerDrawn Buttons erstellen. Die Buttons sind von CButton abgeleitet.Wie ändere ich BackgroundColor OnMouseHover C++ MFC

Jetzt möchte ich zu BackgroundColor meiner Schaltflächen wechseln, wenn der Benutzer darüber schwebt.

Deshalb implementiert ich bereits, dass die OnMouseHover() und die OnMouseLeave() Nachrichten gesendet zu werden:

BEGIN_MESSAGE_MAP(CFooterButton, CButton) 
    ON_WM_MOUSEHOVER() 
    ON_WM_MOUSEMOVE() 
    ON_WM_MOUSELEAVE() 
END_MESSAGE_MAP() 

void CFooterButton::OnMouseMove(UINT nFlags, CPoint point) 
{ 

    //start tracking of Hover and Leave Event 
    TRACKMOUSEEVENT tme; 
    tme.cbSize = sizeof(TRACKMOUSEEVENT); 
    tme.dwFlags = TME_HOVER | TME_LEAVE; 
    tme.hwndTrack = m_hWnd; 
    tme.dwHoverTime = HOVER_DEFAULT; 
    TrackMouseEvent(&tme); 

    CButton::OnMouseMove(nFlags, point); 
} 


void CFooterButton::OnMouseHover(UINT nFlags, CPoint point) 
{ 


    HDC hdc = *GetWindowDC(); 

    SetBkColor(hdc,RGB(54, 125, 184)); 
    CButton::OnMouseHover(nFlags, point); 
} 

Im Debugger und Spy ich kann, dass der Code zu sehen ist immer genannt, aber nichts passiert. Da ich relativ neu in MFC/C++ bin, nehme ich an, dass ich die DC nicht richtig verwende. Kann mir jemand erklären, warum es nicht funktioniert und wie ich es beheben kann?

+1

Das Ändern des Hintergrunds in 'OnMouseHover' wird nicht viel bewirken, da die Hintergrundfarbe beim Malen des Hintergrunds oder des Fensters zurückgesetzt wird. Sie könnten 'OnEraseBkgn' überschreiben und die Farbe dort einstellen. –

+1

@KarstenKoop, also muss ich nur Invalidate() aufrufen, wenn OnMouseHover aufgerufen wird und dann Handle OnEraseBkgn? –

+0

Ich denke, ein besserer Ansatz wäre, den Button als Besitzer zu definieren und die Hintergrundfarbe mit dem DC zu zeichnen. – rrirower

Antwort

1

Für alle anderen, die meine Lösung kämpft:

  • ein m_bHover Mitglied Bool erstellen = false in Ihrer Klasse Button
  • implementieren OnMouseMove wie in der Frage zur Verfügung gestellt Hover zu verfolgen und
  • Lassen Sie implementieren OnMouseHover

    void CFooterButton::OnMouseHover(UINT nFlags, CPoint point) 
    { 
        m_bHover = true; 
        Invalidate(); 
        CButton::OnMouseHover(nFlags, point); 
    } 
    
  • OnMouseLeave implementieren

    void CFooterButton::OnMouseLeave() 
    { 
        m_bHover = false; 
        Invalidate(); 
        CButton::OnMouseHover(nFlags, point); 
    } 
    
  • Griff Hover-Effekt in yourButtonClass :: DrawItem (Invalidate() stellt sicher, dass es genannt werde)

    void CFooterButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    { 
        //default colors 
        COLORREF textColor = RGB(202, 228, 251), backgroundColor = RGB(84, 150, 205); 
    
        switch (lpDrawItemStruct->itemAction) 
        { 
        case ODA_DRAWENTIRE: 
         //check if the user is just hovering over the button 
         if (m_isHovered){ 
          backgroundColor = RGB(54, 125, 184); 
          textColor = RGB(255, 255, 255); 
         } 
         else{ 
    
          backgroundColor = RGB(84, 150, 205); 
          textColor = RGB(202, 228, 251); 
         } 
         break; 
    
        case ODA_FOCUS: 
         //Button was clicked incase you want to change sth OnClick 
         break; 
        } 
    
        CDC dc; 
        dc.Attach(lpDrawItemStruct->hDC); 
        dc.FillSolidRect(rect, backgroundColor); 
        dc.SetTextColor(textColor); 
    
        //your drawing code... 
        //DrawFrameControl()etc.. 
        dc.Detach(); 
    } 
    

Hinweis: Die lp-Struktur eine andere itemAction hat -> ODA_SELECT Siehe MSDN https://msdn.microsoft.com/de-de/library/windows/desktop/bb775802(v=vs.85).aspx

+1

'itemAction' ist eine Kombination verschiedener Flags. Sie müssen 'if (lpDrawItemStruct-> itemAction & ODA_DRAWENTIRE)' überprüfen (für eine Schaltfläche ist dies immer der Fall). Versuchen Sie auch, zu 'tme.dwHoverTime = 10;' für eine bessere Antwort zu wechseln. Ändern Sie in 'OnMouseHover' in' if (! Hover) {hover = true; Invalidate();} ', um aufeinanderfolgende Invalidate-Aufrufe zu reduzieren ... –

Verwandte Themen