Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно отлавить изменение Handle компонента? [D7, Win95/98, WinXP]


Страницы:   1 2 3

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;


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо