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

儀表圖表控制項繪圖框架架構設計

     編輯:關於VC++

設計動機

開發儀表、圖表類控制項需處理多樣化圖形:圓形/線性儀表、指針、刻度、標籤、背景玻璃效果、填充樣式 (純色/漸層/圖片)。傳統「功能導向」架構 (如 MS Graph Demo 的 `PieSlice`+`PieGraph`+`PieGraphRenderer`) 導致功能資料與外觀資料耦合,擴充新圖形或填充方式需修改多處。

提出架構:三層分離模型

┌─────────────────────────────────────┐
│        YPaintBase (邏輯組合層)       │  ← 負責形狀組合、座標轉換、繪製順序
├─────────────────────────────────────┤
│        YShapeBase (幾何形狀層)       │  ← 圓、矩形、三角形、扇形、指針樣式...
├─────────────────────────────────────┤
│        YFillBase (填充樣式層)        │  ← 純色、漸層、圖片、材質、邊框...
└─────────────────────────────────────┘

核心原則:形狀不關心填充,填充不關心形狀,邏輯負責組合兩者。

基底類別設計


// 填充基底
class YFillBase {
public:
    virtual void Draw(CDC* pDC, CRect bounds) = 0;
    YPen m_pen;           // 邊框
    YBrush m_brush;       // 填充
};

// 形狀基底
class YShapeBase {
public:
    YFillBase* m_pFill = nullptr;
    void SetFill(YFillBase* pFill) { m_pFill = pFill; }
    virtual void Draw(CDC* pDC) { 
        if (m_pFill) m_pFill->Draw(pDC, GetBounds()); 
    }
    virtual CRect GetBounds() = 0;
};

// 邏輯組合基底
class YPaintBase {
public:
    virtual void Draw(CDC* pDC) = 0;
    // 組合多個 YShapeBase,處理座標系、旋轉、縮放
};

具體實作範例

1. 形狀與填充自由組合


// 矩形指針 + 漸層填充
YRectangle* pRect = new YRectangle;
YFillGradient* pGrad = new YFillGradient;
pGrad->SetColors(RGB(255,0,0), RGB(255,255,0));
pGrad->SetGradientType(GRADIENT_HORIZONTAL);
pRect->SetFill(pGrad);
pRect->Draw(pDC); // 自動套用漸層填充

// 同一填充套用到圓形背景
YEllipse* pCircle = new YEllipse;
pCircle->SetFill(pGrad); // 共用填充物件
pCircle->Draw(pDC);

2. 新增三角形形狀,自動獲得所有填充能力


class YTriangle : public YShapeBase {
    CPoint m_pts[3];
    CRect GetBounds() override { /* 計算外接矩形 */ }
    // 無需修改任何填充類別
};
// 立即可用:三角形指針、三角形背景、三角形刻度...

3. 新增圖片填充,所有形狀自動支援材質貼圖


class YFillImage : public YFillBase {
    CImage m_image;
    void Draw(CDC* pDC, CRect rc) override {
        m_image.Draw(pDC->m_hDC, rc, /* 重複/拉伸模式 */);
    }
};
// 立即可用:圖片填充指針、圖片背景、圖片刻度...

儀表控制項構建示範

透明玻璃表蓋


YFillGradient glassFill;
glassFill.Border.Hide();
glassFill.Background.SetGradient(
    YColor(20, 240,240,240), YColor(180, 120,120,120),
    GRADIENT_FORWARD_DIAGONAL);
YEllipse glassBg; glassBg.SetFill(&glassFill); glassBg.Draw(pDC);

// 高光反射 (兩條弧形區域)
YFillGradient lightFill;
lightFill.Border.Hide();
lightFill.Background.SetSolid(YColor(210, 255,255,255));
YRange range; range.SetFill(&lightFill);
range.SetSweepAngle(24); range.SetPlacement(INSIDE);
range.SetStartAngle(110); range.Draw(pDC);
range.SetStartAngle(136); range.Draw(pDC);

彈性刻度系統


// 環形刻度 + 環繞文字
YScaleCircular scale; scale.SetRadius(80); scale.SetRange(0, 100);
YScaleTextCircular labels;
labels.AddTextHelper(10, RGB(128,128,128)); // 一般刻度
labels.AddTextHelper(12, RGB(255,44,44), TRUE, "黑體"); // 主刻度
labels.AddText("你"); labels.AddText("有沒有"); labels.AddText("想過");
labels.SetType(TEXT_INWARD); // 向心文字
labels.SetOrigin(cx, cy); labels.SetRadius(60);
labels.Draw(pDC);

// 線性刻度 + 傾斜文字
YScaleXY hScale; hScale.SetLength(380); hScale.SetRange(0, 600);
YScaleTextXY hLabels;
hLabels.AddTextHelper(8.5, -30, ALIGN_RIGHT); // -30度傾斜
hLabels.AddText("一月"); hLabels.AddText("二月")...;
hLabels.Draw(pDC);

架構優勢總結

需求變更傳統架構本框架
新增形狀 (五角星)修改 Slice、Graph、Renderer僅新增 YStar : YShapeBase
新增填充 (材質圖)修改所有 Slice 類別僅新增 YFillTexture : YFillBase
圓餅圖轉長條圖重寫整個繪製管線替換 YPaintBase 組合邏輯
程式碼複用度低極高 (N形狀 × M填充)

Demo 專案結構


GaugeFramework/
├── Core/
│   ├── YFillBase.h/cpp       // 填充體系
│   ├── YShapeBase.h/cpp      // 形狀體系
│   └── YPaintBase.h/cpp      // 組合邏輯
├── Shapes/
│   ├── YEllipse, YRectangle, YTriangle, YRange, YStar...
├── Fills/
│   ├── YFillSolid, YFillGradient, YFillImage, YFillHatch...
├── Paints/
│   ├── YGaugeCircular, YGaugeLinear, YChartPie, YChartBar...
└── DemoApp/                  // MFC 對話式測試程式
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved