如何使用动态Unicode文本设置Win32工具提示控件?

问题描述:

我在使用unicode格式的动态文本提供Win32工具提示控件方面遇到了一些麻烦。我用下面的代码来设置控制:如何使用动态Unicode文本设置Win32工具提示控件?

INITCOMMONCONTROLSEX icc; 
icc.dwSize = sizeof(INITCOMMONCONTROLSEX); 
icc.dwICC = ICC_WIN95_CLASSES; 
InitCommonControlsEx(&icc); 

HWND hwnd_tip = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 
    WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, 
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
    NULL, NULL, hinst, NULL 
); 
SetWindowPos(hwnd_tip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 

TOOLINFOW ti; 
memset(&ti, 0, sizeof(TOOLINFOW)); 
ti.cbSize = sizeof(TOOLINFOW); 
ti.hwnd = hwnd_main; 
ti.uId = (UINT) hwnd_control; 
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS; 
ti.lpszText = L"This tip is shown correctly, including unicode characters."; 
SendMessageW(hwnd_tip, TTM_ADDTOOLW, 0, (LPARAM) &ti); 

这工作得很好,只要我提供ti.lpszText提示文本。不过,我希望文字是动态的,所以不是我设置ti.lpszTextLPSTR_TEXTCALLBACKW和处理回调在我的WindowProc(),像这样:

... 
case WM_NOTIFY: 
{ 
    NMHDR *nm = (NMHDR *) lParam; 
    switch (nm->code) 
    { 
    case TTN_GETDISPINFOW: 
    { 
     static std::wstring tip_string = L"Some random unicode string."; 
     NMTTDISPINFOW *nmtdi = (NMTTDISPINFOW *) lParam;    
     nmtdi->lpszText = (LPWSTR) tip_string.c_str(); 
    } 
    break; 
    } 
} 
break; 
... 

不工作,因为我从来没有收到TTN_GETDISPINOW消息。 (注:它的工作原理,如果我处理TTN_GETDISPINFO来代替,而NMTTDISPINFO提供一个字符数组,但随后没有Unicode支持...)

我猜我做错了什么在我的设置或信息处理吗?有关如何正确执行此操作的任何建议?

更新
另外请注意,我的项目是不是在unicoe编译模式(没有定义,即_UNICODE和项目设置为使用多字节字符集)。这是故意的,我想保留它,因为我不想将整个应用程序重写为unicode意识(至少现在还没有)。由于_UNICODE定义用于选择* W版本的各种函数和数据结构,我希望能够通过在我的代码中明确使用这些结果来达到相同的结果,如上所示。

感谢您的罗伯特斯科特链接。我现在找到了解决这个问题的方法。

总之,诀窍是确保接收窗口是一个unicode窗口并为其注册一个unicode窗口过程。

问题是我的父窗口没有处理TTN_GETDISPINFOW通知消息的unicode WindowProc()。由于此窗口(类)是使用RegisterClassEx()/CreateWindowEx()而不是RegisterClassExW()/CreateWindowExW()创建的,因此它没有为unicode消息注册窗口过程。

为了避开发送TTM_ADDTOOLW时,导致该控件的窗口过程中receving通知,而不是其父我改变ti.hwndhwnd_mainhwnd_control问题。为了拦截现在发送到控件窗口过程的unicode事件,我使用SetWindowLongW(hwnd_control,GWL_WNDPROC,(LONG)NewControlWndProc)对其进行了分类。

注意hwnd_control是一个标准的“LISTBOX”与CreateWindowExW(创建)窗口,因此是unicode的,因为所有buildt的Windows类在Unicode和ANSI版本由系统自动注册。

+1

很可能是正确的解决方案,我即将张贴相同。 Windows内部是Unicode,但是在运行MBCS(又名ANSI又名Windows95)应用程序时会编入API参数。 – MSalters 2009-06-15 08:01:19

您的整个应用程序是否使用unicode?否则你可能会读这个"Microsoft article"。尤其是“启用Unicode的十二步”部分。

或者尝试这样做的人

Robert Scott Unicode Tooltips

您获得TTN_GETDISPINFO通知代码但不TTN_GETDISPINFOW表明你的项目设置为“使用多字节字符集”的事实。

检查项目属性页面:“配置属性” - >“常规” - >“字符集”
此属性应设置为“使用Unicode字符集”。