В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное.
Короткое описание:
m_hWndOwner -- окно, которое будет получать все сообщения мыши
DelayShowAtCursor( UINT time ) -- показать посказку под курсором через определённое время. Не сказать что бы самая востребованная функция, но нне это было нужно.
Остальное должно быть понятно
Маленькое замечание: при создании нужно указать окно хозяин, и это не тоже самое что окно владелец(m_hWndOwner). В качестве хозяина удобнее всего установить ::GetDesktopWindow(), в противном случае возникают малопонятные глюки с позиционированием.
А в чем выражается нужда в виртуальном деструкторе ?
Еще хочу заметить что в WTL принято делать два класса : SomeClassImpl в котором вся функциональность и SomeClass производный от SomeClassImpl, где устанавливается класс окна через DECLARE_WND_SUPERCLASS.
__>А в чем выражается нужда в виртуальном деструкторе ?
Да ни в чём, убрать конечно же.
__>Еще хочу заметить что в WTL принято делать два класса : SomeClassImpl в котором вся функциональность и SomeClass производный от SomeClassImpl, где устанавливается класс окна через DECLARE_WND_SUPERCLASS.
Знаю, но в этом случае с трудом представляю зачем это может понадобиться.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Здравствуйте, WinterMute, Вы писали:
__>>А в чем выражается нужда в виртуальном деструкторе ? WM>Да ни в чём, убрать конечно же.
__>>Еще хочу заметить что в WTL принято делать два класса : SomeClassImpl в котором вся функциональность и SomeClass производный от SomeClassImpl, где устанавливается класс окна через DECLARE_WND_SUPERCLASS.
WM>Знаю, но в этом случае с трудом представляю зачем это может понадобиться.
Для того чтобы кто-то смог в дальнейшем расширить функциональность класса.
Так принято в WTL и отходить от этого стиля не стоит.
Здравствуйте, _nn_, Вы писали:
WM>>Знаю, но в этом случае с трудом представляю зачем это может понадобиться. __>Для того чтобы кто-то смог в дальнейшем расширить функциональность класса.
Да нафиг, и так нормально работает . KISS
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
::SendMessage(m_hWnd...)
В чем смысл в этм если можно писать просто SendMessage ?
Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой
Вдобавок лучше ее сделать статической функцией класса.
По возможности стоит избегать использования CString в классе или же через условную компиляцию добавлять функции.
А то не все пользуются CString и может вылезти ошибка.
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, WinterMute, Вы писали:
__>::SendMessage(m_hWnd...) __>В чем смысл в этм если можно писать просто SendMessage ?
Как то пришлось переносить WTL-ные библиотеки на WinApi, теперь, если не особой разницы, я стараюсь пользоваться API функциями.
__>Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой
Как? Напиши пож, а то я сначала сделал одной строкой, дак она глючила.
__>Вдобавок лучше ее сделать статической функцией класса.
Мне она была нужна и в других классах, поэтому она глобальная.
__>По возможности стоит избегать использования CString в классе или же через условную компиляцию добавлять функции. __>А то не все пользуются CString и может вылезти ошибка.
Приму во внимание.
Думай, что хочешь, делай, что хочешь, живи, как хочешь -- всё тебе припомню!!
Здравствуйте, Odi$$ey, Вы писали:
OE>Здравствуйте, WinterMute, Вы писали:
OE>
OE> ~Tooltip()
OE> {
OE> delete m_ToolInfo.lpszText; // << иначе утекает при уничтожении окна с текстом
OE> m_ToolInfo.lpszText = NULL;
OE> }
OE>
Вот это большое спасибо. У меня подсказка создавалась статически, поэтому наверное, и не заметил.
Здравствуйте, WinterMute, Вы писали:
WM>Здравствуйте, _nn_, Вы писали:
__>>Здравствуйте, WinterMute, Вы писали:
__>>::SendMessage(m_hWnd...) __>>В чем смысл в этм если можно писать просто SendMessage ?
WM>Как то пришлось переносить WTL-ные библиотеки на WinApi, теперь, если не особой разницы, я стараюсь пользоваться API функциями.
По CString это не заметно
А вообще все же не принято писать ::SendMessage(m_hWnd...)
Это выглядит мазохизмом, мы ведь в WTL пишем все же
__>>Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой
WM>Как? Напиши пож, а то я сначала сделал одной строкой, дак она глючила.
Ну попробую :
Оригинал :
Или же можно воспользоваться MAKEWORD
MAKEWORD(pt.x,pt.y)
И все
__>>Вдобавок лучше ее сделать статической функцией класса.
WM>Мне она была нужна и в других классах, поэтому она глобальная.
Понятно.
Здравствуйте, _nn_, Вы писали:
__>Здравствуйте, WinterMute, Вы писали:
WM>>Здравствуйте, _nn_, Вы писали:
__>>>Здравствуйте, WinterMute, Вы писали:
__>>>::SendMessage(m_hWnd...) __>>>В чем смысл в этм если можно писать просто SendMessage ?
WM>>Как то пришлось переносить WTL-ные библиотеки на WinApi, теперь, если не особой разницы, я стараюсь пользоваться API функциями. __>По CString это не заметно
Я СString тоже переносил, как-то хитро откусывая хвосты. И в случае чего опроедлить свой "CString" не проблема, там ведь всё что от СString используется это конструирование из константной строки и приведение к константной строке, такое из std::string в два счёта делается. А использовать строки без обёрток это как-то не по мне.
__>А вообще все же не принято писать ::SendMessage(m_hWnd...) __>Это выглядит мазохизмом, мы ведь в WTL пишем все же
Правильно, я же мазохист .
__>>>Функцию PtToLPARAM слудует пересмотреть, можно это заменить одной строкой
WM>>Как? Напиши пож, а то я сначала сделал одной строкой, дак она глючила. __>Ну попробую : __>Оригинал : __>
Здравствуйте, swap, Вы писали:
S>Данный код не работает (тултипы не появляются) если есть макрос S>#define _WIN32_WINNT 0x0501 S>который например нужен для atltheme.h :(
У меня в текущем проекте он используется в том числе с кодом для отрисовки тем. Там, правда определён макрос
"#define _WIN32_WINNT 0x0500"
Ты уверен что дело в макросе, есть какие-нибудь другие "симптомы"?
Толькло что попробовал с макросом 0x0501 -- всё работает.
Покажи как ты используешь класс.
S>Данный код не работает (тултипы не появляются) если есть макрос S>#define _WIN32_WINNT 0x0501 S>который например нужен для atltheme.h :(
Здравствуйте, WinterMute, Вы писали:
WM>Толькло что попробовал с макросом 0x0501 -- всё работает. WM>Покажи как ты используешь класс.
Да, дело в нем. Если ставишь 0x0500 все работает, но atltheme.h требует 0x0501.
Использую так:
WTL 7.5, VC 80 SP1, создаю через визард WTL проект с главным дилоговым окном. в CMainDlg объявляю переменнкю UI::Tooltip m_tooltip.
В OnInitDialog делаю
m_tooltip.Create(m_hWnd);
И, например, в CMainDlg::OnLButtonDown делаю
m_tooltip.SetText("bla bla bla");
m_tooltip.ShowAtCursor();
У меня другая версия VS и, видимо, ATL. Возможно дело в этом.
Можешь посмотреть отладчиком, создаётся ли вообще окно,
и что происходит после вызова ShowAtCursor() -- GetLastError()
в смысле.
Да, и для подержки тем, по идее, не нужен _WIN32_WINNT 0x0501,
достаточно вручную прописать
По крайней мере, с моей версией библиотек, больше ничего не потребовалось.
WM>>Толькло что попробовал с макросом 0x0501 -- всё работает. WM>>Покажи как ты используешь класс.
S>Да, дело в нем. Если ставишь 0x0500 все работает, но atltheme.h требует 0x0501.
S>Использую так: S>WTL 7.5, VC 80 SP1, создаю через визард WTL проект с главным дилоговым окном. в CMainDlg объявляю переменнкю UI::Tooltip m_tooltip. S>В OnInitDialog делаю
S>m_tooltip.Create(m_hWnd);
S>И, например, в CMainDlg::OnLButtonDown делаю
S>m_tooltip.SetText("bla bla bla"); S>m_tooltip.ShowAtCursor();
S>в stdafx.h такие макросы:
S>#define WINVER 0x0500 S>#define _WIN32_WINNT 0x0501 S>#define _WIN32_IE 0x0501 S>#define _RICHEDIT_VER 0x0100
Здравствуйте, WinterMute, Вы писали:
WM>У меня другая версия VS и, видимо, ATL. Возможно дело в этом. WM>Можешь посмотреть отладчиком, создаётся ли вообще окно, WM>и что происходит после вызова ShowAtCursor() -- GetLastError() WM>в смысле.
WM>Да, и для подержки тем, по идее, не нужен _WIN32_WINNT 0x0501, WM>достаточно вручную прописать WM>
WM>По крайней мере, с моей версией библиотек, больше ничего не потребовалось.
Окно создается, все ::SendMessage возвращают вроде то что должны (для тех сообщений что должны что-то возвращать), GetLastError после ShowAtCursor возвращает 0.
Вопщем с виду все ОК вроде, но тултип не появляется, меняешь на 0x0500 — появляется
У меня в atltheme.h есть такой код
#if (_WIN32_WINNT < 0x0501)
#error atltheme.h requires _WIN32_WINNT >= 0x0501
#endif // (_WIN32_WINNT < 0x0501)
Здравствуйте, WinterMute, Вы писали:
WM>Посмотри как выполняется SubclassWindow( hWnd ), в Create(). Инициализирован-ли m_hWnd?
Да, там все нормально, видимых в отладчике ошибок нет. Более того, на другой машине с той же версией WTL c VC8 (не SP1) все работает.
Ума не приложу в чем дело
Здравствуйте, WinterMute, Вы писали:
WM>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...
Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит
Здравствуйте, WinterMute, Вы писали:
WM>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...
Да и еще кто-нибудь сталкивался с проблемой определения координат иконки в трее? Я там хочу тултип выводить когда окно свернуто...?
P.S. Идею с перемещение курсора мыши на иконку и получения координат через сообщение считаю не спортивной, так как:
а)трей может свернуться, и придется заного водить туда мышь
б)в трей может добавиться еще другая прога и придется заного водить туда мышь
в)а также если запущенны два экземпляра программы, то нужно будет еще различать где какой
Здравствуйте, kaz, Вы писали:
kaz>Здравствуйте, WinterMute, Вы писали:
WM>>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...
kaz>Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит
Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
Здравствуйте, WinterMute, Вы писали:
WM>Здравствуйте, kaz, Вы писали:
kaz>>Здравствуйте, WinterMute, Вы писали:
WM>>>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...
kaz>>Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит
WM>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:
Здравствуйте, kaz, Вы писали:
kaz>Да и еще кто-нибудь сталкивался с проблемой определения координат иконки в трее? Я там хочу тултип выводить когда окно свернуто...? kaz>P.S. Идею с перемещение курсора мыши на иконку и получения координат через сообщение считаю не спортивной, так как: kaz>а)трей может свернуться, и придется заного водить туда мышь kaz>б)в трей может добавиться еще другая прога и придется заного водить туда мышь kaz>в)а также если запущенны два экземпляра программы, то нужно будет еще различать где какой
Когда показываете пиктограмму в трее, в Shell_NotifyIcon передаётся структура, содержащая HWND окошка, которая будет принимать сообщение, ID сообщения, ID пиктограммы (чтоб различать несколько от одного окна), текст тултипа. Потом ловите это сообщение в окне, получая ID пиктограммы и WM_чототам, что случилось с пиктограммой, WM_LBUTTONDBLCLK, например. Тултип система сама выведет, кстати.
Здравствуйте, WinterMute, Вы писали:
WM>Здравствуйте, kaz, Вы писали:
kaz>>Здравствуйте, WinterMute, Вы писали:
WM>>>В своё время меня не устроил стандартный CTooltipCtrl -- мне была нужена подсказка которая бы появлялась и пропадала когда ей скажут. Кроме того, нужно было, что бы подсказка была прозрачна для всех сообщений мыши (я делал т.н. inplace tooltip). Этот простой класс делает всё вышеперечисленное...
kaz>>Я новичек в ВТЛ подскажите пожалуйста как обработать сообщения мыши тултипа... В дебагере смотрел он даже в OnMouseMessage не заходит
WM>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
он утебя в OnMouseMessage не заходит, пробовал ставить брекпоинт.
Здравствуйте, Xander Zerge, Вы писали:
XZ>Здравствуйте, kaz, Вы писали:
kaz>>Да и еще кто-нибудь сталкивался с проблемой определения координат иконки в трее? Я там хочу тултип выводить когда окно свернуто...? kaz>>P.S. Идею с перемещение курсора мыши на иконку и получения координат через сообщение считаю не спортивной, так как: kaz>>а)трей может свернуться, и придется заного водить туда мышь kaz>>б)в трей может добавиться еще другая прога и придется заного водить туда мышь kaz>>в)а также если запущенны два экземпляра программы, то нужно будет еще различать где какой
XZ>Когда показываете пиктограмму в трее, в Shell_NotifyIcon передаётся структура, содержащая HWND окошка, которая будет принимать сообщение, ID сообщения, ID пиктограммы (чтоб различать несколько от одного окна), текст тултипа. Потом ловите это сообщение в окне, получая ID пиктограммы и WM_чототам, что случилось с пиктограммой, WM_LBUTTONDBLCLK, например. Тултип система сама выведет, кстати.
Мне надо чтобы тултип в трее выводился не по какому-то событию (WM_MOUSEMOVE, WM_LBUTTONDOWN), а по другим причинам (например, значение переменной вышло за заданный диапазон)
Здравствуйте, kaz, Вы писали:
kaz>Мне надо чтобы тултип в трее выводился не по какому-то событию (WM_MOUSEMOVE, WM_LBUTTONDOWN), а по другим причинам (например, значение переменной вышло за заданный диапазон)
Для того balloon есть. Делается через ту же Shell_NotifyIcon, через NIF_INFO.
WM>>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
kaz>Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:
Убери стиль TTF_TRANSPARENT в строчке:
m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;
Здравствуйте, WinterMute, Вы писали:
WM>>>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
kaz>>Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:
WM>Убери стиль TTF_TRANSPARENT в строчке: WM>m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;
WM>-- Тогда должны ловиться мышиные сообщения.
Ок, спасибо за помощь. Только еще один ньюанс... В родительском окне (которое hwndOwner)я ловлю WM_LBUTTONDBLCLK
и при нажатии мышой на тултип приходит сообщение, но при нажатии на клиентскую облать родительского диалога оно не приходит (меня это устраивает), но
так... интересно как же его если что отловить!
Здравствуйте, Xander Zerge, Вы писали:
XZ>Здравствуйте, kaz, Вы писали:
kaz>>Мне надо чтобы тултип в трее выводился не по какому-то событию (WM_MOUSEMOVE, WM_LBUTTONDOWN), а по другим причинам (например, значение переменной вышло за заданный диапазон) XZ>Для того balloon есть. Делается через ту же Shell_NotifyIcon, через NIF_INFO.
Да, я догодался уже, через NIF_MODYFY оно появляется... Но все равно спкасибо за беспокойство!
правда обидно что максимальный размер 255, а у меня возможна такая ситуация когда размер выводимого в тултипе текста 32000*64...
поэтому я вывожу тултип в трее несколько раз, если размер выводимого текста > 256...
Может есть способ это обойти? Т.е. увеличить размер буффера передаваемогоо через NOTIFYICONDATA?
Здравствуйте, kaz, Вы писали:
kaz>Здравствуйте, WinterMute, Вы писали:
WM>>>>Не понятно что именно надо, опиши задачу подробнее. Если ты о том, чтобы показывать подсказку по сообщению мыши, то это нужно делать вручную, вызвав Show().
kaz>>>Задача такая: при клике мышой на тултипе скрывать его... А мышиные сообщения не обрабатываются... пробовал субклассить тултип... но тоже без результатов:
WM>>Убери стиль TTF_TRANSPARENT в строчке: WM>>m_ToolInfo.uFlags = TTF_TRACK | TTF_TRANSPARENT | TTF_SUBCLASS;
WM>>-- Тогда должны ловиться мышиные сообщения.
kaz>Ок, спасибо за помощь. Только еще один ньюанс... В родительском окне (которое hwndOwner)я ловлю WM_LBUTTONDBLCLK
kaz>
kaz>и при нажатии мышой на тултип приходит сообщение, но при нажатии на клиентскую облать родительского диалога оно не приходит (меня это устраивает), но kaz>так... интересно как же его если что отловить!
Ааааа... нет вру... я просто по ТулБару кликал, приходит все...
Тогда встречный вопрос... Как тогда понять в родительском окне что клик по тултипу, а не по самому окну!?
kaz>Ааааа... нет вру... я просто по ТулБару кликал, приходит все... kaz>Тогда встречный вопрос... Как тогда понять в родительском окне что клик по тултипу, а не по самому окну!?
Очевидно что тултип на самом верху, поэтому можно взять GetWindowRect() тултипа и посмотреть попадают-ли в него координаты курсора.
Здравствуйте, WinterMute, Вы писали:
kaz>>Ааааа... нет вру... я просто по ТулБару кликал, приходит все... kaz>>Тогда встречный вопрос... Как тогда понять в родительском окне что клик по тултипу, а не по самому окну!?
WM>Очевидно что тултип на самом верху, поэтому можно взять GetWindowRect() тултипа и посмотреть попадают-ли в него координаты курсора.
спасибо
Re[6]: WTL: Подсказка в любом месте экрана
От:
Аноним
Дата:
30.01.08 18:59
Оценка:
Такая же лажа. В режиме отладки заметно что tooltip на самом деле появлятся но потом сразу исчезает.