Всем привет.
Пишу на MFC небольшой класс-потомок CEdit, помимо прочей функциональности, позволяющий выкидывать подсказку (стандартный tracking tooltip) в произвольный момент времени.
Задача — наиболее простое решение стандартными средствами, т.к. этот класс будет использоваться в и так чересчур сложном комплексе.
Проблема вполне банальна: не могу красиво отловить факт изменения положения родительского окна, чтобы загасить подсказку (остаётся висеть на своём месте, как и положено popup-окну).
Пока что использую таймер, опрашивающий CEdit::GetWindowRect() и сверяющий координаты, однако это решение я считаю его некрасивым, и в проект оно не пройдёт.
Хуки тоже использовать нельзя.
Тема очень похожа на http://www.rsdn.ru/forum/mfc/3736894.aspx
, но там автор остановился именно на хуках.
Может, всё же можно малой кровью изменить CEdit так, чтобы можно было перехватить WM_MOVE и иже с ним, находясь на диалоге, т.к. хотелось бы всё-таки использовать стандартный tooltip?
Re: Контроль положения родительского окна из CEdit
Здравствуйте, avnazyrov, Вы писали:
A>Проблема вполне банальна: не могу красиво отловить факт изменения положения родительского окна, чтобы загасить подсказку (остаётся висеть на своём месте, как и положено popup-окну).
1.Сабклассинг (в смысле Win32, то есть SetWindowLongPtr) родителя не пойдет ?
2. Почему эту проблему надо решать у edit ? Почему не решать ее именно у родителя — пусть он пришлет edit какое-нибудь сообщение при своем движении ?
With best regards
Pavel Dvorkin
Re[4]: Контроль положения родительского окна из CEdit
RB>А почему именно tracking? RB>Почему не обычный tooltip, который прячется сам?
У меня не получилось заставить появляться обычный тултип в произвольный момент времени (опять же нормальными методами).
К примеру, здесь описано как это реализовать, но уж слишком сложно по сравнению с tracking, при точно таком же результате.
Идеальной ситуацией было бы использовать tracking и иметь возможность самостоятельно (не выше уровня родительского CEdit) обрабатывать сообщения о перемещении и т.д.
Кстати, дополнительный плюс такого подхода в том, что нет необходимости перегружать PreTranslateMessage у родительского окна и вызывать там RelayEvent, как у обычного тултипа. Это повышает прозрачность использования.
Re[2]: Контроль положения родительского окна из CEdit
PD>1.Сабклассинг (в смысле Win32, то есть SetWindowLongPtr) родителя не пойдет ? PD>2. Почему эту проблему надо решать у edit ? Почему не решать ее именно у родителя — пусть он пришлет edit какое-нибудь сообщение при своем движении ?
Есть ограничения на возможное решение: всё должно работать без изменения существующего кода. Максимум добавить один обработчик типа RelayEvent() у CToolTipCtrl.
Сабклассинг, хуки и т.д. — слишком тяжёлая артиллерия.
Тем более, что таких полей ввода может быть несколько на одном окне, так что "максимально просто, прозрачно и отказоустойчиво".
Re[4]: Контроль положения родительского окна из CEdit
A>Есть ограничения на возможное решение: всё должно работать без изменения существующего кода. Максимум добавить один обработчик типа RelayEvent() у CToolTipCtrl. A>Сабклассинг, хуки и т.д. — слишком тяжёлая артиллерия. A>Тем более, что таких полей ввода может быть несколько на одном окне, так что "максимально просто, прозрачно и отказоустойчиво".
Ну тогда не знаю. Сабклассинг не так уж прост, но и не сложен. 10 строчек и все дела. Если ставится задача, но почему-то начинают ограничивать в способе решения (при том, что предлагается отнюдь не хак, а вполне легальный метод) — тогда я пас.
With best regards
Pavel Dvorkin
Re[4]: Контроль положения родительского окна из CEdit
PD>Ну тогда не знаю. Сабклассинг не так уж прост, но и не сложен. 10 строчек и все дела. Если ставится задача, но почему-то начинают ограничивать в способе решения (при том, что предлагается отнюдь не
Тут есть несколько нюансов.
1) Контролов может быть несколько на одном окне, что, конечно, легко учитывается, но уже вносит некоторую сложность.
2) В программном комплексе уже и так используются хуки (и их пытаются изжить по требованию начальства). Где — надо узнавать. Не хотелось бы в итоге пересечься.
3) Некоторые окна программы подгружается в сторонних решениях на Delphi, что, опять же, не страшно, но надо учитывать и дополнительно тестировать.
4) Сабклассинг и хуки, конечно, не хаки, но уже очень близки (попахивает немного костылями).
Неужели нет иных штатных методов, основанных на сообщениях?
Re[5]: Контроль положения родительского окна из CEdit
Здравствуйте, avnazyrov, Вы писали:
A>Тут есть несколько нюансов. A>1) Контролов может быть несколько на одном окне, что, конечно, легко учитывается, но уже вносит некоторую сложность.
Сабклассингу безразлично.
A>2) В программном комплексе уже и так используются хуки (и их пытаются изжить по требованию начальства). Где — надо узнавать. Не хотелось бы в итоге пересечься.
Сабклассинг внутри процесса не требует хуков. Хуки используются для сабклассинга в чужом процессе.
A>3) Некоторые окна программы подгружается в сторонних решениях на Delphi, что, опять же, не страшно, но надо учитывать и дополнительно тестировать.
Родитель есть родитель даже на Дельфи
A>4) Сабклассинг и хуки, конечно, не хаки, но уже очень близки (попахивает немного костылями).
Это легальные средства, документированные, а никакие не костыли.
A>Неужели нет иных штатных методов, основанных на сообщениях?
Что значит "штатных методов" ? Не шлет родитель чайлдам сообщений при своем передвижении, вот и все. Сабклассинг и есть штатный метод для таких ситуаций.
Можно еще ловить в петле while GetMessage и пересылать нужному окну.
With best regards
Pavel Dvorkin
Re[6]: Контроль положения родительского окна из CEdit
A>>Тут есть несколько нюансов. A>>1) Контролов может быть несколько на одном окне, что, конечно, легко учитывается, но уже вносит некоторую сложность.
PD>Сабклассингу безразлично.
Может, я не правильно понимаю технологию?
К примеру, хуки рекомендуется снимать как можно быстрее.
Если сабклассировать всё время существования edit'а, то проблем не будет, но я видел решение так:
При показе подсказки сохраняем старый адрес функции, ставим свою, в которой в итоге вызывается старая.
При скрытии подсказки возвращаем всё на место.
И это без доработок будет падать...
Но это уже флейм
A>>2) В программном комплексе уже и так используются хуки (и их пытаются изжить по требованию начальства). Где — надо узнавать. Не хотелось бы в итоге пересечься.
PD>Сабклассинг внутри процесса не требует хуков. Хуки используются для сабклассинга в чужом процессе.
В данном случае я имел в виду использование хуков, а не сабклассинга.
A>>3) Некоторые окна программы подгружается в сторонних решениях на Delphi, что, опять же, не страшно, но надо учитывать и дополнительно тестировать.
PD>Родитель есть родитель даже на Дельфи
Не спорю, но тестировать придётся, т.к. были случаи странного поведения вызванных окон.
A>>4) Сабклассинг и хуки, конечно, не хаки, но уже очень близки (попахивает немного костылями).
PD>Это легальные средства, документированные, а никакие не костыли.
Штатные костыли тоже бывают
A>>Неужели нет иных штатных методов, основанных на сообщениях?
PD>Что значит "штатных методов" ? Не шлет родитель чайлдам сообщений при своем передвижении, вот и все. Сабклассинг и есть штатный метод для таких ситуаций.
Если действительно нельзя изменить окно подсказки таким образом, чтобы оно само обрабатывало сообщения, то Вы правы.
PD>Можно еще ловить в петле while GetMessage и пересылать нужному окну.
Хрень редьки...
Ладно, огромное спасибо Вам за помощь, видимо придётся искать какой-то компромис.
Re[5]: Контроль положения родительского окна из CEdit
Здравствуйте, avnazyrov, Вы писали:
RB>>Почему не обычный tooltip, который прячется сам? A>Обычный тултип, кстати, прячется по уходу мышки, либо таймеру.
A>Я хочу реализовать аналог CEdit::ShowBalloonTip(), т.к. юникод в нашей системе пока не используется.
используй напрямую EM_SHOWBALLOONTIP, а не обертки из MFC
на самом деле это сообщение никакого юникода не требует, только commctrl.dll 6-й версии
Re[6]: Контроль положения родительского окна из CEdit
Здравствуйте, Андрей, Вы писали:
А>используй напрямую EM_SHOWBALLOONTIP, а не обертки из MFC А>на самом деле это сообщение никакого юникода не требует, только commctrl.dll 6-й версии
То что надо! Спасибо
Меня смутило то, что обёртка без юникода не работала.
Re[7]: Контроль положения родительского окна из CEdit