首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

支援多種交叉形狀的工業控制管道控件實作

     編輯:關於VC++

前言

工業控制系統中,管道控件是模擬現場環境的關鍵元件。市面組態軟體擁有豐富圖形庫可繪製 3D 場景,但自行開發常缺乏此類支援,介面顯得單調。現有開源管道控件多僅支援橫向/縱向,拐角與交叉處理粗糙。本文實作支援 11 種形狀 (4 種拐角、橫向、縱向、5 種交叉) 的管道控件,提升專業度。

繪製原理

管道外觀為圓柱體,視覺上呈現中間亮、兩側暗的漸層效果。參考 Windows 畫圖工具:用筆刷繪製不同顏色直線,顏色漸變可產生「凹凸」視覺效果。管道多為黑白,採用黑白漸層色填充矩形區段即可模擬立體感。

管道視覺效果示意

形狀定義

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;

核心繪製邏輯

在 OnPaint() 依 m_enumFace 分派繪製:

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;
    }
}

區段漸層繪製核心

以 SECTCOUNT 區段數將管道寬度切割,每區段填入對應漸層色 (GetSectColor(i)):

void CPipeCtrl::DrawHorizontal(CDC *pDC, RECT &rectClient)
{
    RECT rcSect;
    CBrush brush, *pOldBrush;
    int nSectWidth = m_nWidth / SECTCOUNT;
    
    for (int i = 0; i < SECTCOUNT; i++)
    {
        brush.CreateSolidBrush(GetSectColor(i));
        pOldBrush = pDC->SelectObject(&brush);
        SetRect(&rcSect, rectClient.left, rectClient.top + i * nSectWidth,
                rectClient.right, rectClient.top + (i + 1) * nSectWidth);
        pDC->FillRect(&rcSect, &brush);
        pDC->SelectObject(pOldBrush);
        brush.DeleteObject();
    }
}

拐角繪製邏輯 (以左上拐角為例)

同時繪製水平與垂直兩段,共用交會區域:

void CPipeCtrl::DrawCornerLeftTop(CDC *pDC, RECT &rectClient)
{
    RECT rcSect;
    CBrush brush, *pOldBrush;
    int nSectWidth = m_nWidth / SECTCOUNT;
    
    for (int i = 0; i < SECTCOUNT; i++)
    {
        brush.CreateSolidBrush(GetSectColor(i));
        pOldBrush = pDC->SelectObject(&brush);
        
        // 水平段
        SetRect(&rcSect, rectClient.left + i * nSectWidth, rectClient.top + i * nSectWidth,
                rectClient.right, rectClient.top + (i + 1) * nSectWidth);
        pDC->FillRect(&rcSect, &brush);
        
        // 垂直段
        SetRect(&rcSect, rectClient.left + i * nSectWidth, rectClient.top + i * nSectWidth,
                rectClient.left + (i + 1) * nSectWidth, rectClient.bottom);
        pDC->FillRect(&rcSect, &brush);
        
        pDC->SelectObject(pOldBrush);
        brush.DeleteObject();
    }
}

中央交叉繪製

計算中心點,繪製水平貫穿條帶與垂直四象限區塊:

void CPipeCtrl::DrawCrossCenter(CDC *pDC, RECT &rectClient)
{
    // ... 計算中心座標 xCenter, yCenter, xLeft, yTop
    // 水平貫穿
    for (int i = 0; i < SECTCOUNT; i++) { /* 填滿整列 */ }
    // 垂直四象限
    for (int i = 0; i <= SECTCOUNT / 2; i++) {
        // 左上、右上、左下、右下四個矩形
    }
}

執行效果

管道控件執行效果

目前固定黑白模式,未提供動態顏色調整。交叉形狀涵蓋基礎需求,歡迎各位改進分享。

聯絡資訊

Email: successq_g@163.com
QQ: 5516853

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved