Unicode工具提示未显示

时间:2010-03-30 13:47:46

标签: c++ windows unicode tooltip

我试图在我的应用程序窗口中显示unicode工具提示,但它们似乎没有显示。非unicode文本显示正确,但是一旦我尝试执行unicode,就不会显示工具提示。以下是我目前正在做的事情,感谢您的任何帮助。

     HWND parentHwnd = pickInfo->getViewer().getCachedHwnd();
  CWnd *pWnd = CWnd::FromHandlePermanent(parentHwnd);
  HINSTANCE hInstance = GetModuleHandle(NULL);

  if (isUnicode)
   m_toolInfoW.lpszText = L"This tooltip does not show up at all.";
  else
   m_toolInfoA.lpszText = "Non unicode text";

  if (!m_bTooltipInitialized){
   ::SendMessage(m_tooltipHwnd, WM_DESTROY, 0,0);

   if(isUnicode)
    m_tooltipHwnd = CreateWindowExW(WS_EX_TOPMOST,
     TOOLTIPS_CLASSW, NULL,
     WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,  
     CW_USEDEFAULT, CW_USEDEFAULT,
     CW_USEDEFAULT, CW_USEDEFAULT,
     parentHwnd, NULL, hInstance, NULL);
   else 
    m_tooltipHwnd = CreateWindowEx(WS_EX_TOPMOST,
     TOOLTIPS_CLASS, NULL,
     WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,  
     CW_USEDEFAULT, CW_USEDEFAULT,
     CW_USEDEFAULT, CW_USEDEFAULT,
     parentHwnd, NULL, hInstance, NULL);

   if (GetLastError() != 0)
    return;

   ::SetWindowPos(m_tooltipHwnd, HWND_TOPMOST,
    0, 0, 0, 0,
    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

   // Set the max text width before multi-line tooltip is used.
   ::SendMessage(m_tooltipHwnd, TTM_SETMAXTIPWIDTH, 0, m_nMaxWinTooltipWidth);

   if (isUnicode){
    m_toolInfoW.uFlags = TTF_SUBCLASS | TTF_IDISHWND | TTF_TRACK;
    m_toolInfoW.hinst = hInstance;
    m_toolInfoW.hwnd = parentHwnd;
    m_toolInfoW.uId = (UINT_PTR)parentHwnd;
    ::GetClientRect (parentHwnd, &m_toolInfoW.rect);

    ::SendMessage(m_tooltipHwnd, TTM_ADDTOOLW, 0, (LPARAM) (LPTOOLINFOW) &m_toolInfoW);
    ::SendMessage(m_tooltipHwnd, TTM_ACTIVATE, TRUE, (LPARAM)(LPTOOLINFOW) &m_toolInfoW);
   }
   else{
    m_toolInfoA.uFlags = TTF_SUBCLASS | TTF_IDISHWND;
    m_toolInfoA.hinst = hInstance;
    m_toolInfoA.hwnd = parentHwnd;
    m_toolInfoA.uId = (UINT_PTR)parentHwnd;
    ::GetClientRect (parentHwnd, &m_toolInfoA.rect);

    ::SendMessage(m_tooltipHwnd, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &m_toolInfoA);
    ::SendMessage(m_tooltipHwnd, TTM_ACTIVATE, TRUE, (LPARAM)(LPTOOLINFO) &m_toolInfoA);
   }
   m_bTooltipInitialized = true;
  }

  if (isUnicode)
   ::SendMessage(m_tooltipHwnd, TTM_UPDATETIPTEXTW, 0, (LPARAM) (LPTOOLINFOW) &m_toolInfoW);
  else
   ::SendMessage(m_tooltipHwnd, TTM_UPDATETIPTEXT, 0, (LPARAM) (LPTOOLINFO) &m_toolInfoA);

  //Repaint the screen so that the area beneath the previous location of the tooltip is restored correctly.
  ::UpdateWindow(pWnd->GetParentOwner()->GetSafeHwnd());
  pWnd = NULL;

3 个答案:

答案 0 :(得分:6)

问题是您尝试使用通用控件版本6,但您无法使用它。

更多细节,

typedef struct tagTOOLINFOW {
    UINT cbSize;
    UINT uFlags;
    HWND hwnd;
    UINT_PTR uId;
    RECT rect;
    HINSTANCE hinst;
    LPWSTR lpszText;
    LPARAM lParam;
#if (NTDDI_VERSION >= NTDDI_WINXP)
    void *lpReserved;
#endif
} TTTOOLINFOW, NEAR *PTOOLINFOW, *LPTTTOOLINFOW;

对于xp +,头文件CommCtrl.h假设您将使用comctl版本6,但如果您没有使用清单文件启用它明确,您仍将使用旧的comctl版本5 。X。然后出现问题,版本5.x的TOOLINFO的大小与版本6.x不同。

因此,如果你需要在windows xp +下使用comctl版本5,你应该使用以下代码初始化TOOLINFO,

TOOLINFO ti;
ti.cbSize = sizeof(TOOLINFO) - 4;

否则,您应该使用清单文件或prgram指令启用可视样式外观:

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

最后,我建议您始终在xp +中启用visual-look。以下是视觉效果的比较:

common controls 5.x

common controls 6.x

注意:如果使用ANSI / MBCS编译程序,则sizeof(TOOLINFO)将为48,已删除lpReserved成员。所以ANSI版本可行,但UNICODE会失败。

答案 1 :(得分:1)

在Unicode情况下,您有TTF_TRACK,我相信您需要手动显示或隐藏工具提示。在ANSI情况下,您没有该选项。

http://msdn.microsoft.com/en-us/library/bb760252(VS.85).aspx

向下滚动到“实施跟踪工具提示”。

答案 2 :(得分:1)

良好的解释和解决方案将由上面的Jichao工作,但硬连接TOOLINFO结构的大小将只修复工具提示。如果问题是该程序是使用6.0+的常见控件编译的,但可能会运行(例如)未安装或未完全安装6.0+的Windows XP系统(如某人已安装IE,但从未使用或更新它,然后更通用的解决方案是限制应用程序只使用5.x常用控件。

可以看出here,结构大小的变化比工具提示更多。

我所做的是为了确保一切都能在Windows XP上运行,将以下内容放在我的程序的最顶端,在任何包含之前(在visual studio的情况下,一个好地方将位于targetver.h的顶部)如果你有一个):

#define _WIN32_WINNT    0x0500