从网上下了个CPolyBtn 修改成三角形(向右的三角形 像这个样子 |> ) 目前能画出来但是按它的时候有问题。在三角形区域不一定能够触发OnMouseMove,而在三角形周围却能触发该事件。 std::vector<CEdge> m_edges;
POINT * m_pPoints; struct CEdge
{
CPoint start, end;
COLORREF clr;
COLORREF downclr;
COLORREF focusclr;
COLORREF disabledclr;
COLORREF rolloverclr;
};
void CPolyBtn::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW); if (m_edges.size()==0)
{
ASSERT(0);
}
else
{
m_rgn.DeleteObject();
SetWindowRgn(NULL, FALSE); m_pPoints = new POINT[m_edges.size()];
for (int i=0;i<m_edges.size();i++)
{
m_pPoints[i] = m_edges.at(i).start;
if (i>0)
{
ASSERT(m_edges.at(i-1).end == m_edges.at(i).start);
}
}
m_rgnWnd.CreateRectRgn(0,0,0,0); // couldn't find a way to expand a region. so, we'll
// offset the region in 8 directions and combine the
// results. yes, this is a hack. CRgn temp;
temp.CreatePolygonRgn(m_pPoints, m_edges.size(), ALTERNATE);
m_rgnWnd.CopyRgn( &temp ); temp.OffsetRgn(-1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(0,1);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(0,-1);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(0,-1);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(-1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(-1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION); // once you use a region in SetWindowRgn, you're not allowed to do *anything* else with it
// so, we'll make a copy.
m_rgn.CreateRectRgn(0,0,0,0);
m_rgn.CopyRgn(&m_rgnWnd); SetWindowRgn(m_rgnWnd, TRUE);
}
CButton::PreSubclassWindow();
}void CPolyBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{ CRect rect = lpDrawItemStruct->rcItem; CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
UINT state = lpDrawItemStruct->itemState;
UINT nStyle = GetStyle(); int nSavedDC = pDC->SaveDC(); CBrush br;
br.CreateSolidBrush(m_clrFill); // fill interior
pDC->SetPolyFillMode(ALTERNATE);
CBrush *ob = pDC->SelectObject(&br);
pDC->Polygon(m_pPoints, m_edges.size());
pDC->SelectObject(ob); pDC->SelectClipRgn(&m_rgn);
// // paint the edges
for (int i=0;i<m_edges.size();i++)
{
int iPenStyle = PS_SOLID;
COLORREF clr = m_edges.at(i).clr; if ((state & ODS_SELECTED))
{
clr = m_edges.at(i).downclr;
}
else if ((state & ODS_FOCUS))
{
if (m_bMouseOnButton)
{
clr = m_edges.at(i).rolloverclr;
}
else
{
iPenStyle = PS_DOT;
}
}
else if ((state & ODS_DISABLED))
{
clr = m_edges.at(i).disabledclr;
}
else if (m_bMouseOnButton)
{
clr = m_edges.at(i).rolloverclr;
} CPen pen(iPenStyle, 1, clr);
CPen *opp = pDC->SelectObject(&pen); pDC->MoveTo(m_edges.at(i).start);
TRACE("第%d条线 开始 x = %d , y = %d\n", i, m_edges.at(i).start.x, m_edges.at(i).start.y );
pDC->LineTo(m_edges.at(i).end);
TRACE("第%d条线 结束 x = %d , y = %d\n", i, m_edges.at(i).end.x, m_edges.at(i).end.y );
pDC->SelectObject(opp);
} pDC->SelectClipRgn(NULL);
pDC->RestoreDC(nSavedDC);
}
POINT * m_pPoints; struct CEdge
{
CPoint start, end;
COLORREF clr;
COLORREF downclr;
COLORREF focusclr;
COLORREF disabledclr;
COLORREF rolloverclr;
};
void CPolyBtn::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW); if (m_edges.size()==0)
{
ASSERT(0);
}
else
{
m_rgn.DeleteObject();
SetWindowRgn(NULL, FALSE); m_pPoints = new POINT[m_edges.size()];
for (int i=0;i<m_edges.size();i++)
{
m_pPoints[i] = m_edges.at(i).start;
if (i>0)
{
ASSERT(m_edges.at(i-1).end == m_edges.at(i).start);
}
}
m_rgnWnd.CreateRectRgn(0,0,0,0); // couldn't find a way to expand a region. so, we'll
// offset the region in 8 directions and combine the
// results. yes, this is a hack. CRgn temp;
temp.CreatePolygonRgn(m_pPoints, m_edges.size(), ALTERNATE);
m_rgnWnd.CopyRgn( &temp ); temp.OffsetRgn(-1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(0,1);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(0,-1);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(0,-1);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(-1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION);
temp.OffsetRgn(-1,0);
m_rgnWnd.CombineRgn(&temp, &m_rgnWnd, SIMPLEREGION); // once you use a region in SetWindowRgn, you're not allowed to do *anything* else with it
// so, we'll make a copy.
m_rgn.CreateRectRgn(0,0,0,0);
m_rgn.CopyRgn(&m_rgnWnd); SetWindowRgn(m_rgnWnd, TRUE);
}
CButton::PreSubclassWindow();
}void CPolyBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{ CRect rect = lpDrawItemStruct->rcItem; CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
UINT state = lpDrawItemStruct->itemState;
UINT nStyle = GetStyle(); int nSavedDC = pDC->SaveDC(); CBrush br;
br.CreateSolidBrush(m_clrFill); // fill interior
pDC->SetPolyFillMode(ALTERNATE);
CBrush *ob = pDC->SelectObject(&br);
pDC->Polygon(m_pPoints, m_edges.size());
pDC->SelectObject(ob); pDC->SelectClipRgn(&m_rgn);
// // paint the edges
for (int i=0;i<m_edges.size();i++)
{
int iPenStyle = PS_SOLID;
COLORREF clr = m_edges.at(i).clr; if ((state & ODS_SELECTED))
{
clr = m_edges.at(i).downclr;
}
else if ((state & ODS_FOCUS))
{
if (m_bMouseOnButton)
{
clr = m_edges.at(i).rolloverclr;
}
else
{
iPenStyle = PS_DOT;
}
}
else if ((state & ODS_DISABLED))
{
clr = m_edges.at(i).disabledclr;
}
else if (m_bMouseOnButton)
{
clr = m_edges.at(i).rolloverclr;
} CPen pen(iPenStyle, 1, clr);
CPen *opp = pDC->SelectObject(&pen); pDC->MoveTo(m_edges.at(i).start);
TRACE("第%d条线 开始 x = %d , y = %d\n", i, m_edges.at(i).start.x, m_edges.at(i).start.y );
pDC->LineTo(m_edges.at(i).end);
TRACE("第%d条线 结束 x = %d , y = %d\n", i, m_edges.at(i).end.x, m_edges.at(i).end.y );
pDC->SelectObject(opp);
} pDC->SelectClipRgn(NULL);
pDC->RestoreDC(nSavedDC);
}
case WM_DRAWITEM :
pdis = (LPDRAWITEMSTRUCT) lParam ;
//用白色填充区域
FillRect (pdis->hDC, &pdis->rcItem,
(HBRUSH) GetStockObject (WHITE_BRUSH)) ; //边框显示为黑色
FrameRect (pdis->hDC, &pdis->rcItem,
(HBRUSH) GetStockObject (BLACK_BRUSH)) ; //将画笔选入指定的设备描述表
SelectObject(pdis->hDC,CreatePen(PS_SOLID,10,255));
else if(pdis->CtlID==IDM_BUTTONFONT)
{
MoveToEx(pdis->hDC,12,12,NULL);
LineTo(pdis->hDC,50,12);
MoveToEx(pdis->hDC,50,12,NULL);
LineTo(pdis->hDC,6,25);
MoveToEx(pdis->hDC,6,25,NULL);
LineTo(pdis->hDC,12,12);
}坐标值 你自己计算一下
这就是一个 自绘的按钮
我是用 windows api做的