Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ MFC
Hello,
 
I do want to draw round edged button with gradient in back ground
 
Can anyone help me out?
Posted 2-Mar-10 1:00am
AJ831.2K
Comments
ManjIndian at 9-Oct-12 9:43am
   
this one is also a single line question.... but seniors will answer for this... not for mine.. what a funny...................
Page 1 of 4

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

For head start, here is a sample of it in C#
Round Button in C#[^]
 
Update:
I saw the tag. I gave you that as a start to you. You will have to Paint it yourself. Handle the Paint event for the button.
 
or are you asking the full codebase for what you need?
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 8

But i have to define some thing here: the bold.
 
m_cButon.Create("", WS_CHILD | WS_VISIBLE, CRect(150, 20, 250, 43), this, UNIT ID);
 
what to provide for UINT ID?
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 10

Eugen, the project which i had sent you earlier, I am working on the same project.
 
I am creating button in one cpp and using it in another cpp. Like this.
 
int CMyButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CButton::OnCreate(lpCreateStruct) == -1)
        return -1;
 
    // TODO:  Add your specialized creation code here
    m_cButon.Create("", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(20, 34, 90, 79), this, 1);
 
    return 0;
}
 
And using here.
void CDisplayBar::DoDataExchange(CDataExchange* pDX)
{
    // TODO: Add your specialized code here and/or call the base class

    CDialogBar::DoDataExchange(pDX);
 
    DDX_Control(pDX, 1, m_Btn1);
 }
 
For more clarification, try to look on my sent project which is named as ColoredButton.
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 21

No, first i do want to work with one button perfectly.
 
But after making "Owner draw" FALSE, still control is not coming hre:
 
int CMyButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CButton::OnCreate(lpCreateStruct) == -1)
        return -1;
 
    // TODO:  Add your specialized creation code here
    //m_cButon.Create("", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(20, 34, 90, 79), this, 1);
    this->SetWindowRgn(m_cRgn, TRUE);
 
    return 0;
}
 
and here:
 
void CMyButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	// TODO: Add your message handler code here and/or call default
	CButton::OnDrawItem(nIDCtl, lpDrawItemStruct);
	CRect cRect;
	m_cButon.GetClientRect(cRect);
	m_cRgn.CreateRoundRectRgn(0, 0, cRect.Width(), cRect.Height(), 25, 25);
	m_cButon.SetWindowRgn(m_cRgn, TRUE);
}
 
And i am not getting Round Edged Button.
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 23

Yes. it is there.
 
public:
    CDisplayBar();
    virtual ~CDisplayBar();
    void InitDialog();
 
    // Dialog Data
  //{{AFX_DATA(CDisplayBar)
    enum { IDD = IDD_DIALOGBAR };
    CMyButton m_Btn1;
  //}}AFX_DATA
 

BEGIN_MESSAGE_MAP(CMyButton, CButton)
    ON_WM_CREATE()
    ON_WM_DRAWITEM()
END_MESSAGE_MAP()
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 25

When i am making "Owner Draw" TRUE for IDC_BUTTON!, I am gettng "Debug Assertion Failed.
 
How to get rid of this. I have already posted where i am getting this error, please do have a look of my previous reply.
 
void CButton::DrawItem(LPDRAWITEMSTRUCT)
{
    ASSERT(FALSE);
}
Here i am getting "Debug Assertion Failed".
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 41

Thanks Eugen.
 
Now one new issue came into picture. When i am changing Dialogbar background, then i am able to see rectangular edges of button which of grey in color.
 
Though we have made round edged button but rectangular edge is still there whcih you can see when you change background color of form
 
here is the piece of code fof changing background color:
BOOL CButtonDialogBar::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default
  CRect rect;
  GetClientRect(&rect);
  int r1=19,g1=40,b1=85; //Any start color
  int r2=60,g2=88,b2=156; //Any stop color
  for(int i=0;i<rect.Height();i++)
  { 
    int r,g,b;
    r = r1 + (i * (r2-r1) / rect.Height());
    g = g1 + (i * (g2-g1) / rect.Height());
    b = b1 + (i * (b2-b1) / rect.Height());
    pDC->FillSolidRect(0,i,rect.Width(),1,RGB(r,g,b));
  }
  return true; 
}
 
And add this code for CMyButton:
void CRoundColoredButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  CDC dc;
  RECT rect;
  dc.Attach(lpDrawItemStruct ->hDC); 
  CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  pDC->RoundRect(0,
                 0,
                 lpDrawItemStruct->rcItem.right,
                 lpDrawItemStruct->rcItem.bottom,
                 50,
		 50);
  
  CRgn cRgn1;
  cRgn1.CreateRoundRectRgn(0,
                          0,
                          lpDrawItemStruct->rcItem.right,
                          lpDrawItemStruct->rcItem.bottom,
                          50,
                          50);
  pDC->SelectClipRgn(&cRgn1);
  pDC->FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255, 255, 255));
 
  CRgn cRgn2;
  cRgn2.CreateRoundRectRgn(3,
                          3,
                          lpDrawItemStruct->rcItem.right-3,
                          lpDrawItemStruct->rcItem.bottom-3,
                          50,
                          50);
  pDC->SelectClipRgn(&cRgn2);
 
  int r2=19,g2=40,b2=85; //Any start color
  int r1=60,g1=88,b1=156; //Any stop color
  
  rect = lpDrawItemStruct->rcItem;     //Store the Button rect to our local rect.
  for(int i=0;i<rect.bottom;i++)
  { 
    int r,g,b;
    r = r1 + (i * (r2-r1) / rect.bottom);
    g = g1 + (i * (g2-g1) / rect.bottom);
    b = b1 + (i * (b2-b1) / rect.bottom);
   dc.FillSolidRect(0,i,rect.right,1,RGB(r,g,b));
  }
 
  CString strText;
  GetWindowText(strText);
  int iOldMode = pDC->SetBkMode(TRANSPARENT);
  COLORREF crOldColor = pDC->SetTextColor(RGB(255,255,255));
 
  if (lpDrawItemStruct->itemState & ODS_SELECTED) {
    lpDrawItemStruct->rcItem.top += 2;
    lpDrawItemStruct->rcItem.left += 2;
  }
 
  pDC->DrawText(strText, &lpDrawItemStruct->rcItem,  DT_SINGLELINE|DT_VCENTER|DT_CENTER);
  pDC->SetTextColor(crOldColor);
  pDC->SetBkMode(iOldMode);
  pDC->SelectClipRgn(NULL);
}
 
Apply above code, you will come to know what i am talking about,
 
How to make rounded edge button completely by cutting rectangular edge of button?
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 46

Sorry Smile | :)
 
The usage of m_cFont must be placed in to the CRoundColoredButton::DrawItem(..)
 

(we do not need OnDrawItem Smile | :) )
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 56

Yes Smile | :)
 
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  CDC* pDC0 = CDC::FromHandle(lpDrawItemStruct->hDC);
  int iCX = lpDrawItemStruct->rcItem.right;
  int iCY = lpDrawItemStruct->rcItem.bottom;
 
  CRgn cRgn1;
  cRgn1.CreateRoundRectRgn(0,
                           0,
                           lpDrawItemStruct->rcItem.right,
                           lpDrawItemStruct->rcItem.bottom,
                           50,
                           50);
  pDC0->SelectClipRgn(&cRgn1);
  
  CDC cMemDC;
  cMemDC.CreateCompatibleDC(pDC0);
  CDC* pDC = &cMemDC;
  
  CBitmap cBmp;
  cBmp.CreateCompatibleBitmap(pDC0, iCX, iCY);
  CGdiObject* pcOldBitmap = cMemDC.SelectObject(&cBmp);
  
  pDC->RoundRect(0,
                 0,
                 lpDrawItemStruct->rcItem.right,
                 lpDrawItemStruct->rcItem.bottom,
                 50,
                 50);
  pDC->FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255, 255, 255));
  CRgn cRgn2;
  cRgn2.CreateRoundRectRgn(3,
                           3,
                           lpDrawItemStruct->rcItem.right-3,
                           lpDrawItemStruct->rcItem.bottom-3,
                           50,
                           50);
  pDC->SelectClipRgn(&cRgn2);
  int r2=19,g2=40,b2=85; //Any start color
  int r1=60,g1=88,b1=156; //Any stop color
  RECT rect = lpDrawItemStruct->rcItem;     //Store the Button rect to our local rect.
  for(int i=0;i<rect.bottom;i++)  {
    int r,g,b;
    r = r1 + (i * (r2-r1) / rect.bottom);
    g = g1 + (i * (g2-g1) / rect.bottom);
    b = b1 + (i * (b2-b1) / rect.bottom);
    pDC->FillSolidRect(0,i,rect.right,1,RGB(r,g,b));
  }
  CString strText;
  GetWindowText(strText);
  int iOldMode = pDC->SetBkMode(TRANSPARENT);
  COLORREF crOldColor = pDC->SetTextColor(RGB(255,255,255));
  if (lpDrawItemStruct->itemState & ODS_SELECTED) {
    lpDrawItemStruct->rcItem.top += 2;
    lpDrawItemStruct->rcItem.left += 2;
  }
  lpDrawItemStruct->rcItem.top = (lpDrawItemStruct->rcItem.bottom -
                                  lpDrawItemStruct->rcItem.top) /2;
  strText = _T("this is a long\ntest text...");
  pDC->DrawText(strText, &lpDrawItemStruct->rcItem, DT_CENTER|DT_WORDBREAK );
  pDC0->BitBlt(0, 0, iCX, iCY, pDC, 0, 0, SRCCOPY);
  
  pDC->SetTextColor(crOldColor);
  pDC->SetBkMode(iOldMode);
  pDC->SelectObject(pcOldBitmap);
  pDC->DeleteDC();
  pDC0->SelectClipRgn(NULL);
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 31

OK Smile | :)
 
Please check your buttons implementation:
void CMyButton::PreSubclassWindow()
{
  CRect cRect;
  GetWindowRect(cRect);
  m_cRgn.CreateRoundRectRgn(0, 0, cRect.Width(), cRect.Height(), 50, 50);
  SetWindowRgn(m_cRgn, TRUE);
}
 
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
  CRgn cRgn;
  cRgn.CreateRoundRectRgn(0,
                          0,
                          lpDrawItemStruct->rcItem.right,
                          lpDrawItemStruct->rcItem.bottom,
                          50,
                          50);
  CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  pDC->SelectClipRgn(&cRgn);
  _FillGradient(pDC, lpDrawItemStruct->rcItem,
                lpDrawItemStruct->itemState & ODS_SELECTED ?
                RGB(0, 200, 0) : RGB(0, 100, 0),
                lpDrawItemStruct->itemState & ODS_SELECTED ?
                RGB(0, 100, 0) : RGB(0, 200, 0),
                TRUE, 0, 0);
  // Get the button's text.
  CString strText;
  GetWindowText(strText);
  int iOldMode = pDC->SetBkMode(TRANSPARENT);
  COLORREF crOldColor = pDC->SetTextColor(RGB(255,255,255));
  if (lpDrawItemStruct->itemState & ODS_SELECTED) {
    lpDrawItemStruct->rcItem.top += 2;
    lpDrawItemStruct->rcItem.left += 2;
  }
  pDC->DrawText(strText, &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
  
  pDC->SetTextColor(crOldColor);
  pDC->SetBkMode(iOldMode);
  pDC->SelectClipRgn(NULL);
}
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 34

You could draw at three steps Smile | :) :
- CDC::RoundRect(..) at the itemRect
 
- Decrement the itemRect
- The rest (SelectClipRgn(..) and so on)
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 42

Please implement the same function of CMyButton Smile | :) :
BOOL CMyButton::OnEraseBkgnd(CDC* pDC)
{
  return true;
}
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 52

It is working by me Smile | :) :
lpDrawItemStruct->rcItem.top = (lpDrawItemStruct->rcItem.bottom -
                                lpDrawItemStruct->rcItem.top) /2;
strText = _T("this is a long\ntest text...");
pDC->DrawText(strText, &lpDrawItemStruct->rcItem, DT_CENTER|DT_WORDBREAK );
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Here would be the init stage of a button Smile | :) :
  CRect cRect;
  m_cButton.GetWindowRect(cRect);
  // CRgn m_cRgn;
  m_cRgn.CreateRoundRectRgn(0, 0, cRect.Width(), cRect.Height(), 50, 50);
  m_cButton.SetWindowRgn(m_cRgn, TRUE);
Now it is controlled by Windows in this edge.
Secondly, the m_cButton must draw
a gradient surface and a title in the same region Smile | :)
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 5

There are two stages Smile | :) :
- Setting of the buttons region (ON_WM_CREATE()/at CYourButton::OnCreate())
- Drawing inside the region (CYourButton::OnDrawItem(..))
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 7

No. You do not need to create the buttons explicitly
since they are coming from your resources Smile | :)
 
BEGIN_MESSAGE_MAP(CYouButton, CButton)
    //{{AFX_MSG_MAP(CYourButton)
    ON_WM_CREATE()
...
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
  
int CYourButton::OnCreate(LPCREATESTRUCT lpcs)
{
  int iResult = CButton::OnCreate(lpcs);
  // Set the buttons region here
...
  return iResult;
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 9

Are you sure ? Smile | :)
I would use the parents exchange:
 
class CYourPane : public CBaseOfYourPane
{
  CYourButton m_cButton1;
  CYourButton m_cButton2;
...
};
 
void CYourPane::DoDataExchange(CDataExchange* pDX)
{
  CBaseOfYourPane::DoDataExchange(pDX);
  // IDC_BUTTON1 is a "property" of the button in the resource view
  DDX_Control(pDX, IDC_BUTTON1, m_cButton1);
  // IDC_BUTTON2 is a "property" of the button in the resource view
  DDX_Control(pDX, IDC_BUTTON2, m_cButton2);
...
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 11

Please forget m_cButton Smile | :)
 
int CMyButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CButton::OnCreate(lpCreateStruct) == -1)
    return -1;
 
  // We are created, now it is time to set our region :)
...
  this->SetWindowRegion(..); // or just SetWindowRegion(..)

  return 0;
}
 
Please do not modify the buttons IDs in the exchange function -
they must remain the same to "properties" of the buttons in the resource view Smile | :)
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 20

Very good Smile | :)
 
You could include the second button in the function
or reset its "Owner Draw" property to "False" Smile | :)
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 22

Please check
- The m_Btn1 is from the type CMyButton
 
- You have the ON_WM_CREATE(); macro in the message map of CMyButton
  Permalink  
Page 1 of 4
1 2 3 4

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

  Print Answers RSS
0 Maciej Los 225
1 OriginalGriff 145
2 manoj kumar choubey 115
3 _Amy 115
4 Sergey Alexandrovich Kryukov 105
0 OriginalGriff 7,320
1 Sergey Alexandrovich Kryukov 6,043
2 Maciej Los 3,749
3 Peter Leow 3,408
4 DamithSL 2,555


Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 4 Mar 2010
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100