2009-06-14 3 views
0

У меня возникли проблемы с установкой инструментальной панели Win32 с динамическим текстом в формате Unicode. Я использую следующий код для настройки управления:Как настроить управление всплывающей подсказкой 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, чтобы обеспечить массив символов, но без поддержки Юникода ...)

Я предполагаю, что я делаю что-то неправильно в моей установке или обработки сообщений здесь? Любые предложения о том, как сделать это правильно?

Update
отметить также, что мой проект не компилируется в unicoe режиме (т.е. _UNICODE не определен, и проект настроен на использование многобайтную набор символов). Это намеренно, и я хотел бы сохранить его таким образом, поскольку у меня нет желания переписывать все приложение в формате unicode (по крайней мере, пока). Поскольку определение _UNICODE используется для выбора * W-версий различных функций и структур данных, я надеялся, что смогу достичь такого же результата, используя это явно в моем коде, как показано выше.

ответ

3

Спасибо за ссылку Роберта Скотта. Я нашел способ решить это сейчас.

Короче говоря, трюк состоял в том, чтобы убедиться, что принимающее окно было окном Юникода и зарегистрировало для него процедуру окна Юникода.

Проблема была в том, что у меня не было юникода WindowProc() для моего родительского окна, обрабатывающего сообщение уведомления TTN_GETDISPINFOW. Поскольку это окно (класс) было создано с RegisterClassEx()/CreateWindowEx(), а не RegisterClassExW()/CreateWindowExW(), у него не было зарегистрированной процедуры окна для сообщений в Юникоде.

Чтобы обойти эту проблему, я изменил ti.hwnd от hwnd_main к hwnd_control при отправке TTM_ADDTOOLW, в результате чего в оконной процедуре элемента управления receving уведомления вместо своего родителя. Чтобы перехватить события unicode, которые теперь отправлены в оконную процедуру элемента управления, я подклассифицировал его с помощью SetWindowLongW (hwnd_control, GWL_WNDPROC, (LONG) NewControlWndProc).

Обратите внимание, что hwnd_control это стандартное окно «LISTBOX» создан с CreateWindowExW() и поэтому Юникод, так как все buildt в классах Windows, автоматически регистрируется в оба Юникоде и ANSI версии системы.

+1

Скорее всего, правильное решение, я собирался опубликовать то же самое. Windows внутренне является Unicode, но будет аргументировать аргументы API при запуске приложения MBCS (aka ANSI aka Windows95). – MSalters

1

Является ли все ваше приложение использующим unicode? Иначе вы можете прочитать это "Microsoft article". Особенно «Двенадцать шагов к Unicode-разрешению» раздел.

Или попробовать, как этот парень сделал

Robert Scott Unicode Tooltips

3

Тот факт, что вы получите код уведомления TTN_GETDISPINFO но не TTN_GETDISPINFOW означает, что ваш проект установки «Установить Многобайтовые символов».

Проверьте страницы свойств проектов: «Свойства конфигурации» -> «Общие» -> «Набор символов»
Это свойство должно быть установлено в «Использовать набор символов Юникода».

Смежные вопросы