Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.036 c