需要一個 MFC 控件,顯示紅/黃/綠三種狀態,類似 SQL Server 服務管理器圖標,支持屬性設置狀態,比 CheckBox 模擬更美觀。
CButton 或 CStatic,重寫 DrawItem(Owner Draw)或 OnPaint。enum State { Red, Yellow, Green };。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 等開源項目:
MFC LED control、MFC indicator light。CImageList 或 CStatic::SetBitmap 切換。若需同步到工具欄按鈕:
// 主框架中
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();
}
CImageList 管理多狀態圖標,SetButtonInfo 切換。