Отловить завершение создания формы.
От: Alex.Che  
Дата: 02.07.08 15:39
Оценка:
Здравствуйте, ВСЕ !

Несколько заумная задача, но мож кто сталкивался...
Требуется "внутри" некоторого компонента поймать момент,
когда у его формы-владельца уже отработали "загрузчики-конструкторы"
и методы OnCreate (буде таковые имеются), но до того,
как вызван метод Show (этой формы).

Можно, конечно, подменять обработчик OnCreate формы своим обработчиком
(сперва дёргая обработчик формы, а потом верша свои "темные дела"),
но это больно уж некузяво как-то...

Мож форма рассылает че-нить бродкастом?
Или мож есть какие другие решения?..

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 2.1 beta
Re: Отловить завершение создания формы.
От: SergeyIT Россия  
Дата: 02.07.08 15:48
Оценка:
Здравствуйте, 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
Извините, я все еще учусь
Re[2]: Отловить завершение создания формы.
От: Alex.Che  
Дата: 02.07.08 15:55
Оценка:
Привет, SergeyIT!
Вы пишешь 02 июля 2008:

S> А из этого выбрать нельзя?

S> 1. OnCreate
S> 2. OnShow
S> 3. OnActivate
S> 4. OnPaint

Я же сказазал, могу подменить OnCreate (можно и OnShow), но сие не есть комильфо.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 2.1 beta
Re: Отловить завершение создания формы.
От: sz36 Россия  
Дата: 02.07.08 21:45
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>Требуется "внутри" некоторого компонента поймать момент,

AC>когда у его формы-владельца уже отработали "загрузчики-конструкторы"
AC>и методы OnCreate (буде таковые имеются), но до того,
AC>как вызван метод Show (этой формы).

У TComponent есть виртуальный метод Loaded(). Вызывается, когда форма
полностью загружена и создана. Насколько я понимаю, перегрузив его, Вы
получите желаемое.
Re[2]: Отловить завершение создания формы.
От: Alex.Che  
Дата: 03.07.08 08:26
Оценка:
Привет, sz36!
Вы пишешь 03 июля 2008:

AC>> Требуется "внутри" некоторого компонента поймать момент,

AC>> когда у его формы-владельца уже отработали "загрузчики-конструкторы"
AC>> и методы OnCreate (буде таковые имеются), но до того,
AC>> как вызван метод Show (этой формы).

s> У TComponent есть виртуальный метод Loaded(). Вызывается, когда форма

s> полностью загружена и создана. Насколько я понимаю, перегрузив его, Вы
s> получите желаемое.

Нет.
Сперва вызывается Loaded самой формы, потом Loaded дочерних компонентов формы.
И только потом обработчик OnCreate формы.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Отловить завершение создания формы.
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 03.07.08 09:15
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>>> Требуется "внутри" некоторого компонента поймать момент,

AC>>> когда у его формы-владельца уже отработали "загрузчики-конструкторы"
AC>>> и методы OnCreate (буде таковые имеются), но до того,
AC>>> как вызван метод Show (этой формы).

AfterConstruction() перепиши... Он как раз OnCreate() для формы генерит.
P.S. Что-то я не совсем понимаю сокровенный смысл этих телодвижений.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[4]: Отловить завершение создания формы.
От: Alex.Che  
Дата: 03.07.08 11:23
Оценка:
Привет, DarkMaster!
Вы пишешь 03 июля 2008:

D> AfterConstruction() перепиши... Он как раз OnCreate() для формы генерит.


Перекрывать методы формы не имею возможности (по условию).
Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента),
ничего пока не придумалось...

Наверное, на том и остановлюсь.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Отловить завершение создания формы.
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 03.07.08 12:23
Оценка: 4 (1)
Здравствуйте, Alex.Che, Вы писали:

D>> AfterConstruction() перепиши... Он как раз OnCreate() для формы генерит.


AC>Перекрывать методы формы не имею возможности (по условию).

AC>Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента),
AC>ничего пока не придумалось...

AC>Наверное, на том и остановлюсь.


Ну можно еще сделать хук на WM_CREATE и WM_SHOWWINDOW. WM_CREATE получим при создании, WM_SHOWWINDOW — при показе. WM_SHOWWINDOW придет
после создания, но ДО показа...
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re: Отловить завершение создания формы.
От: CTpaHHoe Россия http://ctpahhoe.blogspot.com/
Дата: 03.07.08 13:02
Оценка:
Здравствуйте, Alex.Che, Вы писали:

AC>Требуется "внутри" некоторого компонента поймать момент,

AC>когда у его формы-владельца уже отработали "загрузчики-конструкторы"

Для чего это потребовалось?
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Windows XP 5.1.2600.131072 ... абсолютная тишина
сразу к делу, без приветов. осторожно, злой антиспам
Re: Отловить завершение создания формы.
От: snusmumrick  
Дата: 03.07.08 13:50
Оценка:
Здравствуйте, 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;


Должно работать, но не уверен.
Re[2]: Отловить завершение создания формы.
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 03.07.08 15:48
Оценка:
Здравствуйте, snusmumrick, Вы писали:

S>Здравствуйте, Alex.Che, Вы писали:


AC>>Требуется "внутри" некоторого компонента поймать момент,

S>Если компонент оконный, можно при создании посылать ему сообщение.

S>
S>procedure TMyComponent.AfterConstruction;
S>begin
S>    inherited;
S>    PostMessage(Handle, WM_AFTER_CREATION, 0, 0);
S>end;
S>


Это сообщение будет послано после создания этого компонента на форме, а не всей формы (в принципе если он последний в списке создания — тогда может быть). К тому же PostMessage() поставит сообщение в очередь и вернется. Так что нет гарантии, что WM_AFTER_CREATION будет пойман/обработан именно в момент между Create и Show.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[5]: Отловить завершение создания формы.
От: Leonid Troyanovsky  
Дата: 03.07.08 19:11
Оценка: 6 (1)
Здравствуйте, Alex.Che, Вы писали:

AC>Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента),

AC>ничего пока не придумалось...

Подмени форме WindowProc, а после обработки, скажем, cm_activate
верни на место старую.
--
С уважением, LVT
Re[3]: Отловить завершение создания формы.
От: snusmumrick  
Дата: 03.07.08 20:39
Оценка:
Здравствуйте, DarkMaster, Вы писали:

AC>>>Требуется "внутри" некоторого компонента поймать момент,

S>>Если компонент оконный, можно при создании посылать ему сообщение.

S>>
S>>procedure TMyComponent.AfterConstruction;
S>>begin
S>>    inherited;
S>>    PostMessage(Handle, WM_AFTER_CREATION, 0, 0);
S>>end;
S>>


Да, я ошибся. Не взлетит.

DM>Это сообщение будет послано после создания этого компонента на форме, а не всей формы


Разумеется.

DM>(в принципе если он последний в списке создания — тогда может быть). К тому же PostMessage() поставит сообщение в очередь и вернется.


Разумеется.

DM>Так что нет гарантии, что WM_AFTER_CREATION будет пойман/обработан именно в момент между Create и Show.


Объясняю. Почему-то я решил, что TForm.Show тоже позовёт PostMessage(), то есть сам показ формы будет асинхронным.
Если бы это было так, то сообщение, положенное в очередь раньше (WM_AFTER_CREATION) гарантированно отработало бы раньше.
Однако, TForm.Show на самом деле зовёт Perform, то есть вызов синхронный. В силу этого, TForm.Show
произойдёт раньше, чем обработчик WM_AFTER_CREATION. Факт. Признаю свою ошибку.

Топикстартеру мои извинения.
Re[5]: Отловить завершение создания формы.
От: wallaby  
Дата: 04.07.08 02:23
Оценка: 4 (1)
Здравствуйте, Alex.Che, Вы писали:

AC>Перекрывать методы формы не имею возможности (по условию).


Тогда можно написать компонент, который будет субклассировать (SetWindowLong) окно формы-владельца, перехватывать все посылаемые форме сообщения и обрабатывать подходящее (WM_CREATE, WM_SHOWWINDOW, WM_ACTIVATE или что-то ещё).

Делается примерно так:

В конструкторе компонента (устанавливаем свой метод обработки сообщений)

  FWndHandle:= TWinControl(AOwner).Handle;
  FNewWndProc:= MakeObjectInstance(NewWndProc);
  FOrgWndProc:= TFarProc(GetWindowLong(FWndHandle, gwl_WndProc));
  SetWindowLong(FWndHandle, gwl_WndProc, LongInt(FNewWndProc));
  FWndHooked:= True;


В деструкторе и в обработчике WM_DESTROY компонента (удаляем свой метод обработки сообщений)

  if FWndHooked then begin
    SetWindowLong(FWndHandle, gwl_WndProc, LongInt(FOrgWndProc));
    FreeObjectInstance(FNewWndProc);
    FWndHooked:= False;
  end;


В перекрытом методе DefaultHandler(var Msg) компонента (дабы сообщение попало форме)

  if FWndHooked then with TMessage(Msg) do
    Result:= CallWindowProc(FOrgWndProc, FWndHandle, Msg, WParam, LParam);
---
The optimist proclaims that we live in the best of all possible worlds; and the pessimist fears this is true
Re[6]: Отловить завершение создания формы.
От: Leonid Troyanovsky  
Дата: 04.07.08 09:08
Оценка:
Здравствуйте, wallaby, Вы писали:

W>Тогда можно написать компонент, который будет субклассировать (SetWindowLong) окно формы-владельца


Субклассировать его таким образом из Loaded вряд ли возможна, бо
окна там еще быть не должно.
А если еще следить за созданием окна, то лучше уж хук до конца.

См. также WindowProc.
--
С уважением, LVT
Re[7]: Отловить завершение создания формы.
От: wallaby  
Дата: 04.07.08 09:46
Оценка:
Здравствуйте, 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
Re[6]: Отловить завершение создания формы.
От: Alex.Che  
Дата: 07.07.08 11:02
Оценка:
Привет, Leonid!
Вы пишешь 03 июля 2008:

AC>> Кроме подмены обработчика формы OnCreate (изнутри Loaded компонента),

AC>> ничего пока не придумалось...

LT> Подмени форме WindowProc, а после обработки, скажем, cm_activate

LT> верни на место старую.

Хорошая идея. Спасибо!

Спасибо также всем, участвовавшим в обсуждении.

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.