![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TForm.OnShow [D6, WinXP]
begin...end © (2004-08-13 16:24:00)Событие TForm.OnShow возникает до того, как форма показана, или сразу после этого?
Поясню, для чего это надо.
Нужно следующее: показать форму модально, выполнить некий длительный процесс (всё это время форма показывается и на ней отображается информация о ходе процесса), по окончании процесса форма закрывается. Пользователь может прервать выполнение процесса нажатием кнопки на форме.
Первое, что пришло в мою тупую голову - повесить этот процесс на обработчик OnShow, но, если так сделать, то процесс выполняется, но форма показывается только после его окончания. Т.е. такое впечатление, что форма показывается после OnShow. и ещё есть проблемы с тем, как её потом закрывать. Если это действительно тупой способ (подозреваю), то как ещё можно реализовать задуманное?
GuAV (2004-08-14 18:52:00) [1]Короче, я как у себя сделал - тупо Enabled в False остальным.
> это в OnShow
Конечно нет.
У меня перед вызовом её конструктора (до длит процесса и по окончании она вообще не существует и переменная её равна nil)
Anatoly Podgoretsky (2004-08-14 15:39:00) [2]Не в этом дело, умиляет всегда желание делать это в OnShow и если не надо то закрыть форму, не показывая, это означает что форма не нужна, а программист зачем то пытается ее создавать.
Два варианта решения для его случая указал, пусть выберет любой и не мучается.
KSergey (2004-08-14 15:28:00) [3]> [25] Anatoly Podgoretsky © (14.08.04 15:22)
> при том эти обработчики могут сработать более
> одного раза.
К стати да, золотые слова!
Anatoly Podgoretsky (2004-08-14 15:22:00) [4]К него модальная форма и он пытается делать работу в несответствующем обработчике, при том эти обработчики могут сработать более одного раза.
KSergey (2004-08-14 14:59:00) [5]> [23] Anatoly Podgoretsky © (14.08.04 14:55)
Для случая, когда именно эта форма используется именно для выполнения этого действия и только этого. Что вполне соответствует вопросу. Для универсальной формы некоего индикатора маненько не канает... Ну не в полной мере во всяком случае. Хотя и туда допилить напильничком можно. Может даже и корректнее будет по сути своей результат.
Anatoly Podgoretsky (2004-08-14 14:55:00) [6]В OnCreate послать себе сообщение или запустить таймер с небольшой задержкой и это все.
KSergey (2004-08-14 14:41:00) [7];)
афвуд (2004-08-14 14:24:00) [8]KSergey, да это твой код.
Извини забыл поставить (c)KSergey и (c)Borland :)
KSergey (2004-08-14 08:54:00) [9]> [16] афвуд (13.08.04 17:35)
> Сталкивался с проблемой этой.
> Решил так:
Прикольно, мой код уже на Си переклали ;) Надо сохранить ;)
Код однозначно идентифицирую по комментарию, так что не отвертитесь. Два разных человека не могут написать абсолютно идентичный комментарий в одном и том же месте ;)
Правда, несколько оригинал (мой) тоже тут вроде подкоцан зачем-то - ну да ладно ;)
И почему-то тут тоже забыли привести объявления используемых переменных, прям как я (FWindowList и т.д.)
Короче забавно ;)
> Код модуля с формочкой. На ней только ProgressBar.
В оригинале там еще кнопка "остановить" и много чего другого, хотя это я уже не приводил, когда выкладывал сей код ;)
> [17] s999 (13.08.04 17:45)
Да, именно так я бы и посоветовал, если "длинный" код спокойно ложится внутрь этой формы. Иначе (для многократного использования этой формы) с.м. [16].
TUser (2004-08-13 21:12:00) [10]Весь длинный процесс - в отдеьный поток (убьют меня создатели операционок :)
begin...end (2004-08-13 18:06:00) [11]
> [16] афвуд (13.08.04 17:35)
Спасибо, разберёмся :-)
Всем спасибо.
s999 (2004-08-13 17:45:00) [12]Попробуй просто в OnShow послать свое сообщение форме (но только через PostMessage), а в обработчике этого сообщения свою тяжелую процедуру и вызывай.
афвуд (2004-08-13 17:35:00) [13]Сталкивался с проблемой этой.
Решил так:
Код модуля с формочкой. На ней только 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 модально открывается, но управляем мы им из процедуры.
Извини за С++ код :) . В приниципе в Дельфи примерно также выглядит.
Sandman25 (2004-08-13 17:19:00) [14]>Хм... А может быть, вызывать немодально, но задизабливать главную форму?
Звучит логично.
begin...end (2004-08-13 17:17:00) [15]
> [12] Sandman25 © (13.08.04 17:12)
> в OnShow перед вычислениями вызвать Self.Update
Я и это пробовал, почему-то не помогает.
Хм... А может быть, вызывать немодально, но задизабливать главную форму?
shc (2004-08-13 17:17:00) [16]Начало simpson. Тлько 3)... не процессу опрашивать какой-то флаг, а на кнопку "отмена" повесить посылку прерывания процесса.
Sandman25 (2004-08-13 17:12:00) [17][11] begin...end © (13.08.04 17:09)
Можно и через ShowModal, но в OnShow перед вычислениями вызвать Self.Update
begin...end (2004-08-13 17:09:00) [18]
> [9] Sandman25 © (13.08.04 17:05)
Э-э... Не понял...
> [10] Sandman25 © (13.08.04 17:06)
Просто желательно, чтобы пользователь на время выполнения процесса не имел доступа к главной форме, из которой вызывается вот эта вот, информационная.
Sandman25 (2004-08-13 17:06:00) [19]Кстати, какая разница насчет модальности, если по окончании процесса форма закрывается?
Sandman25 (2004-08-13 17:05:00) [20]MyForm.Show;
MyForm.Update;
MyForm.DoCalculations;
MyForm.Hide;
MyForm.ShowModal;