分类: C/C++
2008-08-01 17:11:39

//管道的形状
typedef enum _PipeFace
{
PF_CORNER_LEFT_TOP = 0, //左上的拐角
PF_CORNER_RIGHT_TOP = 2, //右上的拐角
PF_CORNER_RIGHT_BOTTOM = 3, //右下的拐角
PF_CORNER_LEFT_BOTTOM = 4, //左下的拐角
PF_VERTICAL = 5, //竖向
PF_HORIZONTAL = 6, //横向
PF_CROSS_CENTER = 7, //中央交叉
PF_CROSS_LEFT = 8, //左边交叉
PF_CROSS_TOP = 9, //顶边交叉
PF_CROSS_RIGHT = 10, //上边交叉
PF_CROSS_BOTTOM = 11 //底边交叉
}PIPEFACE;
下面就是我们管道的绘制工作了,触发WM_PAINT消息完成绘制工作。void CPipeCtrl::OnPaint()
{
CPaintDC dc(this);
RECT rcClient;
GetClientRect(&rcClient);
switch (m_enumFace)
{
case PF_HORIZONTAL:
DrawHorizontal(&dc, rcClient);
break;
case PF_VERTICAL:
DrawVertical(&dc, rcClient);
break;
case PF_CORNER_LEFT_TOP:
DrawCornerLeftTop(&dc, rcClient);
break;
case PF_CORNER_RIGHT_TOP:
DrawCornerRightTop(&dc, rcClient);
break;
case PF_CORNER_RIGHT_BOTTOM:
DrawCornerRightBottom(&dc, rcClient);
break;
case PF_CORNER_LEFT_BOTTOM:
DrawCornerLeftBottom(&dc, rcClient);
break;
case PF_CROSS_CENTER:
DrawCrossCenter(&dc, rcClient);
break;
case PF_CROSS_TOP:
DrawCrossTop(&dc, rcClient);
break;
case PF_CROSS_RIGHT:
DrawCrossRight(&dc, rcClient);
break;
case PF_CROSS_BOTTOM:
DrawCrossBottom(&dc, rcClient);
break;
case PF_CROSS_LEFT:
DrawCrossLeft(&dc, rcClient);
break;
}
}
下面是关于管道的详细绘制方法代码,属于这个控件绘制的核心部分void CPipeCtrl::DrawHorizontal(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
for (int i=0; i < SECTCOUNT; i )
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.left, rectClient.top i * nSectWidth,
rectClient.right, rectClient.top (i 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawVertical(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
for (int i=0; iSelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.left i * nSectWidth, rectClient.top,
rectClient.left (i 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCornerLeftTop(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
for (int i=0; iSelectObject(&pBackBrush);
//绘制横向
SetRect(&rcSect, rectClient.left i * nSectWidth, rectClient.top i * nSectWidth,
rectClient.right, rectClient.top (i 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//绘制竖向
SetRect(&rcSect, rectClient.left i * nSectWidth, rectClient.top i * nSectWidth,
rectClient.left (i 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCornerRightBottom(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
for (int i=0; iSelectObject(&pBackBrush);
//绘制横向
SetRect(&rcSect, rectClient.left, rectClient.bottom - (SECTCOUNT - i) * nSectWidth,
rectClient.right - (SECTCOUNT - i) * nSectWidth, rectClient.bottom - (SECTCOUNT - i - 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//绘制竖向
SetRect(&rcSect, rectClient.right - (SECTCOUNT - i) * nSectWidth, rectClient.top,
rectClient.right - (SECTCOUNT - i - 1) * nSectWidth, rectClient.bottom - (SECTCOUNT - i - 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCornerRightTop(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
for (int i=0; iSelectObject(&pBackBrush);
//绘制横向
SetRect(&rcSect, rectClient.left, rectClient.top i * nSectWidth,
rectClient.right - i * nSectWidth, rectClient.top (i 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//绘制竖向
SetRect(&rcSect, rectClient.right - (SECTCOUNT -i) * nSectWidth, rectClient.top (SECTCOUNT - i) * nSectWidth,
rectClient.right - (SECTCOUNT - i - 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCornerLeftBottom(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
for (int i=0; iSelectObject(&pBackBrush);
//绘制横向
SetRect(&rcSect, rectClient.left (SECTCOUNT - i) * nSectWidth, rectClient.bottom - (SECTCOUNT - i) * nSectWidth,
rectClient.right, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
//绘制竖向
SetRect(&rcSect, rectClient.left i * nSectWidth, rectClient.top,
rectClient.left (i 1) * nSectWidth, rectClient.bottom - i * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCrossCenter(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
int xCenter = rectClient.left (rectClient.right - rectClient.left) / 2;
int yCenter = rectClient.top (rectClient.bottom - rectClient.top) / 2;
int xLeft = xCenter - SECTCOUNT * nSectWidth / 2;
int yTop = yCenter - SECTCOUNT * nSectWidth / 2;
//绘制横向
for (int i=0; iSelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.left, yTop i * nSectWidth,
rectClient.right, yTop (i 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
//绘制竖向
for (i=0; i<=SECTCOUNT / 2; i )
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
//上左
SetRect(&rcSect, xLeft i * nSectWidth, rectClient.top,
xLeft (i 1) * nSectWidth, yTop i * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//上右
SetRect(&rcSect, xLeft (SECTCOUNT - i -1) * nSectWidth, rectClient.top,
xLeft (SECTCOUNT - i) * nSectWidth, yTop i * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//下左
SetRect(&rcSect, xLeft i * nSectWidth, yTop (SECTCOUNT - i) * nSectWidth,
xLeft (i 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
//下右
SetRect(&rcSect, xLeft (SECTCOUNT - i -1) * nSectWidth, yTop (SECTCOUNT - i) * nSectWidth,
xLeft (SECTCOUNT - i) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCrossTop(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
int xCenter = rectClient.left (rectClient.right - rectClient.left) / 2;
//绘制横向
for (int i=0; iSelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.left, rectClient.top i * nSectWidth,
rectClient.right, rectClient.top (i 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
//绘制竖向
int xLeft = xCenter - SECTCOUNT * nSectWidth / 2;
for (i=0; i<=SECTCOUNT / 2; i )
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
//下左
SetRect(&rcSect, xLeft i * nSectWidth, rectClient.top (SECTCOUNT - i) * nSectWidth,
xLeft (i 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
//下右
SetRect(&rcSect, xLeft (SECTCOUNT - i - 1) * nSectWidth, rectClient.top (SECTCOUNT - i) * nSectWidth,
xLeft (SECTCOUNT - i) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCrossRight(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
int yCenter = rectClient.top (rectClient.bottom - rectClient.top) / 2;
//绘制竖向
for (int i=0; iSelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.right - (SECTCOUNT - i) * nSectWidth, rectClient.top,
rectClient.right - (SECTCOUNT - i - 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
//绘制横向
int yTop = yCenter - SECTCOUNT * nSectWidth / 2;
for (i=0; i<=SECTCOUNT / 2; i )
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
//上
SetRect(&rcSect, rectClient.left, yTop i * nSectWidth,
rectClient.right - (SECTCOUNT - i) * nSectWidth, yTop (SECTCOUNT - i - 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//下
SetRect(&rcSect, rectClient.left, yTop (SECTCOUNT - i) * nSectWidth,
rectClient.right - (SECTCOUNT - i) * nSectWidth, yTop (SECTCOUNT - i - 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCrossBottom(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
int xCenter = rectClient.left (rectClient.right - rectClient.left) / 2;
//绘制横向
for (int i=0; iSelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.left, rectClient.bottom - (i 1) * nSectWidth,
rectClient.right, rectClient.bottom - i * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
//绘制竖向
int xLeft = xCenter - SECTCOUNT * nSectWidth / 2;
for (i=0; i<=SECTCOUNT / 2; i )
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
//下左
SetRect(&rcSect, xLeft i * nSectWidth, rectClient.top,
xLeft (i 1) * nSectWidth, rectClient.bottom - (SECTCOUNT - i) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//下右
SetRect(&rcSect, xLeft (SECTCOUNT - i - 1) * nSectWidth, rectClient.top,
xLeft (SECTCOUNT - i) * nSectWidth, rectClient.bottom - (SECTCOUNT - i) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
}
void CPipeCtrl::DrawCrossLeft(CDC *pDC, RECT &rectClient)
{
RECT rcSect;
CBrush pBackBrush, *pOldBrush;
int nSectWidth = m_nWidth / SECTCOUNT;
int yCenter = rectClient.top (rectClient.bottom - rectClient.top) / 2;
//绘制竖向
for (int i=0; iSelectObject(&pBackBrush);
SetRect(&rcSect, rectClient.left (SECTCOUNT - i) * nSectWidth, rectClient.top,
rectClient.left (SECTCOUNT - i 1) * nSectWidth, rectClient.bottom);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
//绘制横向
int yTop = yCenter - SECTCOUNT * nSectWidth / 2;
for (i=0; i<=SECTCOUNT / 2; i )
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&pBackBrush);
//上
SetRect(&rcSect, rectClient.left (SECTCOUNT - i) * nSectWidth, yTop i * nSectWidth,
rectClient.right, yTop (SECTCOUNT - i - 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
//下
SetRect(&rcSect, rectClient.left (SECTCOUNT - i) * nSectWidth, yTop (SECTCOUNT - i) * nSectWidth,
rectClient.right, yTop (SECTCOUNT - i - 1) * nSectWidth);
pDC->FillRect(&rcSect, &pBackBrush);
pDC->SelectObject(pOldBrush);
pBackBrush.DeleteObject();
}
} 到这里,我们的定义的各种形状就绘制完毕了,编译控件运行,我们可以看到下面的效果: