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

氣球式工具提示:CToolTipWnd 類別實現類似 Windows XP 風格提示視窗

     編輯:關於C語言

動機

標準 CToolTipCtrl 外觀固定 (矩形、黃底黑字),無法自訂形狀 (如氣球尖角)、標題、圖示、自訂顏色。CToolTipWnd 以無框視窗 (WS_POPUP) 手繪氣球外觀,提供豐富視覺效果。

類別介面


class CToolTipWnd : public CWnd {
public:
    BOOL Create(CWnd* pParent); // 建立視窗
    void AddTool(CWnd* pTool, LPCTSTR pszText, COLORREF clrText = RGB(0,0,0)); // 新增工具
    void SetDefTextColor(COLORREF clr); // 設定預設文字顏色
    void RelayEvent(MSG* pMsg); // 轉發訊息 (在 PreTranslateMessage 調用)

protected:
    // 內部處理 WM_TIMER 顯示/隱藏、WM_PAINT 繪製氣球、WM_MOUSEMOVE 追蹤
};

使用步驟

  1. 專案加入 ToolTipWnd.cpp/.h。
  2. 視圖/對話框類別加入成員:CToolTipWnd m_wndToolTip;。
  3. OnInitDialog/OnInitialUpdate 初始化:
    
    m_wndToolTip.Create(this);
    m_wndToolTip.AddTool(GetDlgItem(IDC_EDIT1), _T("輸入用戶名稱"), RGB(255,0,0));
    m_wndToolTip.AddTool(GetDlgItem(IDC_BUTTON_OK), _T("確認送出"));
    
  4. 重載 PreTranslateMessage 轉發訊息:
    
    BOOL CMyDialog::PreTranslateMessage(MSG* pMsg) {
        m_wndToolTip.RelayEvent(pMsg);
        return CDialog::PreTranslateMessage(pMsg);
    }
    

核心實作邏輯

1. 視窗建立


BOOL CToolTipWnd::Create(CWnd* pParent) {
    return CreateEx(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, // 置頂、不在工作列
        AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
        _T(""), WS_POPUP, 0,0,0,0, pParent->GetSafeHwnd(), NULL);
}

2. 工具資料結構


struct TOOLINFO {
    CWnd* pWnd;        // 關聯控制項
    CString strText;   // 提示文字
    COLORREF clrText;  // 文字顏色
    CRect rect;        // 控制項螢幕矩形 (更新時重算)
};
CArray m_tools;

3. RelayEvent 訊息分派


void CToolTipWnd::RelayEvent(MSG* pMsg) {
    if (pMsg->message == WM_MOUSEMOVE || pMsg->message == WM_LBUTTONDOWN || 
        pMsg->message == WM_RBUTTONDOWN || pMsg->message == WM_KEYDOWN) {
        CPoint pt(pMsg->pt); // 螢幕座標
        ScreenToClient(&pt);
        // 檢查滑鼠是否在某工具控制項矩形內
        for (int i=0; iGetWindowRect(&rectTool); // 即時更新
            if (rectTool.PtInRect(pMsg->pt)) {
                ShowToolTip(i, pMsg->pt); // 顯示對應提示
                return;
            }
        }
        HideToolTip(); // 不在任何工具區域,隱藏
    }
}

4. 氣球繪製 (OnPaint)


void CToolTipWnd::OnPaint() {
    CPaintDC dc(this);
    CRect rect; GetClientRect(&rect);

    // 1. 建立氣球路徑 (圓角矩形 + 三角形尖角)
    CRgn rgn;
    // ... 計算路徑點,包含尖角指向控制項中心 ...
    rgn.CreatePolygonRgn(points, nPoints, ALTERNATE);
    dc.SelectClipRgn(&rgn);

    // 2. 填充背景漸層/單色
    dc.FillSolidRect(rect, RGB(255, 255, 200)); // 淺黃

    // 3. 繪製邊框
    dc.DrawEdge(&rect, EDGE_RAISED, BF_RECT);

    // 4. 繪製文字
    dc.SetBkMode(TRANSPARENT);
    dc.SetTextColor(m_clrCurrentText);
    dc.DrawText(m_strCurrentText, &rect, DT_CENTER | DT_VCENTER | DT_WORDBREAK);
}

5. 位置計算與顯示/隱藏動畫

  • 計算提示視窗大小:DrawText(..., DT_CALCRECT) 加上邊距與尖角空間。
  • 位置:預設在控制項上方置中,尖角指向控制項中心;螢幕邊界自動翻轉 (下方/左側/右側)。
  • 顯示延遲:SetTimer(TIP_SHOW, 500, NULL) (0.5 秒)。
  • 隱藏:滑鼠離開控制項或按鍵按下即時隱藏,或 SetTimer(TIP_HIDE, 5000, NULL) 自動隱藏。
  • 動畫:AnimateWindow (AW_SLIDE | AW_BLEND) 或手動漸變。

擴充功能建議

  • 支援標題 + 圖示 (TTI_INFO/TTI_WARNING/TTI_ERROR)。
  • 支援超連結文字 (點擊跳轉)。
  • 支援多行、RTF 富文本。
  • 高 DPI 感知縮放。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved