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

在樹狀控件中實現鼠標懸停時的字體與顏色動態變化

     編輯:關於VC++

在 Windows XP 的資源管理器左側目錄樹中,當滑鼠游標移動到某個項目上時,該項目標籤的字體與顏色會發生變化,使選擇目標更加醒目。本文介紹如何在基於 MFC 的 CTreeCtrl 控件衍生類 CDirTreeCtrl 中實現類似效果。核心思路是:重載滑鼠移動訊息 (WM_MOUSEMOVE) 以偵測游標是否進入項目標籤區域,並記錄需變更的顏色與字體屬性;再重載繪製訊息 (WM_PAINT),在裝置環境中建立帶有底線屬性的邏輯字體,並以設定的顏色重繪項目文字。

關鍵資料成員定義

在 CDirTreeCtrl 的標頭檔中宣告以下變數:

HTREEITEM hItem_bc;                   // 記錄目前游標所在的項目控制代碼
COLORREF ItemText_OldColor;           // 系統預設項目文字顏色,於初始化時取得
LOGFONT logfont_old;                  // 系統預設邏輯字體屬性,於初始化時取得

struct Color_Font {
    COLORREF color;
    LOGFONT logfont;
};

// 以項目控制代碼為鍵,儲存對應的顏色與字體設定
CMap<void*, void*, Color_Font, Color_Font&> m_mapColorFont;

重載 OnMouseMove:偵測游標進入與離開

void CDirTreeCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
    CRect rc;
    TVHITTESTINFO tvInfo;
    tvInfo.pt = point;
    HTREEITEM hItem = HitTest(&tvInfo);        // 取得游標下的項目控制代碼
    GetItemRect(hItem, &rc, TRUE);
    BOOL yn = rc.PtInRect(point);              // 判斷游標是否在項目標籤矩形內

    Color_Font cf;
    if (yn) {                                  // 游標進入項目標籤
        cf.color = RGB(0, 0, 150);             // 設定高亮顏色(深藍)
        SetCursor(hIcon_sx);                   // 切換為手型游標
        hItem_bc = hItem;
    } else {                                   // 游標離開
        cf.color = ItemText_OldColor;          // 恢復預設顏色
    }
    m_mapColorFont[hItem] = cf;                // 更新對應項目的顏色/字體記錄
    Invalidate(FALSE);                         // 觸發重繪
    CTreeCtrl::OnMouseMove(nFlags, point);
}

重載 OnPaint:自訂繪製高亮項目

void CDirTreeCtrl::OnPaint()
{
    CPaintDC dc(this);
    CDC memDC;
    memDC.CreateCompatibleDC(&dc);
    CRect rcClip, rcClient;
    dc.GetClipBox(&rcClip);
    GetClientRect(&rcClient);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
    memDC.SelectObject(&bitmap);

    // 讓預設繪製流程先在記憶體 DC 上執行
    CWnd::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0);

    if (hItem_bc != NULL) {
        CRect rect;
        UINT selflog = TVIS_DROPHILITED | TVIS_SELECTED;
        Color_Font cf;
        // 若項目非拖放高亮也非選中狀態,且有自訂字體記錄
        if (!(GetItemState(hItem_bc, selflog) & selflog) && m_mapColorFont.Lookup(hItem_bc, cf)) {
            CFont fontDC;
            LOGFONT logfont = logfont_old;
            logfont.lfUnderline = TRUE;                // 加底線
            fontDC.CreateFontIndirect(&logfont);
            CFont* pOldFont = memDC.SelectObject(&fontDC);
            memDC.SetTextColor(cf.color);
            CString sItem = GetItemText(hItem_bc);
            GetItemRect(hItem_bc, &rect, TRUE);
            memDC.TextOut(rect.left + 2, rect.top + 2, sItem); // 繪製文字
            memDC.SelectObject(pOldFont);
            fontDC.DeleteObject();
        }
    }
    // 將記憶體 DC 內容複製到螢幕 DC
    dc.BitBlt(rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(),
              &memDC, rcClip.left, rcClip.top, SRCCOPY);
    bitmap.DeleteObject();
    hItem_bc = NULL;  // 重置
}

透過雙重緩衝繪製與字體屬性的動態切換,即可在樹狀控件中實現類似 Windows XP 資源管理器的項目高亮效果,提升使用者介面的視覺回饋。

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