mfccbutton

Custom draw button using uxtheme.dll


I have implemented my custom button inheriting from CButton and drawing it by using uxtheme.dll (DrawThemeBackground with BP_PUSHBUTTON).

Everything works fine but I have two statuses (Normal and Pressed) which Hot status is the same. It means when the user places the cursor over the button it is drawn alike regardless the button status (Pressed or not).

This is a bit confusing to the user and I would like to change the way the button is drawn in Pressed & Hot status. Does anybody know a way?

I have also thought about custumizing the whole drawing but the buttons use gradients, borders, shadows, etc. So it is not easy to achive the same look&feel drawing everything by myself. Is there a way to find the source code of the dll or know how to do it?

Thanks in advance.

Javier

Note: I think I could be able to achive what I want to do by using CMFCButton and overriding the OnDraw method. Let the control draw the button on OnDrawBorder and then drawing the inside button myself. But I need to know how the control draws the inside button when pressed. It is a gradient and I can't guess how it's done. Does anybody have a clue?


Solution

  • I finally figured out how to achive what I want to do. It's pretty easy indeed.

    I use two calls to DrawThemeBackground. The first one with PBS_PRESSED and the second one with state PBS_HOT. Then I make a ExcludeClipRect to avoid from drawing over the center of the button.

    Something like this:

            DrawThemeBackground(    hTheme,
                                    pCustomDraw->hdc, 
                                    BP_PUSHBUTTON,
                                    PBS_PRESSED,
                                    &pCustomDraw->rc, 
                                    NULL);
    
            CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
    
            CRect rectClient;
            GetClientRect(rectClient);
            CRect rectInternal = rectClient;
    
            rectInternal.DeflateRect(4,4);
            pDC->SelectClipRgn(NULL);
            pDC->ExcludeClipRect(&rectInternal);
    
            DrawThemeBackground(    hTheme,
                                    pCustomDraw->hdc, 
                                    BP_PUSHBUTTON,
                                    PBS_HOT,
                                    &pCustomDraw->rc, 
                                    NULL);
    
            pDC->SelectClipRgn(NULL);
    

    Of course this is not the whole code but I think is enough to make my point.

    Thanks.