一个支持各种交叉等形状工业控制管道控件的实现
2008-08-09 19:26:05 来源:WEB开发网上图所示的我们可以得到是一种能够类似横向管道的控件绘制的方法,那么同样道理,我们可以这样得到纵向管道的控件的绘制方法。当时在拐角的实现中,我们要进行一些别的处理。很多时候我们看到一些师傅进行实体连接的时候,当进行管道拐角的时候,需要将两根管道在接口处进行鞋45度的切割,然后就实现了不同管道的交叉了。我们可以这种方法进行交叉的处理就可以了。相信可以见后面的代码实现。
通过对管道的分析,大致可以得到管道的一些通用的形状,大概氛围下面11种情况,左上的拐角、右上的拐角、右下的拐角、左下的拐角、竖向、横向、中央交叉、左边交叉、顶边交叉、上部交叉、底边交叉。通过设置控件的属性进行不同形状的绘制工作。我们可以在这里进行形状的大致抽象//管道的形状
下面就是我们管道的绘制工作了,触发WM_PAINT消息完成绘制工作。
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;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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; 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();
}
//绘制竖向
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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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; i<SECTCOUNT; i++)
{
pBackBrush.CreateSolidBrush(GetSectColor(i));
pOldBrush = (CBrush *)pDC->SelectObject(&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();
}
}
由于时间关系,这里控件就固定采用了黑白的模式,没有提供颜色动态修改等方法,然后控件的交叉大致实现了基本的各种交叉,可能还有一些别的形状等。各位如有好的实现方法请完成实现并共享您的经验。
您可以和我联系:
successq_g@163.com
QQ:5516853
正文完
更多精彩
赞助商链接