如何使用动态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.lpszText
到LPSTR_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.hwnd
从hwnd_main
到hwnd_control
问题。为了拦截现在发送到控件窗口过程的unicode事件,我使用SetWindowLongW(hwnd_control,GWL_WNDPROC,(LONG)NewControlWndProc)
注意hwnd_control是一个标准的“LISTBOX”与CreateWindowExW(创建)窗口,因此是unicode的,因为所有buildt的Windows类在Unicode和ANSI版本由系统自动注册。
您获得TTN_GETDISPINFO通知代码但不TTN_GETDISPINFOW表明你的项目设置为“使用多字节字符集”的事实。
检查项目属性页面:“配置属性” - >“常规” - >“字符集”
此属性应设置为“使用Unicode字符集”。
很可能是正确的解决方案,我即将张贴相同。 Windows内部是Unicode,但是在运行MBCS(又名ANSI又名Windows95)应用程序时会编入API参数。 – MSalters 2009-06-15 08:01:19