Подсказки Unicode не отображаются - PullRequest
4 голосов
/ 30 марта 2010

Я пытаюсь отобразить подсказки Юникода в окне моего приложения, однако они не отображаются. Текст не в Юникоде отображается правильно, но как только я пытаюсь выполнить Юникод, подсказка не появляется. Вот что я сейчас делаю, спасибо за любую помощь.

     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 ]

6 голосов
/ 02 марта 2013

Проблема в том, что вы пытаетесь использовать общие элементы управления версии 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 предполагает, что вы будете использовать версию 6 comctl, но если вы не включите ее явно с файлом манифеста, вы все равно будете использовать старую версию 5 comctl. Икс. Тогда возникает проблема: размер TOOLINFO версии 5.x отличается от версии 6.x.

Так что, если вам нужно использовать версию 5 Comctl под Windows XP +, вы должны запустить 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 +. Вот сравнение визуальных эффектов:

common controls 5.x

common controls 6.x

Примечание. Если для компиляции программы вы используете ANSI / MBCS, размер (TOOLINFO) будет равен 48, что уже привело к удалению члена lpReserved. Таким образом, ANSI-версия будет работать, но UNICODE не будет работать.

1 голос
/ 28 июля 2016

Хорошее объяснение и решение, которое будет работать Jichao выше, но жесткий размер структуры TOOLINFO исправит только всплывающие подсказки. Если проблема заключается в том, что программа была скомпилирована с учетом общих элементов управления 6.0+, но может быть запущена, скажем, в системе Windows XP с 6.0+ или не установлена, или не полностью установлена ​​(как кто-то установил IE, но никогда не использовал обновите его), тогда более общее решение состоит в том, чтобы ограничить применение только 5.x общими элементами управления.

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

То, что я сделал, чтобы убедиться, что все будет работать в Windows XP, помещает следующее в самую верхнюю часть моей программы, прежде чем что-либо включать (в случае visual studio, хорошее место будет на вершине targetver.h если у вас есть):

#define _WIN32_WINNT    0x0500
1 голос
/ 30 марта 2010

В случае Unicode у вас есть TTF_TRACK, что, как я считаю, требует, чтобы вы вручную показывали или скрывали подсказку. В случае ANSI у вас нет этой опции.

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

Прокрутите вниз до «Реализация подсказок по отслеживанию».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...