Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/48: Рейтинг темы: голосов - 48, средняя оценка - 4.69
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
1

Вывести окно с сообщением во время запуска приложения

13.11.2010, 12:21. Показов 9920. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Подскажите если не влом. Сам что-то пока не догадался. В приложении в FormCreate запускается некий сравнительно длительный процесс и форма приложения не сразу появляется. Как бы мне перед самым запуском того процесса вывести на время окошко с сообщением, что идет запуск приложения, а потом уже, после появления главной формы, убрать это окошко? Спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.11.2010, 12:21
Ответы с готовыми решениями:

Из окна приложения в случае ошибки надо вызвать окно с сообщением о ней
У меня есть два окна - одно с основной программой, другое с сообщением об ошибке ввода данных. Как...

Вывести окно с сообщением
всем привет, как можно вывести окно с сообщением о том что надо ввести свое имя, если имя не...

После отображения списка загружаемых файлов всплывает окно "Восстановление запуска" с сообщением об ошибке
Когда открываю компьютер открывается бегущая строка Winfows is loading files, а потом всплывает...

Служба запуска приложения в определенное время
Здравствуйте. Возникла задача: сделать резидентную программу, которая должна висеть все время в...

16
Супер-модератор
8783 / 2536 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
13.11.2010, 12:36 2
AleksBak, ну что сложного, я лично тут уже раз 5 писал примеры... создаете новую форму, переносите из auto-create и в конструкторе главного окна создаете с помощью new эту форму... а в конце кода конструтора убиваете ее... что сложного-то?
1
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
13.11.2010, 13:03  [ТС] 3
Цитата Сообщение от Lord_Voodoo Посмотреть сообщение
AleksBak, ну что сложного, я лично тут уже раз 5 писал примеры... создаете новую форму, переносите из auto-create и в конструкторе главного окна создаете с помощью new эту форму... а в конце кода конструтора убиваете ее... что сложного-то?
Да извините пожалуйста, что глупые вопросы задаю. Я просто с самого начала пошел по неверному пути и все пытался используя ShowMessage это сделать только убрать кнопку Ok в ней. И другие варианты пробывал(MessageBox и пр.), думал что нужен какой-то отдельный поток что ли и пр., но до такого способа как у Вас не догадался. Я теперь поищу информацию как создавать новую форму т.к. не делал этого до сих пор. Спасибо.
0
1702 / 898 / 207
Регистрация: 25.11.2009
Сообщений: 1,847
13.11.2010, 16:21 4
в Unit1.h (или как он у тебя называется), в public
C++
1
TForm* Form2;
в конструкторе формы
C++
1
2
Form2=new TForm(Form1);
Form2->Show();
чтобы убить форму
C++
1
delete Form2;
1
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
14.11.2010, 23:33  [ТС] 5
Форму создал по способу Lelik-pahan, а по способу Lord_Voodoo так и не получилось(еще указывал в меню File->Use Unit... и там указывал чтобы мог обращаться к этой второй форме из основной). Если бы получилось по способу Lord_Voodoo, то было бы хорошо и смог бы легко добавить компонент TProgressBar например. По способу Lelik-pahan не получается добавить такой компонент в созданную форму. Помогите/проясните пожалуйста.
0
Эксперт С++
3953 / 1808 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
15.11.2010, 01:57 6
AleksBak, добавьте в проект новую форму, настройте её как вам нужно, добавьте компоненты и т.д.
Дальше зайдите в опции проекта и уберите созданную форму из авто-создаваемых форм (Auto-created Forms, на форуме обсуждалось не раз).
Дальше вы в праве создавать объекты описанного вами класса (вашей созданной формы).

Создание такое, как выше написал Lelik-pahan, за исключением названия класса. Например:
C++
1
TAboutForm *AF = new TAboutForm(this);
1
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
15.11.2010, 11:08  [ТС] 7
MikeSoft, я сделал все как Вы написали, с Auto-created Forms разобрался и до этого, форма появляется, но почему-то курсор помещенный над ней превращается в часы(т.е. процессор загружен), а на самой форме ничего нет кроме заголовка и пустого окна - см. скриншот. Т.е. что я сделал(извиняюсь если уже надоел):
1. Создал новую форму(как Lord_Voodoo указал) - Form2. Добавил на нее кнопку, Label1.
2. Переместил ее из Auto-created в Available.
3. Не стал ничего добавлять в Unit1.h (закомментировал предыдущее от Lelik-pahan).
4. Написал след. код(на скриншоте тоже он виден):

C++
1
2
3
4
    TForm *Form2 = new TForm(this);
 
    Form2->Caption = "Searching camera.    Please wait...";
    Form2->Show();
и получается как написал ранее - пустое окно без кнопок и лабелов. И при чем на нем курсор превращается в часы(и даже зависание всей программы если кликать по окну). Однако, после запуска основного окна и если ничего не кликать, то пустое окно с новой формой так и остается(если эту форму не уничтожать) и главная форма(норм.) Необходимо отметить, что и по способу Lelik-pahan у меня точно такое же пустое окно с заголовком и такие же зависания если на нем кликать. Я тогда пытался что-то добавлять в форму по способу Lelik-pahan и не получалось(был однако однажды виден "силует" добавляемой кнопки). Я подумал, что способ Lord_Voodoo нужно попробывать, но ничего не получалось(ошибка по обращению к памяти возникала). После того, как Вы пояснили, что нужно сделать, то теперь получается так как выше описал. Помогите пожалуйста.
Миниатюры
Вывести окно с сообщением во время запуска приложения  
0
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
15.11.2010, 18:49  [ТС] 8
Пояснение - если же оставить новую форму в Auto-Created, то она появляется вместе с главной(естественно поздно т.к. у главной в OnCreate идет длительный поиск устройства вначале) и причем в "нормальном" виде т.е. с кнопками и пр.. А если же убрать эту новую форму из Auto-Created, то как писал она появляется первой(теперь мы ее вначале создаем, а потом устройство ищем), но так и остается пустой и даже после того как появится главная форма.

Добавлено через 4 часа 54 минуты
Компоненты вот так создаю и добавляю:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    // создаем временное новое окно для вывода сообщения, что нужно подождать
    TForm *Form2 = new TForm(this);
 
        // добавляем на эту новую форму ProgressBar
    TProgressBar *ProgressBar1 = new TProgressBar(this);
    Form2->InsertControl(ProgressBar1);
 
    // убираем системные иконки у этого окна(все иконки отсутствуют)
    Form2->BorderIcons = TBorderIcons() >> biSystemMenu;
 
    Form2->Caption = "Searching camera.    Please wait...";
    Form2->Show();
Подскажите - так правильно или нет? Вроде работает. (С одной стороны хорошо, что мало подсказывают т.к. самому лучше ковыряться, а с другой непонятно в правильном ли направлении идешь или нет.)

Добавлено через 55 минут
Вроде получилось(так просто все оказалось и столько ненужных телодвижений было совершено). Еще как бы ненужные кликания по этой новой форме запретить бы т.к. и-за них выходит в заголовке формы строка типа "Не отвечает", но основное приложение все-таки запускается спустя положенное время(когда закончен поиск оборудования) и все потом нормально работает.
0
1702 / 898 / 207
Регистрация: 25.11.2009
Сообщений: 1,847
15.11.2010, 19:27 9
попробуй так
C++
1
2
Application->CreateForm(__classid(TForm2), &Form2);
Form2->Show();
Lord_Voodoo, MikeSoft, не могли бы вы мне разъяснить один момент...
В моём лузерском понимании, если мы создаём форму динамически:
C++
1
TAboutForm *AF = new TAboutForm(this);
то её не нужно добавлять в проект.
А формы, добавленные в проект, но убранные из auto-created я всегда создавал так, как написал выше (взял этот код из учебника Культина, когда только знакомился с билдером, так им и пользуюсь)
Ведь, как я понимаю, через new создаётся форма, никак не связанная с той, что была добавлена в проект...
0
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
15.11.2010, 19:34  [ТС] 10
Цитата Сообщение от Lelik-pahan Посмотреть сообщение
попробуй так
C++
1
2
Application->CreateForm(__classid(TForm2), &Form2);
Form2->Show();
Это тоже как вариант и проверял заменяет следующее:
C++
1
2
    // создаем временное новое окно для вывода сообщения, что нужно подождать
    TForm2 *Form2 = new TForm2(this);
Т.е. еще один(3-й) вариант создания формы. Интересно. Сейчас я просто пишу только один из двух вариантов и работает(форму только настариваю предварительно). Если на создаваемой форме или же на основной поместить таймер и запустить его на увеличение ProgressBar1 из новой формы, то это не работает т.к. основное приложение "подвисло" в процессе поиска устройства. Это уже наверно надо в дополнительном потоке сделать. Как бы еще запретить кликания на новой форме. Спасибо.
0
Эксперт С++
3953 / 1808 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
15.11.2010, 21:03 11
Цитата Сообщение от AleksBak Посмотреть сообщение
MikeSoft, я сделал все как Вы написали, с Auto-created Forms разобрался и до этого, форма появляется, но почему-то курсор помещенный над ней превращается в часы(т.е. процессор загружен), а на самой форме ничего нет кроме заголовка и пустого окна - см. скриншот.
Всё из-за того, что вы не разрешаете форме получать сообщения, пришедшие от системы.
Необходимо вызывать методы перерисовки или же использовать Application->ProcessMessages();

Чтобы уже раз и навсегда прояснить данный вопрос, сейчас напишу простенький проект и выложу его здесь...
0
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
15.11.2010, 21:57  [ТС] 12
Цитата Сообщение от MikeSoft Посмотреть сообщение
Всё из-за того, что вы не разрешаете форме получать сообщения, пришедшие от системы.
Необходимо вызывать методы перерисовки или же использовать Application->ProcessMessages();
...
Я уже это писал у себя - не помогло. Вот что я пишу(окончательный вариант) в OnCreate для Form1:
C++
1
2
3
4
5
6
7
8
9
10
11
    // создаем временное новое окно для вывода сообщения, что нужно подождать
//  TForm2 *Form2 = new TForm2(this);
 
    Application->CreateForm(__classid(TForm2), &Form2);
    Form2->Show();
 
    Form2->InitiateAction();   // это наверно лишнее, но без него все то же самое
    Application->ProcessMessages();
 
    // ставим камеру в начальное положение
            ......
При запуске приложения появляется форма2(настроенная предварительно в Редакторе формы -Design). На этой новой форме есть Таймер и ProgressBar. В событии таймера увеличиваю Position этого ProgressBar. Когда появляется эта новая форма2(вышеприведенный код запустился), то она остается в таком виде и далее очевидно идет процесс поиска камеры(длительный), а курсор над этой формой превращается в часы. В этот момент всякие кликания на этой форме какого-нибудь юзера(я пока вместо него) вызывают как бы "зависания" формы и надпись"не отвечает". Спустя опред. время все начинает работать(появляется форма1 и т.д.). Причем самое интересное - если не уничтожать форму2, то по способу ее объявления, что закомментирован в вышеприведенном коде выходит ошибка, что приложение обратилось к памяти и пр.(на английском). Очевидно Таймер на форме2 вызывает эту ошибку. А если так как сейчас написать, то Таймер на форме2 работает(после открытия главной формы), ошибок нет и ProgressBar начинает меняться. А меняться он начинает, как писал, только после открытия главной формы. Вот так. Спасибо.
0
Эксперт С++
3953 / 1808 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
15.11.2010, 22:00 13
Лучший ответ Сообщение было отмечено как решение

Решение

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

Создаём новый VCL-проект, создаём ещё одну форму, которая должна отображать ход загрузки и связываем два юнита между собой (в первом юните - #include "Unit2.h", во втором - #include "Unit1.h").
Теперь необходимо убрать вторую форму из авто-создаваемых. Для этого переходим в "Project" -> "Options" -> "Forms" и убираем Form2 из колонки Auto-Created Forms в Available Forms.
Т.к. по этому действию возникают вопросы, попробую его немного осветить.
Данным действием мы запрещаем компилятору автоматически создавать объект описанного класса.
То есть, добавляя к проекту новую форму, мы по сути добавляем описание нового класса, объект которого по-умолчанию автоматически создаётся вместе с главной формой. Убедится в этом можно заглянув в файл проекта и обратив внимание на строки:
C++
1
2
Application->CreateForm(__classid(TForm1), &Form1);
Application->CreateForm(__classid(TForm2), &Form2);
После того, как мы уберём Form2 из Auto-Created Forms в файле проекта останется только команда создания объекта класса TForm1 (о классе TForm2 упоминания нет).

В описании класса TForm1 нам необходимо добавить одну переменную, которая будет хранить в себе процент загрузки программы.
Для этого переходим к заголовочному файлу Unit1.h и в область public добавляем переменную типа int:
C++
1
2
3
4
// ...
public:     // User declarations
  int LoadPercent;
// ...
Для чего мы это сделали? Для того, чтобы иметь возможность считывать значение из второй формы.

Теперь перейдём ко второй форме.
Подгоним её размер так, как угодно душе (мне захотелось увидеть форму размером 500х30)
Установим BorderStyle в bsNone.
Добавим на неё компоненты классов TProgressBar и TTimer.
Объект ProgressBar1 "размажем" по всей форме, для этого выставим Align в alClient.
Для объекта Timer1 обработаем событие OnTimer и запишем туда следующий код:
C++
1
2
3
4
5
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
  ProgressBar1->Position = Form1->LoadPercent;
  this->Update();
}
Время срабатывания таймера (Interval) установите в 50 мс.

Нерадивый пользователь может попробовать закрыть эту форму посредством нажатия Alt+F4...
Запретим ему эту возможность. Для этого обработаем событие OnCloseQuery для Form2:
C++
1
2
3
4
void __fastcall TForm2::FormCloseQuery(TObject *Sender, bool &CanClose)
{
  CanClose = false;
}
На этом "настройка" второй формы завершена.

Вернёмся к первой форме.
Для того, чтобы показать ход выполнения нам необходим какой-нибудь длительный процесс.
Самое простое, что можно придумать - это создать массив и заполнять его случайными значениями множество раз.
В конструкторе класса TForm1 опишем процесс заполнения массива случайными числами. После чего, конструктор будет иметь следующий вид:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
  LoadPercent = 0; // инициализируем переменную, отображающую ход загрузки.
  int mas[100]; // объявляем массив, который будем заполнять случайными числами.
  srand(time(NULL)); // инициализируем зерно seed системным временем.
 
  TForm2 *Form2 = new TForm2(NULL); // создаём объект класса TForm2.
  Form2->Position = poScreenCenter; // позиция - центр экрана.
  Form2->Show(); // немодально показываем форму.
 
  for (LoadPercent = 0; LoadPercent < 100; LoadPercent+=2) { // в цикле проходим от 0 до 100 с шагом 2.
    Sleep(10 + rand() % 200); // случайное время заморозки действия, необходимо для реализма.
    for (int j = 0; j < 10000; j++) { // перезапишем один и тот же элемент случайным числом 10000 раз.
      mas[LoadPercent] = rand()%9; // случайное число в диапазоне 0-9.
      Application->ProcessMessages(); // обработаем сообщения, пришедшие из ОС.
    }
  }
 
  Form2->Timer1->Enabled = false; // отключаем действие таймера.
  delete Form2; // уничтожаем объект класса TForm2.
  Form2 = NULL; // обнуляем указатель.
}
На этом подготовка проекта завершена. Компилируем и любуемся результатом.
Для тех, у кого остались вопросы - прикладываю проект (созданный в RAD Studio XE).

Скачать проект: LoadingProgress.rar

С уважением, Михаил.
7
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
15.11.2010, 23:04  [ТС] 14
MikeSoft, честно, уже только за то что Вы столько написали и сделали Вам премию или что-то в этом роде нужно. Тут есть "Спасибо", но это так и непонятно. Я в долгу короче. Я собираюсь сейчас проверить. (если бы я знал, что так затянется, то не стал бы связываться, но это не подход и надо все додолбить)

Добавлено через 46 минут
MikeSoft большое человеческое спасибо еще раз. Я прочитал, проверил. Некоторые вещи немного по-другому, но получается, что практически также я делал(под конец). Я решил проверить как будет работать Ваша вещь если в нее добавить код для поиска камеры. Оказалось, что точно также как и у меня. Для того чтобы проверить(если нужно измененный файл Вашего проекта помещу) достаточно проделать элементарные вещи - из вкладки Indy Clients помещаете на основную форму TIdHTTP. В нем, в Request пропишите любой IP(для локальных сетей и начинающийся с 192.ххх.ххх.ххх и при чем такой которого нет в сети - например 192.168.0.139) и такое запишите в конструкторе класса TForm1:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TMemoryStream *InMes = new TMemoryStream();
    TStringList* str=new TStringList;
 
    LoadPercent = 0; // инициализируем переменную, отображающую ход загрузки.
    int mas[100]; // объявляем массив, который будем заполнять случайными числами.
    srand(time(NULL)); // инициализируем зерно seed системным временем.
 
    TForm2 *Form2 = new TForm2(NULL); // создаём объект класса TForm2.
    Form2->Position = poScreenCenter; // позиция - центр экрана.
    Form2->Show(); // немодально показываем форму.
 
    // ставим камеру в начальное положение
    try
    {
        str->Clear();
        Form1->IdHTTP1->Post("http://192.168.0.139", str, InMes);
        Application->ProcessMessages();
        Form1->Label1->Caption = "Camera Ok";
    }
    catch(...)
    {
        Form1->Label1->Caption = "Camera fail";
    }
 
 
    Form2->Timer1->Enabled = false; // отключаем действие таймера.
    delete Form2; // уничтожаем объект класса TForm2.
    Form2 = NULL; // обнуляем указатель.
}
И все. И увидите, что совсем по другому(как я описывал) ведет себя приложение. Для сетей допускаются большие тайм-ауты и тут приложение как бы "подвисает" наверно. Я использовал Ваш пример чтобы показать прямо в нем(извините). Мне надо было с самого начала все подробно указать и пояснить. Извините пожалуйста. Как Вы считаете, что тут можно сделать? Спасибо.
0
Эксперт С++
3953 / 1808 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
15.11.2010, 23:10 15
AleksBak, никаких извинений не нужно. Я не защищал авторских прав на данный код.
Запускать проект не буду, т.к. ошибка очевидна. Вы не указали таймаут, в течении которого будут произведены попытки соединения, чтения.
C++
1
2
HTTP->ReadTimeout = 2000;
HTTP->ConnectTimeout = 2000;
Ну а ещё лучше использовать отдельный поток.
1
10 / 10 / 4
Регистрация: 14.08.2010
Сообщений: 103
15.11.2010, 23:28  [ТС] 16
Цитата Сообщение от MikeSoft Посмотреть сообщение
AleksBak, никаких извинений не нужно. Я не защищал авторских прав на данный код.
Запускать проект не буду, т.к. ошибка очевидна. Вы не указали таймаут, в течении которого будут произведены попытки соединения, чтения.
C++
1
2
HTTP->ReadTimeout = 2000;
HTTP->ConnectTimeout = 2000;
...
Не такой знаток я потому что, но это:
C++
1
2
        Form1->IdHTTP1->ReadTimeout = 2000;
        Form1->IdHTTP1->ConnectTimeout = 2000;
практически не поменяло ничего и наверно тут тайм-ауты в секундах(надо мне почитать). А насчет:
Цитата Сообщение от MikeSoft Посмотреть сообщение
...Ну а ещё лучше использовать отдельный поток.
полностью, к своему стыду, согласен. С самого начала не так сделал. По другому нужно что-то сделать. Спасибо большое еще раз.
0
0 / 0 / 0
Регистрация: 28.10.2014
Сообщений: 46
20.04.2016, 20:59 17
MikeSoft, а можно тоже самое, только для Visual studio?
0
20.04.2016, 20:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.04.2016, 20:59
Помогаю со студенческими работами здесь

Вывести окно с сообщением после того как закончил вводить текст в Memo, который был выведен в RichEdit
Здравствуйте, ситуация такова. На форме есть кнопки начать и установить шаблон, после нажатия на...

Как сохранить время запуска и выключения приложения в бд
Здравствуйте, подскажите пожалуйста как реализовать сохранение даты и времени запуска/выхода из...

Окно программы меняет внешний вид после запуска приложения (ASP.NET)
Когда приложение ASP.NET запускаю, файл открывается в браузере. НО меняется внешний вид окна...

Программа для предотвращения запуска определенных процессов во время работы приложения
Доброго времени суток. Я мало знаком с программированием в целом, и мне нужна помощь, может какие...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru