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

MFC 樹狀控制項 (CTreeCtrl) 設定背景圖片完整實作

     編輯:關於C語言

`CTreeCtrl` 不支援自繪,直接設定背景圖片需繞過繪製流程。核心技巧:將樹狀控制項繪製到記憶體 DC,再透明混合到背景位圖上。本文提供 `CTreeCtrlX` 衍生類完整實作,含位圖載入、調色板建立、WM_ERASEBKGND/WM_PAINT 訊息處理與平鋪/置中顯示選項。

核心步驟

  1. 資源匯入:將 256 色(或 16 色)BMP 匯入專案資源
  2. 成員變數:
    
    protected:
        CPalette m_pal;      // 邏輯調色板
        CBitmap  m_bmp;      // 背景位圖
        int      m_cxBmp, m_cyBmp; // 位圖尺寸
    
  3. 設定背景圖片函數(支援資源 ID 或名稱):
    
    BOOL CTreeCtrlX::SetBkImage(UINT nIDResource) {
        return SetBkImage(MAKEINTRESOURCE(nIDResource));
    }
    
    BOOL CTreeCtrlX::SetBkImage(LPCTSTR lpszResourceName) {
        // 1. 刪除舊 GDI 物件
        if (m_bmp.m_hObject) m_bmp.DeleteObject();
        if (m_pal.m_hObject) m_pal.DeleteObject();
    
        // 2. 載入 DIBSECTION 以取得色彩表
        HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
            lpszResourceName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
        if (!hBmp) return FALSE;
    
        m_bmp.Attach(hBmp);
        BITMAP bm; m_bmp.GetBitmap(&bm);
        m_cxBmp = bm.bmWidth; m_cyBmp = bm.bmHeight;
    
        // 3. 建立邏輯調色板(256 色以下)
        if (bm.bmBitsPixel <= 8) {
            int nColors = 1 << bm.bmBitsPixel;
            RGBQUAD* pRGB = new RGBQUAD[nColors];
            ::GetDIBColorTable(m_bmp.GetSafeHandle(), 0, nColors, pRGB);
    
            LOGPALETTE* pLP = (LOGPALETTE*)new BYTE[sizeof(LOGPALETTE) + nColors * sizeof(PALETTEENTRY)];
            pLP->palVersion = 0x300;
            pLP->palNumEntries = nColors;
            for (int i = 0; i < nColors; i++) {
                pLP->palPalEntry[i].peRed   = pRGB[i].rgbRed;
                pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
                pLP->palPalEntry[i].peBlue  = pRGB[i].rgbBlue;
                pLP->palPalEntry[i].peFlags = 0;
            }
            m_pal.CreatePalette(pLP);
            delete[] pLP; delete[] pRGB;
        }
        Invalidate(); // 觸發重繪
        return TRUE;
    }
    
  4. 訊息處理:
    
    // 擦除背景:不做任何事,防止閃爍
    BOOL CTreeCtrlX::OnEraseBkgnd(CDC* pDC) { return TRUE; }
    
    // 繪製:先畫背景,再呼叫預設繪製
    void CTreeCtrlX::OnPaint() {
        CPaintDC dc(this);
        CDC memDC; memDC.CreateCompatibleDC(&dc);
        CBitmap* pOldBmp = memDC.SelectObject(&m_bmp);
    
        // 取得用戶區大小
        CRect rect; GetClientRect(&rect);
    
        // 平鋪繪製背景
        for (int y = 0; y < rect.Height(); y += m_cyBmp)
            for (int x = 0; x < rect.Width(); x += m_cxBmp)
                dc.BitBlt(x, y, m_cxBmp, m_cyBmp, &memDC, 0, 0, SRCCOPY);
    
        memDC.SelectObject(pOldBmp);
    
        // 關鍵:呼叫預設繪製讓節點/文字覆蓋在背景上
        Default(); // 或 CTreeCtrl::OnPaint()
    }
    

使用方式


// 在對話框 OnInitDialog 或 View OnInitialUpdate 中
m_tree.SetBkImage(IDB_MY_BACKGROUND); // IDB_ 為位圖資源 ID

注意事項

  • 調色板建立僅針對 8-bit (256 色) 以下位圖;真彩色位圖無需調色板
  • `LR_CREATEDIBSECTION` 確保取得 DIB 區塊以讀取色彩表
  • `OnEraseBkgnd` 返回 `TRUE` 抑制預設擦除,配合 `OnPaint` 手動繪製背景可消除閃爍
  • 若需置中而非平鋪,修改 `OnPaint` 中迴圈邏輯即可
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved