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

MFC 靜態控件 CStatic 完整開發指南:文本/圖標/位圖顯示、對齊樣式與動態圖片加載

     編輯:關於C語言

靜態控件功能簡單但用途極廣:顯示標籤、分組框、圖標、位圖、分隔線、動畫等。MFC CStatic 封裝文本/圖像顯示、對齊樣式、前綴轉義控制及圖片資源動態加載。本文系統講解全風格、三種顯示模式切換、動態圖片加載代碼模板。

一、 創建與風格大全

BOOL Create(LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff);

文本對齊風格(互斥)

風格效果
SS_LEFT左對齊 (默認)
SS_CENTER居中對齊
SS_RIGHT右對齊
SS_NOPREFIX禁用 & 加速鍵前綴轉義 (直接顯示 &)

顯示模式風格(核心,決定內容類型)

風格顯示內容配置方式典型用途
SS_LEFT/CENTER/RIGHT (無圖像風格)文本SetWindowText標籤、提示、數值顯示
SS_BITMAP位圖SetBitmap(HBITMAP)Logo、圖片預覽、狀態圖標
SS_ICON圖標SetIcon(HICON)應用圖標、文件類型圖標
SS_GRAYRECT灰色矩形框無需配置分組視覺分隔
SS_BLACKRECT黑色矩形框無需配置分隔線、邊框
SS_WHITERECT白色矩形框無需配置背景遮罩
SS_ETCHEDHORZ蝕刻水平線無需配置3D 分隔線
SS_ETCHEDVERT蝕刻垂直線無需配置3D 分隔線
SS_CENTERIMAGE圖像居中顯示 (配合 BITMAP/ICON)自動居中,不拉伸固定尺寸框內顯示不同尺寸圖片
SS_REALSIZECONTROL按實際尺寸顯示 (不拉伸)配合 BITMAP/ICON保持原始比例
SS_SUNKEN凹陷邊框配合文本/圖像輸入框風格標籤

二、 三大核心顯示模式操作

1. 文本模式 (默認)

// 設置文本
m_static.SetWindowText(_T("Hello World"));

// 獲取文本
CString text;
m_static.GetWindowText(text);

// 動態修改對齊 (需重繪)
m_static.ModifyStyle(SS_LEFT, SS_CENTER);
m_static.Invalidate();

2. 圖標模式 (SS_ICON)

// 從資源加載
HICON hIcon = AfxGetApp()->LoadIcon(IDI_MYICON);
m_static.SetIcon(hIcon);

// 獲取當前圖標
HICON hCur = m_static.GetIcon();

// 釋放資源 (若手動 LoadImage)
DestroyIcon(hIcon);

3. 位圖模式 (SS_BITMAP) - 最常用

// 動態加載位圖資源並顯示 (完整代碼模板)
void CMyDialog::ShowBitmap(UINT nBitmapID) {
    // 1. 確保風格包含 SS_BITMAP | SS_CENTERIMAGE
    m_static.ModifyStyle(0, SS_BITMAP | SS_CENTERIMAGE);
    
    // 2. 加載位圖對象
    CBitmap bmp;
    if (!bmp.LoadBitmap(nBitmapID)) {
        AfxMessageBox(_T("位圖加載失敗"));
        return;
    }
    
    // 3. 設置位圖 (Detach 轉移所有權給靜態控件)
    HBITMAP hOld = m_static.SetBitmap(bmp.Detach());
    
    // 4. 釋放舊位圖 (防止內存洩漏)
    if (hOld) DeleteObject(hOld);
    
    // 5. 強制重繪
    m_static.Invalidate();
}

三、 圖片資源加載進階

從文件加載 (非資源)

void LoadBitmapFromFile(LPCTSTR pszPath) {
    // 1. 使用 LoadImage 從文件加載
    HBITMAP hBmp = (HBITMAP)LoadImage(NULL, pszPath, IMAGE_BITMAP, 0, 0, 
                                      LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    if (!hBmp) return;
    
    // 2. 設置並管理生命週期
    HBITMAP hOld = m_static.SetBitmap(hBmp);
    if (hOld) DeleteObject(hOld);
    
    // 注意:此處 hBmp 所有權已轉移,對話框銷毀時需手動 DeleteObject
    // 建議成員變量保存 hBmp,在 OnDestroy 中釋放
}

運行時創建位圖 (雙緩衝繪製)

void CreateDynamicBitmap(int width, int height) {
    CClientDC dc(&m_static);
    CDC memDC;
    memDC.CreateCompatibleDC(&dc);
    
    CBitmap bmp;
    bmp.CreateCompatibleBitmap(&dc, width, height);
    CBitmap* pOld = memDC.SelectObject(&bmp);
    
    // 在 memDC 上繪圖...
    memDC.FillSolidRect(0, 0, width, height, RGB(255,255,255));
    memDC.TextOut(10, 10, _T("動態生成"));
    
    memDC.SelectObject(pOld);
    
    // 設置顯示
    HBITMAP hOld = m_static.SetBitmap(bmp.Detach());
    if (hOld) DeleteObject(hOld);
}

四、 常見問題與避坑指南

  1. 位圖不顯示/顯示異常:
    • 檢查風格是否包含 SS_BITMAP
    • 確認 SetBitmap 參數為有效 HBITMAP
    • 調用 Invalidate() 觸發重繪
  2. 圖片拉伸變形:添加 SS_CENTERIMAGE (居中不拉伸) 或 SS_REALSIZECONTROL (實際尺寸)
  3. 內存洩漏:SetBitmap 返回舊 HBITMAP 必須 DeleteObject;LoadImage 加載的位圖所有權轉移後需在銷毀時釋放
  4. 圖標與位圖互斥:同一控件同一時間只能顯示文本/圖標/位圖之一,切換需 ModifyStyle 移除舊風格
  5. 高 DPI 模糊:使用 LR_CREATEDIBSECTION 加載位圖,或改用 CImage/GDI+ 支持縮放
  6. 動態文本截斷:控件矩形過小,調整 rect 或啟用 SS_ENDELLIPSIS (需 WinXP+)

五、 實戰場景:狀態指示燈面板

class CStatusPanel {
    CStatic m_leds[4]; // 紅/黃/綠/藍
    CBitmap m_bmpOn[4], m_bmpOff[4];
    
public:
    void Init(CWnd* pParent, UINT baseID) {
        for (int i = 0; i < 4; ++i) {
            m_leds[i].Create(_T(""), WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_CENTERIMAGE,
                           CRect(10+i*30, 10, 35+i*30, 35), pParent, baseID+i);
            m_bmpOn[i].LoadBitmap(IDB_LED_RED_ON + i);
            m_bmpOff[i].LoadBitmap(IDB_LED_RED_OFF + i);
            SetLed(i, FALSE);
        }
    }
    
    void SetLed(int index, BOOL on) {
        m_leds[index].SetBitmap((on ? m_bmpOn[index] : m_bmpOff[index]).Detach());
        m_leds[index].Invalidate();
    }
};

本文整理自 MFC 經典技術文檔,適用於 VC6~VS2022 所有版本。

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