Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
5-1145681307
mufan
2006-04-22 08:48
2006.12.24
TListView - заполнение ячейки текстом


2-1165300164
ПытливыйУМ
2006-12-05 09:29
2006.12.24
Перемищать форму за WebBrowser


6-1153984676
nuf
2006-07-27 11:17
2006.12.24
как сохранить страничку из интернета


2-1165005267
User7777
2006-12-01 23:34
2006.12.24
нужен таймер с интервалом меньше 1ms


15-1164800476
Quicker
2006-11-29 14:41
2006.12.24
Синтаксис .htaccess





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский