Форум: "Основная";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];
ВнизКак правильно отлавить изменение Handle компонента? Найти похожие ветки
← →
MegaVolt © (2006-11-09 12:10) [0]Некоторые компоненты при изменении свойств пересоздают себя и в результате изменяется их Handle. В результате другой компонент который слал сообщения первому уже не знает правильный Handle и следовательно сообщения уже не доходят.
Например Listiew при переключении в OwnerDraw...
Как правильно перехватить моменты до и после изменения Handle?
← →
Ketmar © (2006-11-09 12:21) [1]а на кой фиг хранить handle?
← →
MegaVolt © (2006-11-09 12:28) [2]В ToolTip handle окна входит в параметром передаваемым ToolTip. Если окно меняет свой handle то сообщения от ToolTip недоходят и функциональность пропадает. Следовательно перед изменением нужно старые настройки сбросить а после изменения заново настроить.
← →
Ketmar © (2006-11-09 12:54) [3]а чем стандартные хинты не устроили?
← →
DVM © (2006-11-09 13:02) [4]
> Как правильно перехватить моменты до и после изменения Handle?
Самый тупой и простой способ периодически проверять по таймеру.
← →
MegaVolt © (2006-11-09 13:02) [5]Внешним видом.
← →
DVM © (2006-11-09 13:03) [6]
> Внешним видом.
А что внешний вид стандартного хинта нельзя изменить?
← →
MegaVolt © (2006-11-09 13:05) [7]>Самый тупой и простой способ периодически проверять по таймеру.
Я пишу наследника от компонента поэтому должны быть нормальные культурные методы.
Например в лоб. До и после изменения свойств которые вызывают изменение Handle.
Но нутром чувствую что можно просто перекрыть какую то функцию. Например CreateParam и получить нужный результат. Только я не уверен в правильности такого подхода.
← →
MegaVolt © (2006-11-09 13:08) [8]>А что внешний вид стандартного хинта нельзя изменить?
Самому отрисовывать? А зачем мне это? ToolTip великолепно работает, прост в использовании.
← →
Ketmar © (2006-11-09 13:08) [9]>[5] MegaVolt(c) 9-Nov-2006, 13:02
>Внешним видом.
???
← →
DVM © (2006-11-09 13:09) [10]
> пишу наследника от компонента поэтому должны быть нормальные
> культурные методы.
А чем данный подход некультурен?
> Самому отрисовывать?
Погляди: http://rouse.drkb.ru/files/fwhint.zip
← →
Ketmar © (2006-11-09 13:10) [11]обалдеть. вся программа использует стандартные хинты (возможно, с расширеным функционалом), а один "крутой" компонент как обычно ведёт себя некультурно. такие компоненты надо отправлять в топку. а авторов больно бить ногами.
← →
Reindeer Moss Eater © (2006-11-09 13:10) [12]Как правильно перехватить моменты до и после изменения Handle?
Храни его каком-нибудь глобальном списке.
Например прямо в модуле своего чудо-компонента
← →
DVM © (2006-11-09 13:13) [13]
> > пишу наследника от компонента поэтому должны быть нормальные
>
> > культурные методы.
Добавь в свой компонент таймер. Хочешь на API. При создании компонента записываешь в одно из полей Handle окна, по таймеру сверяешь, если не совпадает - правишь поле, правишь хинт.
← →
Reindeer Moss Eater © (2006-11-09 13:15) [14]Добавь в свой компонент таймер.
Зачем такой изврат?
Компонет что, не знает когда он разрушется?
Не может без таймера обновить значение хендла своего окна в списке?
← →
DVM © (2006-11-09 13:19) [15]
> Компонет что, не знает когда он разрушется?
Компонент то знает. Автор вопроса нет.
А еще никто кроме автора не знает что за компонент и.т.д.
Потому я предложил простой и рабочий на все случаи вариант.
← →
Reindeer Moss Eater © (2006-11-09 13:22) [16]А что это за такой полезный компонент получится, если пользователю надо будет самому отслеживать таймером чего-то там внутренне происходящее внутри этого компонента?
Это недоразумение, а не компонент.
← →
DVM © (2006-11-09 13:24) [17]
> А что это за такой полезный компонент получится, если пользователю
> надо будет самому отслеживать таймером чего-то там внутренне
> происходящее внутри этого компонента?
Ты верно не понял идеи. Зачем пользователю что-то там отслеживать?
Компонент в своем конструкторе создает таймер, в деструкторе уничтожает. Между ними пользуется.
← →
DVM © (2006-11-09 13:26) [18]Хотя сообщения от таймера должны тоже окну приходить, а хэндл измениться может, так что опять те же яйца только в профиль :)
← →
Reindeer Moss Eater © (2006-11-09 13:27) [19]Ты сам не понял идеи.
Зачем комоненту самому себя мониторить таймером?
Он же (компонент) без таймера абсолютно точно знает когда у него новый хендл создается.
← →
DVM © (2006-11-09 13:28) [20]
> Он же (компонент) без таймера абсолютно точно знает когда
> у него новый хендл создается.
Да я с этим согласен полностью.
← →
MegaVolt © (2006-11-09 13:30) [21]>обалдеть. вся программа использует стандартные хинты (возможно, с расширеным функционалом), а один "крутой" компонент как обычно ведёт себя некультурно. такие компоненты надо отправлять в топку. а авторов больно бить ногами.
Спасибо. Но если есть желание бить ногами милости просим. Все претензии к Борланд. Возьми TListView и посмотри какой стандартный Hint там вылазит когда текст в ячейку не влазит. Если не знаешь то там вылазит как раз ToolTip и смотрится он там очень кстати и до сих пор никто не жаловался что он там плохо смотрится.
>Храни его каком-нибудь глобальном списке.
Например прямо в модуле своего чудо-компонента
Я кажется не спрашиваю где хранить я спрашиваю как отловить изменение.
>Зачем такой изврат?
Спасибо за понимание.
>Компонет что, не знает когда он разрушется?
Знает только вот где именно это происходит я не совсем понимаю. Компонент стандартный ListView.
Очень поже что тут:
procedure TCustomListView.ResetExStyles;
...
ListView_SetExtendedListViewStyle(Handle, Styles);
...
или после вызова RecreateWnd
← →
Reindeer Moss Eater © (2006-11-09 13:32) [22]А вообще задача бессмысленная.
Если в каком-то месте хранится голый хендл (целое) причем хендл может стать неактуальным, значит нужна функция, возвращающая хендл, а не
просто переменная , проинициализированная однажды.
Идем дальше.
Компонентов много а не один.
У функции появляется параметр, идентифицирующий нужный нам компонент.
Итого: у нас есть или ссылка на сам компонент, или имя, по которому мы его сможем найти.
Вопрос:
нафига нам хранить хендл сбоку, если мы его можем спросить у самого найденного компонента?
← →
Ketmar © (2006-11-09 14:00) [23]>[21] MegaVolt(c) 9-Nov-2006, 13:30
>Все претензии к Борланд. Возьми TListView и посмотри
ты будешь смеяться: этот тултип вовсе не Borland рисует.
← →
MegaVolt © (2006-11-09 14:19) [24]>ты будешь смеяться: этот тултип вовсе не Borland рисует.
Рисует не борланд всё правильно. Хотя мог бы быть стандартный Hint :) Так что это нормально когда один компонент исспользует разные подсказки.
>А вообще задача бессмысленная. Если в каком-то месте хранится голый хендл (целое) причем хендл может стать неактуальным, значит нужна функция, возвращающая хендл, а не просто переменная , проинициализированная однажды.
Это к MicroSoft претензии? Чем я могу могу помочь? ToolTip при настройке принимает Handle окна с которого он перехватывает сообщения мыши. Он внутри себя хранит. Если же я что то меняю у ListView у него меняется Handle и ToolTip перестаёт работать как положено.
Подскажите в каком месте ListView происходит это изменение.
← →
Reindeer Moss Eater © (2006-11-09 14:29) [25]Некоторые компоненты при изменении свойств пересоздают себя
Ну скажем так, не всего себя а всего лишь окно.
Подскажите в каком месте ListView происходит это изменение.
например здесь
procedure TCustomListView.SetOwnerDraw(Value: Boolean);
begin
if FOwnerDraw <> Value then
begin
FOwnerDraw := Value;
RecreateWnd;
end;
end;
← →
DiamondShark © (2006-11-09 14:38) [26]перекрой CreateHandle
после вызова унаследованного метода оповещай кого хочешь, что handle изменился.
← →
MegaVolt © (2006-11-09 15:00) [27]>например здесь
Это одно из мест. Таких вызовов RecreateWnd много.
>перекрой CreateHandle
ага то что доктор прописал. Спасибо. Жаль только что этот метод невидим в TListView
← →
MegaVolt © (2006-11-09 15:03) [28]CreateWnd уже есть в CustomListView но опять же недоступен в ListView.
Что делать?
← →
MegaVolt © (2006-11-09 15:15) [29]Наследовать от CustomListView?
← →
MegaVolt © (2006-11-09 15:40) [30]Сделал проще:
procedure TListViewEx.CMRecreateWnd(var Message: TMessage);
begin
//Тута Handle старый
inherited;
//Тута Handle новый
end;
Спасибо вопрос решен :)
← →
icWasya © (2006-11-09 15:49) [31]>>перекрой CreateHandle
>ага то что доктор прописал. Спасибо.
Жаль только что этот метод невидим в TListView
TListView->TCustomListView->TWinControl
у TWinControl есть метод
protected
....
procedure CreateHandle; virtual;// Delphi5, Controls.Pas(1103)
Так что значит невидим???
← →
MegaVolt © (2006-11-09 16:05) [32]>Так что значит невидим???
то и значит что он protected. Т.е. видим только потомку TWinControl а именно TCustomListView. И так как TCustomListView не переопределяет видимость то в ListView этот метод уже недоступен :(
А так как в реальности цепочка чуть длиннее и за TWinControl идёт не TCustomListView а TCustomMultiSelectListControl то CreateHandle и в TCustomListView невидим.
← →
Ketmar © (2006-11-09 16:12) [33]>[32] MegaVolt(c) 9-Nov-2006, 16:05
>то и значит что он protected. Т.е. видим только потомку
>TWinControl а именно TCustomListView. И так как
>TCustomListView не переопределяет видимость то в ListView
>этот метод уже недоступен :(
это что за бред???
← →
MegaVolt © (2006-11-09 16:37) [34]>это что за бред???
Хм... Получается я фразу "доступны в классах, являющихся потомками данного класса" воспринимал неправильно? Очень интересно :( Я считал что потомком считается клас Class2 непосредственно унаследованный от данного Class1.
Это несколько меняет дело :)
Но опять же если мне нужны два события до и после нужно наследовать и CreateHandle и DestroyHandle.
Что правильней? Мой вариант с перехватом сообщения или перекрытие двух методов.
← →
Ketmar © (2006-11-09 16:41) [35]>[34] MegaVolt(c) 9-Nov-2006, 16:37
>Хм... Получается я фразу "доступны в классах, являющихся
>потомками данного класса" воспринимал неправильно?
неправильно. ты тоже потомок своего дедушки, хоть и не непосредственный (иногда русский язык меня удивляет...). %-)
>Что правильней? Мой вариант с перехватом сообщения или
>перекрытие двух методов.
лучше методы. сообщения зависят от диспетчера, а методы вызываются когда надо. %-)
← →
MegaVolt © (2006-11-09 16:52) [36]Т.е. когда я в обработчике сообщения потомка пишу inherited, то я вызываю обработчик этого же сообщения в предке не непосредственно, а как то иначе?
Ведь CreateHandle и DestroyHandle вызываются в обработчике этого же сообщения только описанного в TWinControl;
procedure TWinControl.CMRecreateWnd(var Message: TMessage);
var
WasFocused: Boolean;
begin
....
DestroyHandle;
UpdateControlState; // вызывает CreateHandle
...
end;
← →
Ketmar © (2006-11-09 16:57) [37]>[36] MegaVolt(c) 9-Nov-2006, 16:52
>Т.е. когда я в обработчике сообщения потомка пишу
>inherited, то я вызываю обработчик этого же сообщения в
>предке не непосредственно, а как то иначе?
слушай, ну не лезь ты туда. оно тебе надо сейчас?
>Ведь CreateHandle и DestroyHandle вызываются в обработчике
>этого же сообщения только описанного в TWinControl;
а могут и не оттуда. мало ли.
← →
Ketmar © (2006-11-09 16:57) [38]в смысле -- "не лезь в тонкости реализации классов, VMT и прочего".
← →
MegaVolt © (2006-11-09 17:01) [39]>в смысле -- "не лезь в тонкости реализации классов, VMT и прочего".
почему? Судя по ассемблерному коду вызывается непосредственно функция из предка.
ListViewEx.pas.332: inherited;
0049D518 E8E713FCFF call TWinControl.CMRecreateWnd
Или реализация inherited для сообщений может быть изменена в будущем?
← →
Ketmar © (2006-11-09 17:03) [40]sigh...
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.041 c