Click here to Skip to main content
16,019,043 members
Please Sign up or sign in to vote.
3.88/5 (6 votes)
See more:
Hello,

I do want to draw round edged button with gradient in back ground

Can anyone help me out?
Posted
Comments
ManjIndian 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 3


You are welcome :)

(Please implement your validations
of the used pointers and functions results, thank you)
 
Share this answer
 
Thanks for everything which you have provided to me. :)
 
Share this answer
 
I have done exactly same as suggested by you. but i am getting all buttons with white color in background and it is not showing any text on the button.

Tomorrow, again i will check it and do let you know.

Thanks once again for all code which you have given to me.
 
Share this answer
 
The idea is already tested:
you should use a memory DC to draw there
and then - copy it to the buttons DC
that is protected with a clipping region :)

Please just copy the code, try it as is
and then modify it (font, ...)

Good luck :)
 
Share this answer
 
Eugen, If i am doing this, I am loosing my Gradient color and i am getting white color in whole button.

So any other idea?
 
Share this answer
 
Yes :)

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);
}
 
Share this answer
 
OK.....

One Question: I got everything which i wanted. But now when i am clicking button many times, it is flickering and sometimes some of its area color is appearing grey for very small period of time say in milliseconds.

Can we handle this type of flickering or appearance of grey color?
 
Share this answer
 
v2
You can not draw something outside of lpDrawItemStruct->rcItem

but you could set a small surface region and a large text region
inside of of lpDrawItemStruct->rcItem :)
 
Share this answer
 
Thanks......

Is there any way to make text appearance in button just above bottom border?
 
Share this answer
 
It is working by me :) :
C++
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 );
 
Share this answer
 
No. it's not working for me.... any other idea?
 
Share this answer
 
You could change the rectangle of the text instead,
for example - offset it down :)

Use the description[^] and the flag DT_WORDBREAK
to process a multiline output :)
 
Share this answer
 
I did this already. I do want Button name say "Computer Data". But this is coming very close to bottom border and name is not looking good.

I do want little bit up from bottom border so that it will look good in appearance.

Try with this Font:

MIDL
m_ptrFont  = new CFont();
m_ptrFont->CreateFont(16, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                                            DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial");


And i also want Multiline property TRUE.
 
Share this answer
 
You should remove the DT_VCENTER flag :)
 
Share this answer
 
Thanks....

How to make Text align in bottom but in center?

I am trying this:
pDC->DrawText(strText, &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER|DT_BOTTOM);


But text is going at top. I have also tried different combinations. but did not get thru. And i do want with Multiline property true.

Any Suggestion?
 
Share this answer
 
v2
Sorry :)

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


(we do not need OnDrawItem :) )
 
Share this answer
 
Control is not coming in "OnDrawItem()".

here's my code:
void CRoundColoredButton::PreSubclassWindow()
{
	// TODO: Add your specialized code here and/or call the base class
	CButton::PreSubclassWindow();
	CRect cRect;
	GetWindowRect(cRect);
	m_cRgn.CreateRoundRectRgn(0, 0, cRect.Width(), cRect.Height(), 100, 100);
	SetWindowRgn(m_cRgn, TRUE);
	m_cFont.CreatePointFont(5, "Arial Black");
}


void CRoundColoredButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	// TODO: Add your message handler code here and/or call default
	CString strText;
	GetWindowText(strText);
	CButton::OnDrawItem(nIDCtl, lpDrawItemStruct);
	CDC* pDC = new CDC();
	CGdiObject* pOldFont = pDC->SelectObject(&m_cFont);
	pDC->DrawText(strText, &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	pDC->SelectObject(pOldFont);
}
 
Share this answer
 
Of course, before you are drawing the text :)

CFont m_cFont could be created in CMyButton::PreSubclassWindow()

and then - used in CMyButton::OnDrawItem():
{
...
   CGdiObject* pcOldFont = pDC->SelectObject(&m_cFont);
   pcDC->DrawText(..);
   pDC->SelectObject(pcOldFont);
...
}
 
Share this answer
 
Thanks again....

And again one more question: Do we have to set font in Drawitem() only?
Or in someother function.

I tried in DrawItem(), but did not get good result.

Any suggestion?
 
Share this answer
 
Please implement the same function of CMyButton :) :
C++
BOOL CMyButton::OnEraseBkgnd(CDC* pDC)
{
  return true;
}
 
Share this answer
 
v2

Page 1 of 3
1 2 3

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