Tooltip Controls

最近工作上需要用到 Windows API 來實作 Tooltip 的功能,所以就開始在網路上找 Sample code 來參考,可是奇怪的是:怎麼試都顯示不出來

// Description:
//   Creates a tooltip for an item in a dialog box. 
// Parameters:
//   idTool - identifier of an dialog box item.
//   nDlg - window handle of the dialog box.
//   pszText - string to use as the tooltip text.
// Returns:
//   The handle to the tooltip.
//
HWND CreateToolTip(int toolID, HWND hDlg, PTSTR pszText)
{
    if (!toolID || !hDlg || !pszText)
    {
        return FALSE;
    }
    // Get the window of the tool.
    HWND hwndTool = GetDlgItem(hDlg, toolID);
    
    // Create the tooltip. g_hInst is the global instance handle.
    HWND hwndTip = CreateWindowEx(NULL, TOOLTIPS_CLASS, NULL,
                              WS_POPUP |TTS_ALWAYSTIP | TTS_BALLOON,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              hDlg, NULL, 
                              g_hInst, NULL);
    
   if (!hwndTool || !hwndTip)
   {
       return (HWND)NULL;
   }                              
                              
    // Associate the tooltip with the tool.
    TOOLINFO toolInfo = { 0 };
    toolInfo.cbSize = sizeof(toolInfo);
    toolInfo.hwnd = hDlg;
    toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
    toolInfo.uId = (UINT_PTR)hwndTool;
    toolInfo.lpszText = pszText;
    SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);

    return hwndTip;
}


後來才看到這一篇,原來是 cbSize 的問題,改成 44 就可以正常顯示了

TTM_ADDTOOL为什么会失败

進一步才發現原來是 Common Control 的版本太多了,所以只好改用預先定義的巨集來取代

toolInfo.cbSize = TTTOOLINFO_V2_SIZE;

不過它又忘了定義 UNICODE  版本,所以要改成

toolInfo.cbSize = TTTOOLINFOW_V2_SIZE;

不過人總是貪心的,有了文字後又想要 Icon & Title (因為別人也有嘛)


所以又加了

SendMessage(hwndTip, TTM_SETTITLE, TTI_INFO, (LPARAM)_T("Title text"));

不過為甚麼我的 Icon 長得跟別人不一樣,難道又是版本的問題,又經過一段漫長的搜尋,終於找到原來是要用 Manifest 設定使用新版的 Common Control (多虧了 Trace CToolTipCtrl 才發現它也是直接封裝 Tooltip control,但為甚麼它顯示是 Windows 7 Style 的 Information Icon,最後才查到是 Manifest  不一樣)


最後只要編輯一個 Manifest 的檔案,然後加入專案中編譯就可以了!(似乎不需要開啟 Project | Properties,以便在 Manifest Tool | Input and Output 中的 Additional Manifest Files 加入,只要加入 Project 中就會自動編譯了:待驗證)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <description>Your app description here</description>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
          type="win32"
          name="Microsoft.Windows.Common-Controls"
          version="6.0.0.0"
          processorArchitecture="X86"
          publicKeyToken="6595b64144ccf1df"
          language="*"
        />
    </dependentAssembly>
  </dependency>
</assembly>

PS : 原來 MFC 專案就有這個設定了,只是以前都沒有注意到


留言

這個網誌中的熱門文章

Linux 批次檔的寫法

【分享】如何顯示 Debug Message

[分享] Visual Studio 遠端偵錯