Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.29;
Скачать: CL | DM;

Вниз

TForm.OnShow   Найти похожие ветки 

 
begin...end ©   (2004-08-13 16:24) [0]

Событие TForm.OnShow возникает до того, как форма показана, или сразу после этого?
Поясню, для чего это надо.
Нужно следующее: показать форму модально, выполнить некий длительный процесс (всё это время форма показывается и на ней отображается информация о ходе процесса), по окончании процесса форма закрывается. Пользователь может прервать выполнение процесса нажатием кнопки на форме.
Первое, что пришло в мою тупую голову - повесить этот процесс на обработчик OnShow, но, если так сделать, то процесс выполняется, но форма показывается только после его окончания. Т.е. такое впечатление, что форма показывается после OnShow. и ещё есть проблемы с тем, как её потом закрывать. Если это действительно тупой способ (подозреваю), то как ещё можно реализовать задуманное?


 
Ega23 ©   (2004-08-13 16:29) [1]

Application.ProcessMessages поставь


 
begin...end ©   (2004-08-13 16:31) [2]


> [1] Ega23 ©   (13.08.04 16:29)

Ну не настолько же я тупой... :-)
Пробовал, не полегчало.


 
Ega23 ©   (2004-08-13 16:33) [3]

Подожди, этот процесс должен запуститься непосредственно во время показа формы? Точнее, сразу же за её отрисовкой на экране?


 
Ega23 ©   (2004-08-13 16:34) [4]

OnActivate не поможет?


 
begin...end ©   (2004-08-13 16:35) [5]


> [3] Ega23 ©   (13.08.04 16:33)

Да.


 
Sandman25 ©   (2004-08-13 16:35) [6]

MyForm.Show;
MyForm.Update;
MyForm.DoCalculations;


 
begin...end ©   (2004-08-13 16:39) [7]

> Ega23 ©   (13.08.04 16:34) [4]

OnActivate уже пробовал, показывается она нормально, но я не могу её закрыть (т.е. я пытаюсь её закрыть прямо в OnActivate, вызывая после процедуры процесса Hide).

Sandman25 ©   (13.08.04 16:35) [6]

Т.е. немодально? Не хотелось бы...


 
simpson ©   (2004-08-13 16:42) [8]

1. Показать форму.
2. В OnActivate запустить thread, в котором будет протекать "некий длительный процесс".
3. После окончания работы thread, послать сообщение окну и закрыть его. Ну, и в процессе выполнения thread проверять, не нажал ли юзер  кнопку "Отмена"


 
Sandman25 ©   (2004-08-13 17:05) [9]

MyForm.Show;
MyForm.Update;
MyForm.DoCalculations;
MyForm.Hide;
MyForm.ShowModal;


 
Sandman25 ©   (2004-08-13 17:06) [10]

Кстати, какая разница насчет модальности, если по окончании процесса форма закрывается?


 
begin...end ©   (2004-08-13 17:09) [11]


> [9] Sandman25 ©   (13.08.04 17:05)

Э-э... Не понял...

> [10] Sandman25 ©   (13.08.04 17:06)

Просто желательно, чтобы пользователь на время выполнения процесса не имел доступа к главной форме, из которой вызывается вот эта вот, информационная.


 
Sandman25 ©   (2004-08-13 17:12) [12]

[11] begin...end ©   (13.08.04 17:09)

Можно и через ShowModal, но в OnShow перед вычислениями вызвать Self.Update


 
shc   (2004-08-13 17:17) [13]

Начало simpson. Тлько 3)... не процессу опрашивать какой-то флаг, а на кнопку "отмена" повесить посылку прерывания процесса.


 
begin...end ©   (2004-08-13 17:17) [14]


> [12] Sandman25 ©   (13.08.04 17:12)


> в OnShow перед вычислениями вызвать Self.Update

Я и это пробовал, почему-то не помогает.

Хм... А может быть, вызывать немодально, но задизабливать главную форму?


 
Sandman25 ©   (2004-08-13 17:19) [15]

>Хм... А может быть, вызывать немодально, но задизабливать главную форму?

Звучит логично.


 
афвуд   (2004-08-13 17:35) [16]

Сталкивался с проблемой этой.
Решил так:

Код модуля с формочкой. На ней только ProgressBar.

#include <vcl.h>
#pragma hdrstop

#include "ProgressBarUnit.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TProgressBarForm *ProgressBarForm;
//---------------------------------------------------------------------------
__fastcall TProgressBarForm::TProgressBarForm(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TProgressBarForm::Init(int Size)
{
ProgressBar1->Position=0;
ProgressBar1->Max=Size-1;

// проверка - индикатор уже инициализирован?
if (Visible) return;  // уже и так индикатор активен - выход
// настраиваем параметры отображения

//--- дальнейший код взят из TCustomForm.ShowModal и несколько урезан
CancelDrag();
if (GetCapture != 0)SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
ReleaseCapture();
FFormState << fsModal;
//FActiveWindow = GetActiveWindow;
//FSaveCursor = Screen->Cursor;
//Screen->Cursor = crDefault;
FWindowList = DisableTaskWindows(0);
Show();
SendMessage(Handle, CM_ACTIVATE, 0, 0);
//-- конец кода из TCustomFirm.ShowModal
Application->ProcessMessages();

}

void __fastcall TProgressBarForm::Step()
{
ProgressBar1->StepIt();
}
void __fastcall TProgressBarForm::FormDeactivate(TObject *Sender)
{
//Activate();
//SetForegroundWindow(Handle);
}
//---------------------------------------------------------------------------

void __fastcall TProgressBarForm::DeInit()
{
//--- дальнейший код взят из TCustomForm.ShowModal и несколько урезан
// if(GetActiveWindow() != Handle) then FActiveWindow := (0);
Hide();
// Screen.Cursor := FSaveCursor;
EnableTaskWindows(FWindowList);
// if FActiveWindow <> 0 then SetActiveWindow(FActiveWindow);
FFormState >> fsModal;
//--- конец кода, взятого из TCustomForm.ShowModal
}


После это вызывается так:
ProgressBarForm->Init(query->RecordCount);
while(!query->Eof)
 {
 ......
 query->Next();
 ProgressBarForm->Step();
 Application->ProcessMessages();
 }
ProgressBarForm->DeInit();


Работает так, как надо. ProgressBarForm модально открывается, но управляем мы им из процедуры.
Извини за С++ код :) . В приниципе в Дельфи примерно также выглядит.


 
s999   (2004-08-13 17:45) [17]

Попробуй просто в OnShow послать свое сообщение форме (но только через PostMessage), а в обработчике этого сообщения свою тяжелую процедуру и вызывай.


 
begin...end ©   (2004-08-13 18:06) [18]


> [16] афвуд   (13.08.04 17:35)

Спасибо, разберёмся :-)

Всем спасибо.


 
TUser ©   (2004-08-13 21:12) [19]

Весь длинный процесс - в отдеьный поток (убьют меня создатели операционок :)


 
KSergey ©   (2004-08-14 08:54) [20]

> [16] афвуд   (13.08.04 17:35)
> Сталкивался с проблемой этой.
> Решил так:

Прикольно, мой код уже на Си переклали ;) Надо сохранить ;)
Код однозначно идентифицирую по комментарию, так что не отвертитесь. Два разных человека не могут написать абсолютно идентичный комментарий в одном и том же месте ;)
Правда, несколько оригинал (мой) тоже тут вроде подкоцан зачем-то - ну да ладно ;)
И почему-то тут тоже забыли привести объявления используемых переменных, прям как я (FWindowList и т.д.)
Короче забавно ;)

> Код модуля с формочкой. На ней только ProgressBar.

В оригинале там еще кнопка "остановить" и много чего другого, хотя это я уже не приводил, когда выкладывал сей код ;)

> [17] s999   (13.08.04 17:45)

Да, именно так я бы и посоветовал, если "длинный" код спокойно ложится внутрь этой формы. Иначе (для многократного использования этой формы) с.м. [16].


 
афвуд   (2004-08-14 14:24) [21]

KSergey, да это твой код.

Извини забыл поставить (c)KSergey и (c)Borland  :)


 
KSergey ©   (2004-08-14 14:41) [22]

;)


 
Anatoly Podgoretsky ©   (2004-08-14 14:55) [23]

В OnCreate послать себе сообщение или запустить таймер с небольшой задержкой и это все.


 
KSergey ©   (2004-08-14 14:59) [24]

> [23] Anatoly Podgoretsky ©   (14.08.04 14:55)

Для случая, когда именно эта форма используется именно для выполнения этого действия и только этого. Что вполне соответствует вопросу. Для универсальной формы некоего индикатора маненько не канает... Ну не в полной мере во всяком случае. Хотя и туда допилить напильничком можно. Может даже и корректнее будет по сути своей результат.


 
Anatoly Podgoretsky ©   (2004-08-14 15:22) [25]

К него модальная форма и он пытается делать работу в несответствующем обработчике, при том эти обработчики могут сработать более одного раза.


 
KSergey ©   (2004-08-14 15:28) [26]

> [25] Anatoly Podgoretsky ©   (14.08.04 15:22)
> при том эти обработчики могут сработать более
> одного раза.

К стати да, золотые слова!


 
Anatoly Podgoretsky ©   (2004-08-14 15:39) [27]

Не в этом дело, умиляет всегда желание делать это в OnShow и если не надо то закрыть форму, не показывая, это означает что форма не нужна, а программист зачем то пытается ее создавать.
Два варианта решения для его случая указал, пусть выберет любой и не мучается.


 
GuAV ©   (2004-08-14 18:52) [28]

Короче, я как у себя сделал - тупо Enabled в False остальным.

> это в OnShow

Конечно нет.
У меня перед вызовом её конструктора (до длит процесса и по окончании она вообще не существует и переменная её равна nil)



Страницы: 1 вся ветка

Текущий архив: 2004.08.29;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.047 c
1-1092308900
Deedlit
2004-08-12 15:08
2004.08.29
Проблемы с кодировками


14-1091964279
Piter
2004-08-08 15:24
2004.08.29
Интересно :)


1-1092414954
Eugene1501
2004-08-13 20:35
2004.08.29
Access violation Как отловить?


1-1092578584
Makssim
2004-08-15 18:03
2004.08.29
Как получить сегодняшнюю дату?


3-1091612672
veb
2004-08-04 13:44
2004.08.29
Ошибка: Size of optimizer block exceeded