Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.24;
Скачать: CL | DM;

Вниз

Как правильно отлавить изменение 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;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.052 c
2-1165260019
funky
2006-12-04 22:20
2006.12.24
Импорт в эксель


2-1165261888
Серега__
2006-12-04 22:51
2006.12.24
Корректное очищение Record - а.


15-1165346981
Kerk
2006-12-05 22:29
2006.12.24
Google оцифрует российские библиотеки


15-1164909916
Leonid Troyanovsky
2006-11-30 21:05
2006.12.24
Шеклтон (Shackleton) Эрнест Генри


3-1160982232
kyn66
2006-10-16 11:03
2006.12.24
Вывод информации нарастающего поля