0

I designed a property sheet and painted its footer to some gradient in the OnPaint() event. The footer looks like as below.Observe the button area circled in red colour. enter image description here

In the OnPaint I was doing as follows,

//CMySheet is derived from CPropertySheet.
void CMySheet::OnPaint()
{

if(IsIconic())
    {
        CPaintDC dc(this); // device context for painting
        SendMessage(WM_ICONERASEBKGND,reinterpret_cast<WPARAM>(dc.GetSafeHdc()),0);

        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);

        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1)/2;
        int y = (rect.Height() - cyIcon + 1)/2;

    }
    else
    {
        CPaintDC dc(this);

        UpdateData(false);

        CRect Clientrect;
        GetClientRect(&Clientrect);

        LONG RectDifference = ((Clientrect.bottom - m_PageRectBottom)-2);//m_pageRectBottom is of page bottom rect

        CRect rectFooter(Clientrect.top,(Clientrect.bottom - RectDifference),Clientrect.right,Clientrect.bottom);//638//520
        //CRect rectFooter(0,390,640,445);
        FillGradation(&dc,rectFooter,RGB(150,150,150),RGB(0,0,0),true);

    }

}
}

void CMySheet::OnPaint(CDC* pDC, CRect rc, COLORREF colBegin, COLORREF colEnd, bool bV)
{
    TRIVERTEX av[2] = {rc.left,rc.top,GetRValue(colBegin) << 8,GetGValue(colBegin) << 8,GetBValue(colBegin) << 8 ,0xff00,
        rc.right,rc.bottom,GetRValue(colEnd) << 8 ,GetGValue(colEnd) << 8,GetBValue(colEnd) << 8,0xff00,};

    GRADIENT_RECT gr = {0,1};
    ULONG ulMode;
    if(bV){
        ulMode = GRADIENT_FILL_RECT_V;
    }
    else{
        ulMode = GRADIENT_FILL_RECT_H;       
    }
    GradientFill(pDC->GetSafeHdc(),av,2,&gr,1,ulMode);

}

The buttons are not transparent in the above image ,but actually the background of the button should look like as in below image.

enter image description here

The wizard buttons background or the footer area should look like the above image.But if you can have a look at the first image in that there is some white colour around the Back button ,Next and cancel buttons.

HBRUSH CMySheet::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    HBRUSH hbr = CPropertySheet::OnCtlColor(pDC, pWnd, nCtlColor);

    if((pWnd->GetDlgCtrlID() == ID_WIZBACK) || (pWnd->GetDlgCtrlID() == ID_WIZNEXT) ||
        (pWnd->GetDlgCtrlID() == ID_WIZFINISH) || (pWnd->GetDlgCtrlID() == IDCANCEL))
    {
        return CreateSolidBrush(RGB(130,130,130));
    }

  return hbr;
}

If I am doing like this ,the Image is as follows with gray colour .But that colour should be gradient right,I am not able to create a Gradient brush.

enter image description here

I tried returning NULL in CtlColor but I could not see any difference.

Derived my own classes from CPropertySheet and CButton ,

//Overrided the DrawItem and PreSubclassWindow
    void CPropSheetButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
    {

        CDC* pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
        CRect rect = lpDrawItemStruct->rcItem;
        UINT state = lpDrawItemStruct->itemState;


        if (state & ODS_SELECTED)
            pDC->DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_PUSHED);
           else
               pDC->DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTONPUSH);

        UINT uStyle = DFCS_BUTTONPUSH;
        HTHEME hTheme = OpenThemeData(m_hWnd, L"BUTTON");
        HRESULT hr = DrawThemeBackground(hTheme, lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_DEFAULTED, &lpDrawItemStruct->rcItem, NULL);

        // Get the button's text.
        CString strText;
        GetWindowText(strText);


        CloseThemeData(hTheme);
        ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),
            &lpDrawItemStruct->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);


            int nMode = pDC->SetBkMode(TRANSPARENT);
            pDC->SetBkMode(nMode);

    }

    void CPropSheetButton::PreSubclassWindow() 
    {
        CButton::PreSubclassWindow();

        ModifyStyle(0, BS_OWNERDRAW);   // make the button owner drawn
    }
    //In the Sheet derived class OnInitDialog ,
    BOOL CMySheetWizard::OnInitDialog()
    {

        CPropertySheet::OnInitDialog();
        CMyButton backbutton;
        BOOL bRet = backbutton.SubclassDlgItem(ID_WIZBACK,this);
    }

Can anyone please let me know how I can remove the border around those buttons.

Siva
  • 1,281
  • 2
  • 19
  • 41
  • i guess that the "45" stands for the distance between the last control's bottom value (top+height of the control excluding the back, next, cancel, finish buttons) and the bottom of the dialog (Clientrect.bottom). but anyway, can you show more the dialog? like not only those buttons but a little bit more to see what you have up there – Robson Nov 11 '14 at 11:35
  • Modified the above post now I am able to paint paint the area properly,In order to over come that problem I had just got the page bottom rect and got it , but only the white square around the wizard buttons is not done.can anyone guide me how can I get rid of that white square round the button. – Siva Nov 19 '14 at 03:51
  • You need to handle WM_CTL_COLOR for the buttons and return a NULL brush. – user1793036 Nov 20 '14 at 06:37
  • @user1793036 returning NULL made no change.Actually I subclassed CButton and in this subclass I handled WM_CTL_COLOR and here I tried returning NULL,but it didn't show me any effect can you please elaborate what extra needs to be done to get that done.If possible kindly share a sample code with me. – Siva Nov 20 '14 at 11:53

1 Answers1

0

Using your painting code to render the background and some extra classes, I was able to achieve this...

enter image description here

I think this was what you were trying to achieve. I was able to accomplish this by doing the following:

  • Derive my own CPropertySheet and CButton classes.
  • Subclass the property sheet buttons and make them owner drawn.

And here's the code that draws the buttons from the button class.

void SheetButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    UINT uStyle = DFCS_BUTTONPUSH;
    HTHEME hTheme = OpenThemeData(m_hWnd, L"BUTTON");
    DrawThemeBackground(hTheme, lpDrawItemStruct->hDC, BP_PUSHBUTTON, PBS_DEFAULTED, &lpDrawItemStruct->rcItem, NULL);

    // Get the button's text.
    CString strText;
    GetWindowText(strText);

    // Draw the button text using the text color red.
    COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255, 0, 0));
    ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),
        &lpDrawItemStruct->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
    ::SetTextColor(lpDrawItemStruct->hDC, crOldColor);

    CloseThemeData(hTheme);
    }

BTW...you still need to add code to return a null brush for the buttons. I did not, however, account for the different states of the buttons in the drawing code. I left that up to you as an exercise.

rrirower
  • 4,338
  • 4
  • 27
  • 45
  • As you suggested I derived a class from CButton and named it as CPropSheetButton and overrided DrawItem method . In the CMySheet(CPropertySheet derived class) OnInitDialog I added these steps CPropSheetButton BackBtn; BackBtn.SubClassDlgItem(ID_WIZBACK,this); – Siva Nov 23 '14 at 11:40
  • But DrawItem is not at all getting fired.Same Logic I applied in a Dialog sample there it is working good.And in the DrawItem I added piece of code for button state(ODS_SELECTED).It is bit fuzzy why DrawItem is not getting fired in the propertysheet.Can please let me know whether I am calling SubClassDlgItem in an appropriate place or not.Or will can you please let me what is right way of calling to make this work.One thing what I noticed is the button is like a DEFPUSHBUTTON even though I am clicked on a different button it's state is remaining as DEFPUSHBUTTON style( not changing). – Siva Nov 23 '14 at 11:45
  • Did you change the style of the button to indicate it is owner draw? – rrirower Nov 23 '14 at 13:14
  • Yes I changed the button style to BS_OWNERDRAW in the CButton derived class as follows, void CPropSheetButton::PreSubclassWindow(){ CButton::PreSubclassWindow(); ModifyStyle(0,BS_OWNERDRAW);}And one more thing is when I called BackBtn.SubClassDlgItem(ID_WIZBACK,this);the back button is simply vanished.When I commented this line again the back button is back.For more details I will update my original post please have a look and let me know where I am doing wrong. – Siva Nov 24 '14 at 04:17
  • If the button vanishes, that typically means you are not handling the DrawItem correctly. You should set breakpoints and debug the code. – rrirower Nov 24 '14 at 13:22
  • That is what I mean to say that DrawItem is not at all being called.Same Logic I applied in a dialog application in that it is being called.My doubt is calling BackBtn.SubClassDlgItem(ID_WIZBACK,this) will not work for wizard buttons ? – Siva Nov 27 '14 at 04:07