Сообщений 2 Оценка 1 Оценить |
Первое, что приходит в голову в связи с этим вопросом - это сообщение TTM_SETDELAYTIME. Оно предназначено для задания различных временных интервалов, связанных с тултипом. В частности интервал, задаваемый флагом TTDT_AUTOPOP, определяет промежуток времени, по истечении которого тултип исчезает автоматически. Проблема с этим сообщением состоит в том, что тултип воспринимает интервалы как двухбайтовые числа, да ещё и в милисекундах. Это значит, что нам не удастся задать интервал больше приблизительно 30 секунд , а такой интервал вряд ли покажется пользователю бесконечным.
Поскольку законного метода решить задачу не существует, придётся прибегнуть к незаконному. Дело в том, что тултип использует для измерения промежутков времени стандартный механизм таймеров системы Windows. В частности, время до исчезновения измеряется таймером с идентификатором 4 (это и есть недокументированный параметр, вычисленный при помощи Spy++). Если уничтожить его (таймер) с помощью функции KillTimer, тултип навсегда останется на экране. Единственная проблема, которая здесь возникает - в каком месте программы лучше всего убивать таймер? Поэкспериментировав с этим подходом, я пришёл к выводу, что таймер проще всего убивать по таймеру. Разумеется, нужно проследить, чтобы период нашего таймера был меньше времени исчезновения тултипа (для этого достаточно использовать уже рассмотренное сообщение TTM_SETDELAYTIME). Вот как может выглядеть функция окна, реализующая эту идею.
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: ... SetTimer(hWnd, 0, 3000, NULL); break; case WM_TIMER: // hTip - дескриптор тултипа if(IsWindow(hTip)) KillTimer(hTip, 4); // Убиваем таймер! ... } return DefWindowProc(hWnd, msg, wParam, lParam); } |
Совершенно аналогично этот способ реализуется в MFC, для этого придётся написать обработчики OnCreate и OnTimer.
int CSomeWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; SetTimer(0, 3000, NULL); return 0; } void CSomeWnd::OnTimer(UINT nIDEvent) { // pTT - указатель на объект класса CToolTipCtrl pTT->KillTimer(4); CWnd::OnTimer(nIDEvent); } |
Если вы создаёте тултип вручную, проблем с получением указателя pTT не возникает. Если же вы активизируете его, используя CWnd::EnableToolTips, нужный указатель можно получить из структуры состояния потока, используя выражение AfxGetThreadState()->m_pToolTip.
Сообщений 2 Оценка 1 Оценить |