У меня возникли проблемы с предоставлением элемента управления всплывающих подсказок Win32 с динамическим текстом в формате Unicode. Я использую следующий код для настройки элемента управления:
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 не определен, и проект настроен на использование многобайтовой кодировки). Это сделано намеренно, и я хотел бы сохранить его таким, поскольку у меня нет желания переписывать все приложение, чтобы оно поддерживало юникод (по крайней мере, пока). Поскольку определение _UNICODE используется для выбора * W версий различных функций и структур данных, я надеялся, что смогу достичь того же результата, явно используя их в своем коде, как показано выше.