Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TForm.OnShow [D6, WinXP]


Страницы:   1 2

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;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо