http://www.codeproject.com/Articles/302/Elliptic-Buttons
void CEllepticalButton::PreSubclassWindow() { CButton::PreSubclassWindow(); m_bDefault=GetStyle() & (DWORD)BS_DEFPUSHBUTTON; //this is necessary as // the default button style gets removed when u make it ownerdrawn ModifyStyle(0, BS_OWNERDRAW); CRect rect; GetClientRect(rect); // Resize the window to make it square //commented by Raghav //rect.bottom = rect.right = min(rect.bottom,rect.right); printf("l = [%d], r = [%d], t = [%d], b = [%d]\n", rect.left, rect.right, rect.top, rect.bottom); // Get the vital statistics of the window m_ptCentre = rect.CenterPoint(); m_nHorizontalRadius = rect.right/2-1; m_nVerticalRadius = rect.bottom/2-1; // Set the window region so mouse clicks only activate the round section // of the button m_rgn.DeleteObject(); SetWindowRgn(NULL, FALSE); m_rgn.CreateEllipticRgnIndirect(rect); SetWindowRgn(m_rgn, TRUE); // Convert client coords to the parents client coords ClientToScreen(rect); CWnd* pParent = GetParent(); if (pParent) pParent->ScreenToClient(rect); printf("l = [%d], r = [%d], t = [%d], b = [%d]\n", rect.left, rect.right, rect.top, rect.bottom); // Resize the window MoveWindow(rect.left, rect.top, rect.Width(), rect.Height(), TRUE); } void CEllepticalButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { ASSERT(lpDrawItemStruct != NULL); CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rect = lpDrawItemStruct->rcItem; UINT state = lpDrawItemStruct->itemState; UINT nStyle = GetStyle(); int nHorizontalRadius = m_nHorizontalRadius; int nVerticalRadius = m_nVerticalRadius; int nSavedDC = pDC->SaveDC(); printf("drawing item...\n"); // cout << "di = " << endl; pDC->SelectStockObject(NULL_BRUSH); pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE)); // Draw the focus circle around the button either if it has the focus //or if it is the default button if ((state & ODS_FOCUS || m_bDefault) && m_bDrawDashedFocusCircle) DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, RGB(0,0,0)); // Draw the raised/sunken edges of the button (unless flat) if (nStyle & BS_FLAT) { DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, RGB(0,0,0)); DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, ::GetSysColor(COLOR_3DHIGHLIGHT)); } else { if ((state & ODS_SELECTED)) { DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, ::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT)); DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT)); } else { DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, ::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW)); //RGB(255,255,255), ::GetSysColor(COLOR_3DDKSHADOW)); DrawEllipse(pDC, m_ptCentre, nHorizontalRadius--, nVerticalRadius--, ::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DSHADOW)); } } // draw the text if there is any CString strText; GetWindowText(strText); if (!strText.IsEmpty()) { CRgn rgn; rgn.CreateEllipticRgn(m_ptCentre.x-nHorizontalRadius, m_ptCentre.y-nVerticalRadius, m_ptCentre.x+nHorizontalRadius, m_ptCentre.y+nVerticalRadius); pDC->SelectClipRgn(&rgn); CSize Extent = pDC->GetTextExtent(strText); CPoint pt = CPoint( m_ptCentre.x - Extent.cx/2, m_ptCentre.y - Extent.cy/2 ); if (state & ODS_SELECTED) pt.Offset(1,1); pDC->SetBkMode(TRANSPARENT); if (state & ODS_DISABLED) pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL); else pDC->TextOut(pt.x, pt.y, strText); pDC->SelectClipRgn(NULL); rgn.DeleteObject(); } // Draw the focus circle on the inside of the button if ((state & ODS_FOCUS) && m_bDrawDashedFocusCircle) DrawEllipse(pDC, m_ptCentre, nHorizontalRadius-2, nVerticalRadius-2, RGB(0,0,0), TRUE); pDC->RestoreDC(nSavedDC); }