15,979
社区成员
发帖
与我相关
我的任务
分享
void path2rgn(int quadrant,CButton *pBT)
{
int gap=8;
int innerR=110;
int outerR=200;
int roundR=76;
CPoint start1, end1, start2, end2;
CPoint center(outerR+80,outerR+20);
CClientDC dc(pBT);
switch(quadrant)
{
case 0:
{
CRect rcRound(center.x-roundR,center.y-roundR,center.x+roundR,center.y+roundR);
dc.BeginPath();
dc.Ellipse(&rcRound);
dc.EndPath();
CRgn rgn0;
CRect rc0;
rgn0.CreateFromPath(&dc);
rgn0.GetRgnBox(&rc0);
//afxDump << rc0 << "\n";
pBT->MoveWindow(rc0.left,rc0.top,rc0.Width(),rc0.Height(),TRUE);
rgn0.OffsetRgn(-rc0.left, -rc0.top);
SetWindowRgn(pBT->m_hWnd, rgn0, FALSE);
//
DeleteObject(&rgn0);
return;
}
case 1:
start1.x=center.x+innerR; start1.y=center.y-gap;
start2.x=center.x+outerR; start2.y=center.y-gap;
end1.x=center.x+gap; end1.y=center.y-innerR;
end2.x=center.x+gap; end2.y=center.y-outerR;
break;
case 2:
start1.x=center.x-gap; start1.y=center.y-innerR;
start2.x=center.x-gap; start2.y=center.y-outerR;
end1.x=center.x-innerR; end1.y=center.y-gap;
end2.x=center.x-outerR; end2.y=center.y-gap;
break;
case 3:
start1.x=center.x-innerR; start1.y=center.y+gap;
start2.x=center.x-outerR; start2.y=center.y+gap;
end1.x=center.x-gap; end1.y=center.y+innerR;
end2.x=center.x-gap; end2.y=center.y+outerR;
break;
case 4:
start1.x=center.x+gap; start1.y=center.y+innerR;
start2.x=center.x+gap; start2.y=center.y+outerR;
end1.x=center.x+innerR; end1.y=center.y+gap;
end2.x=center.x+outerR; end2.y=center.y+gap;
break;
}
CRect rcInner(center.x-innerR,center.y-innerR,center.x+innerR,center.y+innerR);
CRect rcOuter(center.x-outerR,center.y-outerR,center.x+outerR,center.y+outerR);
dc.BeginPath();
dc.MoveTo(start1.x,start1.y);
dc.LineTo(start2.x,start2.y);
dc.ArcTo(&rcOuter,start2,end2);
dc.LineTo(end1.x,end1.y);
// change dir (is modal)
dc.SetArcDirection(AD_CLOCKWISE);
dc.ArcTo(&rcInner,end1, start1);
// restore dir
dc.SetArcDirection(AD_COUNTERCLOCKWISE);
dc.EndPath();
// dc.StrokeAndFillPath();
CRgn rgn;
CRect rc;
rgn.CreateFromPath(&dc);
rgn.GetRgnBox(&rc);
//afxDump << rc << "\n";
pBT->MoveWindow(rc.left,rc.top,rc.Width(),rc.Height(),TRUE);
rgn.OffsetRgn(-rc.left, -rc.top);
SetWindowRgn(pBT->m_hWnd, rgn, FALSE);
//
DeleteObject(&rgn);
}
初始化
// TODO: Add extra initialization here
path2rgn(0,&m_Bt0);
path2rgn(1,&m_Bt1);
path2rgn(2,&m_Bt2);
path2rgn(3,&m_Bt3);
path2rgn(4,&m_Bt4);
自绘
void CArcButtonsDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDIS)
{
// TODO: Add your message handler code here and/or call default
CDC memDC;
CDC *pDC;
CRgn rgn;
CRect rect = lpDIS->rcItem;
rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
::GetWindowRgn(lpDIS->hwndItem,rgn);
//
SelectClipRgn(lpDIS->hDC,rgn);
switch(nIDCtl)
{
case IDC_BUTTON0:
pDC=CDC::FromHandle(lpDIS->hDC);
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_Bmp);
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,130,130,SRCCOPY);
break;
case IDC_BUTTON1:
pDC=CDC::FromHandle(lpDIS->hDC);
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_Bmp);
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,215,4,SRCCOPY);
break;
case IDC_BUTTON2:
pDC=CDC::FromHandle(lpDIS->hDC);
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_Bmp);
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,4,4,SRCCOPY);
break;
case IDC_BUTTON3:
pDC=CDC::FromHandle(lpDIS->hDC);
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_Bmp);
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,4,215,SRCCOPY);
break;
case IDC_BUTTON4:
pDC=CDC::FromHandle(lpDIS->hDC);
memDC.CreateCompatibleDC(pDC);
memDC.SelectObject(&m_Bmp);
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,215,215,SRCCOPY);
break;
}
// CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
}
//
void CArcButtonsDlg::OnButton0()
{
// TODO: Add your control notification handler code here
AfxMessageBox("Button0 at Your Service!");
OnOK();
}
void path2rgn(CDC &dc,int quadrant,COLORREF color)
{
int gap=8;
int innerR=110;
int outerR=210;
int roundR=76;
CPoint center(300,220);
CPoint start1, end1, start2, end2;
switch(quadrant)
{
case 0:
{
CRect rcRound(center.x-roundR,center.y-roundR,center.x+roundR,center.y+roundR);
dc.BeginPath();
dc.Ellipse(&rcRound);
dc.EndPath();
CBrush brush(color);
CRgn rgn0;
rgn0.CreateFromPath(&dc);
dc.FillRgn(&rgn0,&brush);
//
DeleteObject(&rgn0);
DeleteObject(&brush);
return;
}
case 1:
start1.x=center.x+innerR; start1.y=center.y-gap;
start2.x=center.x+outerR; start2.y=center.y-gap;
end1.x=center.x+gap; end1.y=center.y-innerR;
end2.x=center.x+gap; end2.y=center.y-outerR;
break;
case 2:
start1.x=center.x-gap; start1.y=center.y-innerR;
start2.x=center.x-gap; start2.y=center.y-outerR;
end1.x=center.x-innerR; end1.y=center.y-gap;
end2.x=center.x-outerR; end2.y=center.y-gap;
break;
case 3:
start1.x=center.x-innerR; start1.y=center.y+gap;
start2.x=center.x-outerR; start2.y=center.y+gap;
end1.x=center.x-gap; end1.y=center.y+innerR;
end2.x=center.x-gap; end2.y=center.y+outerR;
break;
case 4:
start1.x=center.x+gap; start1.y=center.y+innerR;
start2.x=center.x+gap; start2.y=center.y+outerR;
end1.x=center.x+innerR; end1.y=center.y+gap;
end2.x=center.x+outerR; end2.y=center.y+gap;
break;
}
CRect rcInner(center.x-innerR,center.y-innerR,center.x+innerR,center.y+innerR);
CRect rcOuter(center.x-outerR,center.y-outerR,center.x+outerR,center.y+outerR);
dc.BeginPath();
dc.MoveTo(start1.x,start1.y);
dc.LineTo(start2.x,start2.y);
dc.ArcTo(&rcOuter,start2,end2);
dc.LineTo(end1.x,end1.y);
// change dir (is modal)
dc.SetArcDirection(AD_CLOCKWISE);
dc.ArcTo(&rcInner,end1, start1);
// restore dir
dc.SetArcDirection(AD_COUNTERCLOCKWISE);
dc.EndPath();
#if 0
dc.StrokeAndFillPath();
#else
CBrush brush(color);
CRgn rgn;
rgn.CreateFromPath(&dc);
dc.FillRgn(&rgn,&brush);
//
DeleteObject(&rgn);
DeleteObject(&brush);
#endif
}
调用:
在对话框初始化中
else
{
path2rgn(dc,0,RGB(128,128,255));//中心园
path2rgn(dc,1,RGB(255,0,0));// 1 象限
path2rgn(dc,2,RGB(0,255,0))// 2 象限
path2rgn(dc,3,RGB(0,0,255));// 3 象限
path2rgn(dc,4,RGB(255,127,127));// 4 象限
}
BOOL CRgnTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
CRgn rgn1,rgn2;//添加这几行就OK
rgn1.CreateEllipticRgn(0,0,80,80);
rgn2.CreateEllipticRgn(20,20,60,60);
rgn1.CombineRgn(&rgn1,&rgn2,RGN_DIFF);
SetWindowRgn(rgn1,TRUE);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void MyButton::DrawItem(LPDRAWITEMSTRUCT lpDS)
{
CDC dc;
dc.Attach(lpDS->hDC);
CString text;
this->GetWindowText(text);
if(lpDS->itemState & ODS_SELECTED)
color = RGB(255,1,1);
else if(lpDS->itemState & ODS_FOCUS)
color = RGB(1,255,1);
else if(m_hover)
color = RGB(188,50,99);
else
color = RGB(100,100,255);
//
RECT rect = lpDS->rcItem;
CRgn rgn;
rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
int ret=::GetWindowRgn(lpDS->hwndItem,rgn);
dc.SelectClipRgn(&rgn);
#ifdef PATTERN
dc.FillRect(&rect,&m_BackBr);
#else
dc.FillRect(&rect,&CBrush(color));
#endif
DeleteObject(rgn);
//
SetBkMode(lpDS->hDC,TRANSPARENT);
//
HFONT oldFont=(HFONT)dc.SelectObject(m_font);
::DrawText(lpDS->hDC,text, text.GetLength(),&(lpDS->rcItem),DT_CENTER|DT_VCENTER|DT_SINGLELINE);
dc.SelectObject(oldFont);
dc.Detach();
}
注意其中
CRgn rgn;
rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
int ret=::GetWindowRgn(lpDS->hwndItem,rgn);
dc.SelectClipRgn(&rgn);CxSkinButtonDemo 搜索这个源码
int CxButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
rgn.CreateEllipticRgn(0,0,80,80);//CRgn rgn
SetWindowRgn((HRGN)rgn.GetSafeHandle(),TRUE);
hBmp=(HBITMAP)LoadImage(NULL,_T("E:\\资料\\11.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
// rgn.DeleteObject();
return 0;
}
void CxButton::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CWnd::OnPaint()
CRect r;
CDC memDC;
BITMAP bmp;
GetClientRect(&r);
memDC.CreateCompatibleDC(&dc);
GetObject(hBmp, sizeof(bmp),&bmp);
memDC.SelectObject(hBmp);
dc.StretchBlt(0,0,r.Width(),r.Height(),&memDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
}