首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 中實現類似 SQL Server 服務管理器的交通燈控件(紅黃綠三狀態)

     編輯:程式設計疑難解答

需求分析

需要一個 MFC 控件,顯示紅/黃/綠三種狀態,類似 SQL Server 服務管理器圖標,支持屬性設置狀態,比 CheckBox 模擬更美觀。

解決方案對比

方案一:自繪按鈕/靜態控件(推薦,輕量)

  1. 派生 CButton 或 CStatic,重寫 DrawItem(Owner Draw)或 OnPaint。
  2. 定義枚舉狀態:enum State { Red, Yellow, Green };。
  3. 根據狀態繪製圓形燈體,支持高亮/陰影效果。
  4. 提供 SetState(State) 方法,內部調用 Invalidate() 觸發重繪。

關鍵代碼片段

// TrafficLightCtrl.h
class CTrafficLightCtrl : public CButton {
    DECLARE_DYNAMIC(CTrafficLightCtrl)
public:
    enum LightState { RED, YELLOW, GREEN };
    void SetState(LightState state) { m_state = state; Invalidate(); }
protected:
    DECLARE_MESSAGE_MAP()
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    LightState m_state = RED;
};

// TrafficLightCtrl.cpp
void CTrafficLightCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS) {
    CDC* pDC = CDC::FromHandle(lpDIS->hDC);
    CRect rect = lpDIS->rcItem;
    // 計算圓心、半徑
    CPoint center(rect.CenterPoint());
    int radius = min(rect.Width(), rect.Height()) / 2 - 2;
    // 選擇顏色
    COLORREF color = (m_state == RED) ? RGB(255,0,0) : 
                     (m_state == YELLOW) ? RGB(255,255,0) : RGB(0,255,0);
    // 繪製立體效果:外框、漸變填充、高光
    CPen pen(PS_SOLID, 1, RGB(100,100,100));
    CBrush brush(color);
    pDC->SelectObject(&pen);
    pDC->SelectObject(&brush);
    pDC->Ellipse(center.x - radius, center.y - radius, center.x + radius, center.y + radius);
    // 可選:添加高光漸變
}

方案二:使用現成開源控件(最快)

參考 CodeProject 等開源項目:

方案三:圖片切換法(最簡單,無縮放失真風險)

  1. 準備三張同尺寸圖片(red.bmp, yellow.bmp, green.bmp)。
  2. 用 CImageList 或 CStatic::SetBitmap 切換。
  3. 支持高 DPI 需提供多倍圖或用矢量繪製(方案一)。

工具欄同步更新

若需同步到工具欄按鈕:

// 主框架中
void CMainFrame::UpdateTrafficLight(CTrafficLightCtrl::LightState state) {
    // 1. 更新自定義控件
    m_wndTrafficLight.SetState(state);
    // 2. 更新工具欄按鈕圖標
    CMFCToolBarImages images;
    images.Load(IDB_TRAFFIC_LIGHT); // 包含三種狀態的圖標條
    m_wndToolBar.GetToolBarCtrl().SetButtonInfo(nID, nID, TBBS_BUTTON, images.ExtractIcon(state));
    m_wndToolBar.Invalidate();
}

總結建議

  1. 輕量自繼承 CButton 重寫 DrawItem:無外部依賴,支持任意縮放、高 DPI、動態效果。
  2. 參考開源代碼快速落地,注意資源釋放(CPen/CBrush 棧上創建自動釋放)。
  3. 工具欄同步用 CImageList 管理多狀態圖標,SetButtonInfo 切換。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved