Click here to Skip to main content
15,891,372 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
INTRODUCTION AND RELEVANT INFORMATION:

I need to have themed common controls but with different text color, and transparent background. I have ran into a problem that is well documented in this question[^].

I have made some progress by handling NM_CUSTOMDRAW and have decided to finish the checkbox first.

PROBLEM:

I got stuck with determining the state of the checkbox, so I can not pass the correct parameter for DrawThemeBackground().

Code speaks more than words, so here is the snippet:
C++
case WM_NOTIFY:
    {
        if( ((LPNMHDR)lParam)->code == NM_CUSTOMDRAW )
        {
            switch( ((LPNMHDR)lParam)->idFrom ) 
            {
            case IDC_CHECK1:
                {
                    switch( ((LPNMCUSTOMDRAW)lParam)->dwDrawStage  )
                    {
                    case CDDS_PREERASE:
                        {
                            HRESULT hr = 
                            DrawThemeParentBackground( (
                                (LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
                                ((LPNMCUSTOMDRAW)lParam)->hdc,
                                &((LPNMCUSTOMDRAW)lParam)->rc );
                            
                            if( FAILED(hr) )
                            {
                                SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 
                                    (LONG_PTR)CDRF_DODEFAULT );
                                return TRUE;
                            }
                            
                            HTHEME hTheme = 
                                OpenThemeData( 
                                    ((LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom, 
                                    L"BUTTON" );
                            
                            if(!hTheme)
                            {
                                CloseThemeData(hTheme);
                                SetWindowLongPtr( hDlg, 
                                    DWLP_MSGRESULT, 
                                    (LONG_PTR)CDRF_DODEFAULT );
                                return TRUE;
                            }
                            
                            // draw the state
                            
                            LRESULT state = SendMessage( 
                                ((LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
                                BM_GETSTATE, 0, 0 );
                            
                            int stateID;
                            
                            switch( ((LPNMCUSTOMDRAW)lParam)->uItemState )
                            {
                            case CDIS_HOT:
                                {
                                    if( IsDlgButtonChecked( hDlg, 
                                        ((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
                                        stateID = CBS_CHECKEDHOT;
                                    else
                                        stateID = CBS_UNCHECKEDHOT;
                                    break;
                                }
                            case CDIS_DEFAULT:
                                {
                                    if( IsDlgButtonChecked( hDlg, 
                                        ((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
                                        stateID = CBS_CHECKEDNORMAL;
                                    else
                                        stateID = CBS_UNCHECKEDNORMAL;
                                    break;
                                }
                            case CDIS_FOCUS:
                                {
                                    if( IsDlgButtonChecked( hDlg, 
                                        ((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
                                        stateID = CBS_CHECKEDNORMAL;
                                    else
                                        stateID = CBS_UNCHECKEDNORMAL;
                                    break;
                                }
                            case CDIS_SELECTED:
                                {
                                    if( IsDlgButtonChecked( hDlg, 
                                        ((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) )
                                        stateID = CBS_CHECKEDPRESSED;
                                    else
                                        stateID = CBS_UNCHECKEDPRESSED;
                                    break;
                                }
                            }
                            
                            RECT r;
                            SIZE s;
                            
                            GetThemePartSize( hTheme, 
                                ((LPNMCUSTOMDRAW)lParam)->hdc, 
                                BP_CHECKBOX,
                                stateID, 
                                NULL, 
                                TS_TRUE ,&s );
                            
                            r.left = ((LPNMCUSTOMDRAW)lParam)->rc.left;
                            r.top = ((LPNMCUSTOMDRAW)lParam)->rc.top;
                            r.right = ((LPNMCUSTOMDRAW)lParam)->rc.left + s.cx;
                            r.bottom = ((LPNMCUSTOMDRAW)lParam)->rc.top + s.cy;
                            
                            DrawThemeBackground( hTheme, 
                                ((LPNMCUSTOMDRAW)lParam)->hdc,
                                BP_CHECKBOX, stateID,
                                &r,
                                NULL );
                            
                            ((LPNMCUSTOMDRAW)lParam)->rc.left +=  2 + s.cx;
                            
                            DrawText( ((LPNMCUSTOMDRAW)lParam)->hdc,
                                L"Example text", 
                                -1, &((LPNMCUSTOMDRAW)lParam)->rc,
                                DT_SINGLELINE | DT_VCENTER );
                            
                            CloseThemeData(hTheme);
                            SetWindowLongPtr( hDlg, DWLP_MSGRESULT, 
                                (LONG_PTR)CDRF_SKIPDEFAULT );
                            return TRUE;
                        }
                    }
                }
                break;
            }
        }
    }
    break;


The text color and text background are set in the WM_CTLCOLORSTATIC handler:

C++
case WM_CTLCOLORSTATIC:
    {
        SetTextColor( (HDC)wParam, RGB( 255, 0, 0 ) );
        SetBkMode( (HDC)wParam, TRANSPARENT );
    }
    return (INT_PTR)( (HBRUSH)GetStockObject(NULL_BRUSH) );


I have included common controls 6 with the #pragma comment and InitCommonControlsEx().

QUESTION:

All I need for now is to pass proper state for the DrawThemeBackground. Can someone help me with this?

EDIT:

The solution that satisfied my needs can be found here[^].

The only problem was in the line bool bChecked = (uiItemState & CDIS_CHECKED);.

It threw C4800 warning[^].

After numerous tries I had to rewrite the offensive line to bool bChecked = ( BST_CHECKED == IsDlgButtonChecked( hDlg, ((LPNMCUSTOMDRAW)lParam)->hdr.idFrom ) );.

In order for everything to work properly I also had to rearrange the order of if statements :
C++
if (uiItemState & CDIS_SELECTED)
    stateID = (bChecked) ? CBS_CHECKEDPRESSED : CBS_UNCHECKEDPRESSED;
else 
    if (uiItemState & CDIS_HOT)
        stateID = (bChecked) ? CBS_CHECKEDHOT : CBS_UNCHECKEDHOT;
    else
        stateID = (bChecked) ? CBS_CHECKEDNORMAL : CBS_UNCHECKEDNORMAL;


The only thing left is to handle keyboard focus by drawing focus rectangle, but I have trouble in using the correct color.

END OF EDIT

Thank you.

Best regards.
Posted
Updated 29-Mar-14 0:14am
v3

1 solution

Hi,

Have a look at the NMCUSTOMDRAW structure[^]. You should be checking the value of uItemState. Note that the MSDN entry says: 'This value is a combination of the following flags.'. This is a hint that you should not be checking by-value... but rather for (bitmask & value).

Best Wishes,
-David Delaune
 
Share this answer
 
Comments
AlwaysLearningNewStuff 29-Mar-14 6:03am    
Thank you. 5ed. Best regards.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900