Несколько заумная задача, но мож кто сталкивался...
Требуется "внутри" некоторого компонента поймать момент,
когда у его формы-владельца уже отработали "загрузчики-конструкторы"
и методы OnCreate (буде таковые имеются), но до того,
как вызван метод Show (этой формы).
Можно, конечно, подменять обработчик OnCreate формы своим обработчиком
(сперва дёргая обработчик формы, а потом верша свои "темные дела"),
но это больно уж некузяво как-то...
Мож форма рассылает че-нить бродкастом?
Или мож есть какие другие решения?..
Здравствуйте, Alex.Che, Вы писали: AC>Или мож есть какие другие решения?..
А из этого выбрать нельзя? >From D5 Help
When a form is being created and its Visible property is True, the following events occur in the order listed:
1. OnCreate
2. OnShow
3. OnActivate
4. OnPaint
Здравствуйте, Alex.Che, Вы писали:
AC>Требуется "внутри" некоторого компонента поймать момент, AC>когда у его формы-владельца уже отработали "загрузчики-конструкторы" AC>и методы OnCreate (буде таковые имеются), но до того, AC>как вызван метод Show (этой формы).
У TComponent есть виртуальный метод Loaded(). Вызывается, когда форма
полностью загружена и создана. Насколько я понимаю, перегрузив его, Вы
получите желаемое.
Привет, sz36!
Вы пишешь 03 июля 2008:
AC>> Требуется "внутри" некоторого компонента поймать момент, AC>> когда у его формы-владельца уже отработали "загрузчики-конструкторы" AC>> и методы OnCreate (буде таковые имеются), но до того, AC>> как вызван метод Show (этой формы).
s> У TComponent есть виртуальный метод Loaded(). Вызывается, когда форма s> полностью загружена и создана. Насколько я понимаю, перегрузив его, Вы s> получите желаемое.
Нет.
Сперва вызывается Loaded самой формы, потом Loaded дочерних компонентов формы.
И только потом обработчик OnCreate формы.
Здравствуйте, Alex.Che, Вы писали:
AC>>> Требуется "внутри" некоторого компонента поймать момент, AC>>> когда у его формы-владельца уже отработали "загрузчики-конструкторы" AC>>> и методы OnCreate (буде таковые имеются), но до того, AC>>> как вызван метод Show (этой формы).
AfterConstruction() перепиши... Он как раз OnCreate() для формы генерит.
P.S. Что-то я не совсем понимаю сокровенный смысл этих телодвижений.
Привет, DarkMaster!
Вы пишешь 03 июля 2008:
D> AfterConstruction() перепиши... Он как раз OnCreate() для формы генерит.
Перекрывать методы формы не имею возможности (по условию).
Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента),
ничего пока не придумалось...
Здравствуйте, Alex.Che, Вы писали:
D>> AfterConstruction() перепиши... Он как раз OnCreate() для формы генерит.
AC>Перекрывать методы формы не имею возможности (по условию). AC>Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента), AC>ничего пока не придумалось...
AC>Наверное, на том и остановлюсь.
Ну можно еще сделать хук на WM_CREATE и WM_SHOWWINDOW. WM_CREATE получим при создании, WM_SHOWWINDOW — при показе. WM_SHOWWINDOW придет
после создания, но ДО показа...
Здравствуйте, Alex.Che, Вы писали:
AC>Требуется "внутри" некоторого компонента поймать момент, AC>когда у его формы-владельца уже отработали "загрузчики-конструкторы"
Для чего это потребовалось?
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Windows XP 5.1.2600.131072 ... абсолютная тишина
Здравствуйте, Alex.Che, Вы писали:
AC>Несколько заумная задача, но мож кто сталкивался... AC>Требуется "внутри" некоторого компонента поймать момент, AC>когда у его формы-владельца уже отработали "загрузчики-конструкторы" AC>и методы OnCreate (буде таковые имеются), но до того, AC>как вызван метод Show (этой формы).
Если компонент оконный, можно при создании посылать ему сообщение.
Примерно так:
const
WM_AFTER_CREATION = WM_USER+01;
type
TMyComponent = class(TWinControl)
private
procedure WmAfterCreation(var Msg : TMessage); message WM_AFTER_CREATION;
public
procedure AfterConstruction; override;
end;
//...procedure TMyComponent.AfterConstruction;
begin
inherited;
PostMessage(Handle, WM_AFTER_CREATION, 0, 0);
end;
procedure TMyComponent.WmAfterCreation(var Msg: TMessage);
begin// все формы созданы, но ни одна еще не показанаend;
Здравствуйте, snusmumrick, Вы писали:
S>Здравствуйте, Alex.Che, Вы писали:
AC>>Требуется "внутри" некоторого компонента поймать момент, S>Если компонент оконный, можно при создании посылать ему сообщение.
S>
Это сообщение будет послано после создания этого компонента на форме, а не всей формы (в принципе если он последний в списке создания — тогда может быть). К тому же PostMessage() поставит сообщение в очередь и вернется. Так что нет гарантии, что WM_AFTER_CREATION будет пойман/обработан именно в момент между Create и Show.
Здравствуйте, DarkMaster, Вы писали:
AC>>>Требуется "внутри" некоторого компонента поймать момент, S>>Если компонент оконный, можно при создании посылать ему сообщение.
S>>
Да, я ошибся. Не взлетит.
DM>Это сообщение будет послано после создания этого компонента на форме, а не всей формы
Разумеется.
DM>(в принципе если он последний в списке создания — тогда может быть). К тому же PostMessage() поставит сообщение в очередь и вернется.
Разумеется.
DM>Так что нет гарантии, что WM_AFTER_CREATION будет пойман/обработан именно в момент между Create и Show.
Объясняю. Почему-то я решил, что TForm.Show тоже позовёт PostMessage(), то есть сам показ формы будет асинхронным.
Если бы это было так, то сообщение, положенное в очередь раньше (WM_AFTER_CREATION) гарантированно отработало бы раньше.
Однако, TForm.Show на самом деле зовёт Perform, то есть вызов синхронный. В силу этого, TForm.Show
произойдёт раньше, чем обработчик WM_AFTER_CREATION. Факт. Признаю свою ошибку.
Здравствуйте, Alex.Che, Вы писали:
AC>Перекрывать методы формы не имею возможности (по условию).
Тогда можно написать компонент, который будет субклассировать (SetWindowLong) окно формы-владельца, перехватывать все посылаемые форме сообщения и обрабатывать подходящее (WM_CREATE, WM_SHOWWINDOW, WM_ACTIVATE или что-то ещё).
Делается примерно так:
В конструкторе компонента (устанавливаем свой метод обработки сообщений)
Здравствуйте, wallaby, Вы писали:
W>Тогда можно написать компонент, который будет субклассировать (SetWindowLong) окно формы-владельца
Субклассировать его таким образом из Loaded вряд ли возможна, бо
окна там еще быть не должно.
А если еще следить за созданием окна, то лучше уж хук до конца.
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT>Субклассировать его таким образом из Loaded вряд ли возможна, бо LT>окна там еще быть не должно.
А Loaded тут при чём? Я про него ничего не говорил. Cубклассирование окна формы-владельца делается в конструкторе компонента, я так однажды делал. Дальше этот компонент кидается на форму и в runtime перехватывает все посылаемые форме сообщения. Единственное что забыл сказать — перед субклассированием нужно сделать проверку
if not csDesigning in ComponentState
понятно зачем.
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Привет, Leonid!
Вы пишешь 03 июля 2008:
AC>> Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента), AC>> ничего пока не придумалось...
LT> Подмени форме WindowProc, а после обработки, скажем, cm_activate LT> верни на место старую.