Ownerdrawn Controls



  • Hallöchen,

    heute will ich mich mal wieder den Ownerdrawn Controls widmen. Beim Testen bin ich auf einige Dinge gestoßen die mir nicht ganz klar sind, bzw. wie sich bestimme Dinge bewerkstelligen lassen.

    Ich habe als Beispiel eine eigene Button Klasse, welche von CButton abgeleitet ist, erstellt. Dieser Button hat je nach Zustand andere Farben.
    Nun wollte ich dem Button "Tooltips" hinzufügen.
    Damit meine ich: Wenn ich mich mit dem Mauszeiger über dem Button befinde, will ich einige Pixel oberhalb des Buttons ein Rechteck zeichnen und einen Text ausgeben.

    Ich hatte mir das so gedacht, dass ich WM_MOUSEMOVE abfange und schaue, ob die Maus sich innerhalb des Buttons befindet:

    void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
    {
    	m_ptMouse = point;
    
    	if (PtInRect(&m_rtButton,m_ptMouse))
    	    m_bDrawToolTip = TRUE;	
    	else 
    	    m_bDrawToolTip = FALSE;
    
    	GetTopLevelFrame()->InvalidateRect(&m_rtTooltip,TRUE); // get top level frame
    
    	CButton::OnMouseMove(nFlags, point);
    }
    

    Nun will ich eigentlich in der WM_PAINT-Behandlung das Rechteck zeichnen.
    Dafür benötige ich doch das Device Context, welches mit dem obersten Fenster verbunden ist, oder? Schließlich will ich ja ausserhalb des Buttons zeichnen.

    Paint beinhaltet bisher nur das Füllen des Rechtecks:

    void CMyButton::OnPaint()
    {
    	CPaintDC dc(this); // device context for painting
    	if (m_bDrawToolTip)
    	{
    	    COLORREF clText  = RGB(255,0,0);
    	    COLORREF clBrush = RGB(0,255,0);
    
    	    dc.FillSolidRect(&m_rtTooltip, clBrush);
    	}
    }
    

    Nun habe ich zwei Probleme:
    Beim Starten der Anwendung bleibt mein Fenster grau. Erst wenn ich an die Stelle des Buttons drücke, dann kommt der Button. (Dieses Phänomen habe ich seit Hinzufügen der Paint-Funktion).
    Zweitens: Das Rechteck des Tooltips wird nicht gezeichnet.

    WM_DRAWITEM sieht so aus:

    void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
        CDC dc;
        CString strButtonText;
    
        dc.Attach(lpDrawItemStruct->hDC);	//Get device context object
        m_rtButton	= lpDrawItemStruct->rcItem;//Get button rect
    
        ClientToScreen(&m_rtButton);
        // set tooltip rect    
        m_rtTooltip.left	= m_rtButton.left;
        m_rtTooltip.top	= m_rtButton.top-40;
        m_rtTooltip.right	= m_rtButton.right;
        m_rtTooltip.bottom	= m_rtButton.top-10;
    
        ScreenToClient(&m_rtButton);
    
        UINT state	= lpDrawItemStruct->itemState;	//Get state of the button
    
        COLORREF clText  = RGB(0,150,0);
        COLORREF clBrush;
    
        UINT uiFlags = BF_RECT;
        UINT uiEdge  = 0;
    
        if (state & ODS_SELECTED)
        {
            clBrush = RGB(255, 0, 0);	//Fill button with yellow color
    	clText  = RGB(255,255, 120);
    	uiEdge  = EDGE_SUNKEN;  
        }
        else
        {
    	clBrush = RGB(255, 255, 120);
    	clText  = RGB(0,120, 0);	
    	uiEdge  = EDGE_RAISED;  
        }
    
        dc.FillSolidRect(m_rtButton, clBrush); //Fill button with yellow color
        dc.DrawEdge(m_rtButton,uiEdge,BF_RECT);// Draw a sunken face
    
        if ( (state & ODS_FOCUS ) )		// If the button is focused
        {		
    	// Draw a focus rect which indicates the user
    	// that the button is focused
    	int iOffset = 3;
    	m_rtButton.top	    += iOffset;
    	m_rtButton.left	    += iOffset;
    	m_rtButton.right    -= iOffset;
    	m_rtButton.bottom   -= iOffset;
    	dc.DrawFocusRect(m_rtButton);
        }
    
        // set text color, draw text
        dc.SetTextColor(clText);	// Set the color of the caption to be green	
        GetWindowText(strButtonText);// Get the caption which have been set		
                 dc.DrawText(strButtonText,m_rtButton,DT_CENTER|DT_VCENTER|DT_SINGLELINE);	    // Draw out the caption
    
        dc.Detach();
    }
    


  • Paul_C. schrieb:

    Paint beinhaltet bisher nur das Füllen des Rechtecks:

    void CMyButton::OnPaint()
    {
    	CPaintDC dc(this); // device context for painting
    	if (m_bDrawToolTip)
    	{
    	    COLORREF clText  = RGB(255,0,0);
    	    COLORREF clBrush = RGB(0,255,0);
    
    	    dc.FillSolidRect(&m_rtTooltip, clBrush);
    	}
    }
    

    Nun habe ich zwei Probleme:
    Beim Starten der Anwendung bleibt mein Fenster grau. Erst wenn ich an die Stelle des Buttons drücke, dann kommt der Button. (Dieses Phänomen habe ich seit Hinzufügen der Paint-Funktion).

    Deine Funktion ersetzt die "normale" CButton::OnPaint(), in der der eigentliche Button gezeichnet wird - also müsstest du die Methode der Basisklasse aus deinem Code heraus aufrufen.



  • Stehe auf dem Schlauch und weiß nicht was ich dann machen soll. Wenn ich einfach ein CButton::OnPaint(); hinzufüge, passiert auch nichts.



  • Lass das mit dem Zeichnen in der OnPaint weg, und nutze für dein ToolTip entweder CToolTip oder eine von CWnd abgeleitete Klasse. Dann muß es gehen.

    Dazu schau Dir noch OnMouseLeave(WM_MouseLeave) an.

    Hoffe habe nicht all zuviel Verraten 😕

    Gruß Matthias



  • Naja, ich will ja gerade selber ein Tooltip-Fenseter erstellen.
    WM_MOUSELEAVE gibt es bei mir nicht?!
    Ich bin nun auch so weit, dass das Rechteck richtig gezeichnet wird. Jedoch das Verschwinden bekomme ich noch nicht hin. 🙂
    Habe da nun ne Idee, dass ich mit GetCursorPos() die aktuelle Position des Mauszeigers überprüfe, jedoch weiß ich nicht genau wo? Schließlich will ich die Überprüfung in der Buttonklasse haben, nicht im FrameView-Fenster.
    Weiß aber nicht, ob das geht. Evtl. Timer oder hat jemand ne andere Idee?



  • Naja, um die das rechteck wegzubekommen, musst Du wahrscheinlich das Parent Fenster neu malne, da dort auch das Rechtecke liegt. Also wirst Du im Button selbst nicht viel uasrichten können. Erzwinge ein Paint des Parents.



  • Ja, ich hatte meine Applikation nun schon sehr weit geändert. Das Zeichnen ging, aber das wegbekommen ist ne andere Sache.
    Mal sehen, vielleicht kann ich das ja dann irgendwie noch umgehen.
    Danke für die Tipps und Anregungen.

    MfG,
    Paul.



  • Schau mal hier:
    http://www.codeproject.com/buttonctrl/hoverbutton.asp

    Ich denke das könnte was sein für dich

    Gruß



  • Hm, könnte durchaus was sein. Dieses Trackmouseevent kenne ich nicht. Mal sehen, was sich damit anstellen lässt.
    Danke!
    🙂


Anmelden zum Antworten