![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно отлавить изменение Handle компонента? [D7, Win95/98, WinXP]
MegaVolt © (2006-11-09 12:10:00)Некоторые компоненты при изменении свойств пересоздают себя и в результате изменяется их Handle. В результате другой компонент который слал сообщения первому уже не знает правильный Handle и следовательно сообщения уже не доходят.
Например Listiew при переключении в OwnerDraw...
Как правильно перехватить моменты до и после изменения Handle?
MegaVolt (2006-11-09 17:51:00) [1]Ясно.
Короче перекрыл CreateWnd и DestroyWnd
Спасибо.
Ketmar (2006-11-09 17:39:00) [2]>[41] MegaVolt(c) 9-Nov-2006, 17:14
>Экономия в один вызов. Чем плохо?
тем, что ты оптимизируешь то, что оптимизировать не надо. и копаешься в том, что опять же тебе сейчас не надо. любознательность -- она похвальна, но когда в меру. %-) см. [37], последнее предложение.
MegaVolt (2006-11-09 17:19:00) [3]Единственным аргументом как я понимаю может быть то что CreateHandle и DestroyHandle вызываются не только из RecreateWnd но и в других местах.
MegaVolt (2006-11-09 17:14:00) [4]>sigh...
Поясни? чего вздыхаешь в чём я не прав?
ты предлогаешь цепочку такую.
->RecreateWnd->TWinControl.CMRecreateWnd->TListViewEx.DestroyHandle->TWinControl.DestroyHandle->TListViewEx.CreateHandle->TWinControl.CreateHandle->
итого 6 вызовов
я предлогаю
->RecreateWnd->TListViewEx.CMRecreateWnd->TWinControl.CMRecreateWnd->TWinControl.DestroyHandle->TWinControl.CreateHandle->
итого 5 вызовов.
Экономия в один вызов. Чем плохо?
Ketmar (2006-11-09 17:03:00) [5]sigh...
MegaVolt (2006-11-09 17:01:00) [6]>в смысле -- "не лезь в тонкости реализации классов, VMT и прочего".
почему? Судя по ассемблерному коду вызывается непосредственно функция из предка.
ListViewEx.pas.332: inherited;
0049D518 E8E713FCFF call TWinControl.CMRecreateWnd
Или реализация inherited для сообщений может быть изменена в будущем?
Ketmar (2006-11-09 16:57:00) [7]в смысле -- "не лезь в тонкости реализации классов, VMT и прочего".
Ketmar (2006-11-09 16:57:00) [8]>[36] MegaVolt(c) 9-Nov-2006, 16:52
>Т.е. когда я в обработчике сообщения потомка пишу
>inherited, то я вызываю обработчик этого же сообщения в
>предке не непосредственно, а как то иначе?
слушай, ну не лезь ты туда. оно тебе надо сейчас?
>Ведь CreateHandle и DestroyHandle вызываются в обработчике
>этого же сообщения только описанного в TWinControl;
а могут и не оттуда. мало ли.
MegaVolt (2006-11-09 16:52:00) [9]Т.е. когда я в обработчике сообщения потомка пишу inherited, то я вызываю обработчик этого же сообщения в предке не непосредственно, а как то иначе?
Ведь CreateHandle и DestroyHandle вызываются в обработчике этого же сообщения только описанного в TWinControl;
procedure TWinControl.CMRecreateWnd(var Message: TMessage);
var
WasFocused: Boolean;
begin
....
DestroyHandle;
UpdateControlState; // вызывает CreateHandle
...
end;
Ketmar (2006-11-09 16:41:00) [10]>[34] MegaVolt(c) 9-Nov-2006, 16:37
>Хм... Получается я фразу "доступны в классах, являющихся
>потомками данного класса" воспринимал неправильно?
неправильно. ты тоже потомок своего дедушки, хоть и не непосредственный (иногда русский язык меня удивляет...). %-)
>Что правильней? Мой вариант с перехватом сообщения или
>перекрытие двух методов.
лучше методы. сообщения зависят от диспетчера, а методы вызываются когда надо. %-)
MegaVolt (2006-11-09 16:37:00) [11]>это что за бред???
Хм... Получается я фразу "доступны в классах, являющихся потомками данного класса" воспринимал неправильно? Очень интересно :( Я считал что потомком считается клас Class2 непосредственно унаследованный от данного Class1.
Это несколько меняет дело :)
Но опять же если мне нужны два события до и после нужно наследовать и CreateHandle и DestroyHandle.
Что правильней? Мой вариант с перехватом сообщения или перекрытие двух методов.
Ketmar (2006-11-09 16:12:00) [12]>[32] MegaVolt(c) 9-Nov-2006, 16:05
>то и значит что он protected. Т.е. видим только потомку
>TWinControl а именно TCustomListView. И так как
>TCustomListView не переопределяет видимость то в ListView
>этот метод уже недоступен :(
это что за бред???
MegaVolt (2006-11-09 16:05:00) [13]>Так что значит невидим???
то и значит что он protected. Т.е. видим только потомку TWinControl а именно TCustomListView. И так как TCustomListView не переопределяет видимость то в ListView этот метод уже недоступен :(
А так как в реальности цепочка чуть длиннее и за TWinControl идёт не TCustomListView а TCustomMultiSelectListControl то CreateHandle и в TCustomListView невидим.
icWasya (2006-11-09 15:49:00) [14]>>перекрой CreateHandle
>ага то что доктор прописал. Спасибо.
Жаль только что этот метод невидим в TListView
TListView->TCustomListView->TWinControl
у TWinControl есть метод
protected
....
procedure CreateHandle; virtual;// Delphi5, Controls.Pas(1103)
Так что значит невидим???
MegaVolt (2006-11-09 15:40:00) [15]Сделал проще:
procedure TListViewEx.CMRecreateWnd(var Message: TMessage);
begin
//Тута Handle старый
inherited;
//Тута Handle новый
end;
Спасибо вопрос решен :)
MegaVolt (2006-11-09 15:15:00) [16]Наследовать от CustomListView?
MegaVolt (2006-11-09 15:03:00) [17]CreateWnd уже есть в CustomListView но опять же недоступен в ListView.
Что делать?
MegaVolt (2006-11-09 15:00:00) [18]>например здесь
Это одно из мест. Таких вызовов RecreateWnd много.
>перекрой CreateHandle
ага то что доктор прописал. Спасибо. Жаль только что этот метод невидим в TListView
DiamondShark (2006-11-09 14:38:00) [19]перекрой CreateHandle
после вызова унаследованного метода оповещай кого хочешь, что handle изменился.
Reindeer Moss Eater (2006-11-09 14:29:00) [20]Некоторые компоненты при изменении свойств пересоздают себя
Ну скажем так, не всего себя а всего лишь окно.
Подскажите в каком месте ListView происходит это изменение.
например здесь
procedure TCustomListView.SetOwnerDraw(Value: Boolean);
begin
if FOwnerDraw <> Value then
begin
FOwnerDraw := Value;
RecreateWnd;
end;
end;