Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическое создание и разрушение формы 
V
    Опции темы
Kirgston
Дата 7.1.2010, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Всем доброго времени суток. Вот собственно что то до конца не понимаю... создаю форму так:
Application->CreateForm(__classid(TForm2), &Form2);
Когда моя форма отработала (ту какую я динамически создал) я делаю Form2->Free(); в итоге получаю ошибку Аксесс Виолейшен и форма не очищается из памяти а дальше там висит (ну если я правильно понял). Как правильно "удалять" форму?

Под словами динамическое создание имел ввиду то что форму создаю не при старте программы а в нужный мне момент. Спасибо!
PM MAIL   Вверх
pdbq
  Дата 7.1.2010, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 15.5.2008

Репутация: нет
Всего: нет



возможно я не прав но попробуйте так:
Код

Form = new TForm(this);
Form->ShowModal();
Form->~TForm();

PM MAIL   Вверх
586
Дата 7.1.2010, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Цитата(pdbq @  7.1.2010,  21:08 Найти цитируемый пост)
Form->~TForm();

нужно уничтожить объект, а не просто вызвать деструктор
Код
Form = new TForm(this);
Form->ShowModal();
delete Form;


Это сообщение отредактировал(а) 586 - 7.1.2010, 21:34
PM   Вверх
vikaz
Дата 7.1.2010, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: 10
Всего: 12



Цитата(Kirgston @  7.1.2010,  22:59 Найти цитируемый пост)
Application->CreateForm(__classid(TForm2), &Form2);

а в чем фишка создания формы таким образом? Почему не:
Код

TForm2 * Form2 = new TForm2 (this);



--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
Kirgston
Дата 8.1.2010, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Цитата(vikaz @  7.1.2010,  21:36 Найти цитируемый пост)
а в чем фишка создания формы таким образом? Почему не:

Ну так делает Билдер. Я так же пробовал. Кстати....
Попробовал так:
Код

TForm2 * Form2 = new TForm2 (this);

В результате на строчке:
Код

Label2->Left=Form2->Width/2 - Label2->Width/2;

Вылетает Access Violation.

PM MAIL   Вверх
vikaz
Дата 8.1.2010, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: 10
Всего: 12



Цитата(Kirgston @  8.1.2010,  10:58 Найти цитируемый пост)
Вылетает Access Violation.

Так и будет! Так как данная строчка не создает глобальный указатель Form2. Я выходил из этого, передавая нужные мне указатели.

Добавлено через 47 секунд
или просто переписать вот так:
Код

Label2->Left=Width/2 - Label2->Width/2;



--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
Kirgston
Дата 8.1.2010, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Хмм... кстати вот вопросик про ту же динамическую форму... вот когда я делаю ShowModal() и открываю модально нужную мне форму. В делфях чтобы выйти из модальной формы я писал Close; Форма сразу закрывалась и управление переходило на строчку ниже после вызова модальной формы. Здесь же не так... да ладно поставил return; но чувствую что это как то нелепо...
PM MAIL   Вверх
SVN74
Дата 8.1.2010, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 11
Всего: 18



Проверьте правильность включений #include - видят ли все друг друга.
Создавать форму можно - Application->CreateForm(__classid(TForm2), &Form2);
В обработчике Form2 (OnClose)  напишите Action = caFree; - (Но после этого уже Form2 не будет доступна, поэтому необходимо будет заново создавать форму).
Закрывать форму можно Form2->Close();
-------------------------------------------------------
Подумайте, нужно ли вам все время очищать память, если Form2 будет вам нужна несколько раз?
Указатель на Form2 - обязательно должен быть виден всей главной форме.

PM MAIL WWW   Вверх
586
Дата 8.1.2010, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 57
Всего: 146



Цитата(Kirgston @  8.1.2010,  13:12 Найти цитируемый пост)
вот когда я делаю ShowModal() и открываю модально нужную мне форму. В делфях чтобы выйти из модальной формы я писал Close; Форма сразу закрывалась и управление переходило на строчку ниже после вызова модальной формы

Чтобы закрыть модальный диалог, измени свойство ModalResult:
Код
void __fastcall TForm2::Button1Click(TObject *Sender)
{
    ModalResult = mrOk;
}

ShowModal() возвратит значение mrOk.

Это сообщение отредактировал(а) 586 - 8.1.2010, 14:33
PM   Вверх
Kirgston
Дата 9.1.2010, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Цитата(586 @  8.1.2010,  14:31 Найти цитируемый пост)
ShowModal() возвратит значение mrOk.

Странно чуток... 
static const ShortInt mrOk = 0x1;
я делал модал резалт не mrOk , а просто 1 (забыл просто про mrOk). В итоге управление не передавалось в место откуда была вызвана модальная форма (конечно вызвана была из другой формы). А кода дальше исполнялся. Может я просто забыл мат часть и всё так и должно быть... а может и очередной баг Билдера 2010  smile 


Цитата(SVN74 @  8.1.2010,  13:39 Найти цитируемый пост)
Создавать форму можно - Application->CreateForm(__classid(TForm2), &Form2);В обработчике Form2 (OnClose)  напишите Action = caFree; - (Но после этого уже Form2 не будет доступна, поэтому необходимо будет заново создавать форму).Закрывать форму можно Form2->Close();

Охххх благодарю!!! Совсем забыл о caFree  smile 


Цитата(SVN74 @  8.1.2010,  13:39 Найти цитируемый пост)
Подумайте, нужно ли вам все время очищать память, если Form2 будет вам нужна несколько раз?

Хм... не знаю сколько раз нужна... но думаю нормальный пользователь запустит её ну 1, ну 2 раза и всё =). К тому же на формочке не мало компонентов. Это что то типа авто обновления. Тот же Indy TCP Client, полосочки всякие, списки и т.д. И в принципе оно не мало жрет оперативки... если скажем там 4 списочка ( ListBox ) и в каждом по 9к записей))))) (меня не бить, сделал я нормально. Бить разрабов игры для какой я делаю авто обновление  smile ). То есть это где то под 1-2 мб оперативки. На скорость я не думаю что будет сильно влиять (спешить то некуда). 
PM MAIL   Вверх
Kirgston
Дата 10.1.2010, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Опять не пойму... сделал вот так:
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream.h>
#include "md5.h"
#include "md5wrapper.h"
#pragma hdrstop
#pragma comment(lib,"Wininet.lib");

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdTCPClient"
#pragma link "IdTCPConnection"
#pragma link "IdAntiFreeze"
#pragma link "IdAntiFreezeBase"
#pragma resource "*.dfm"
TForm2 *Form2;
md5wrapper MD5;
/*TStringList *files=new TStringList;
TStringList *hash=new TStringList;
TStringList *urls=new TStringList;

TStringList *cfiles=new TStringList;
TStringList *chash=new TStringList;  */
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void TForm2::GetUpdateList()
{
    try {
        TC->Connect();
        if (TC->Connected()) {

            int count=0;
            count=TC->IOHandler->ReadInt64();
            TC->IOHandler->ReadStrings(files,count);
            ListBox1->Items=files;

            count=TC->IOHandler->ReadInt64();
            TC->IOHandler->ReadStrings(hash,count);
            ListBox2->Items=hash;

            count=TC->IOHandler->ReadInt64();
            TC->IOHandler->ReadStrings(urls,count);
            ListBox3->Items=urls;

            count=TC->IOHandler->ReadInt64();
            TC->IOHandler->ReadStrings(size,count);
            ListBox4->Items=size;

        }
    } catch (...) {
        Application->MessageBoxA(L"Невозможно соеденится с сервером обновлений!",L"Auto Updater",MB_OK);
        Form2->Close();
        terminate=true;
        Application->ProcessMessages();

    }

}
//---------------------------------------------------------------------------

void TForm2::Search(UnicodeString dir)
{
    bool updated=false;
    ProgressBar1->Position=0;
    ProgressBar1->Max=ListBox1->Count;
    for (int i=0; i < ListBox1->Count; i++) {
        Application->ProcessMessages();
        UnicodeString Name=dir;
        Name+=ListBox1->Items->Strings[i];
        Label2->Caption=L"Текущий файл: "+IntToStr(i)+L" \\ Всего файлов: "+IntToStr(ListBox1->Count);
        Label2->Left=Form2->Width/2 - Label2->Width/2;
        Label3->Caption=Name;
        Label3->Left=Form2->Width/2 - Label3->Width/2;
        if (FileExists(Name)) {
            string Md5=MD5.getHashFromFile(Name.t_str());
            UnicodeString str=Md5.c_str();
            if (str!=ListBox2->Items->Strings[i]) {
                DeleteFile(Name);
                if (!Download(ListBox3->Items->Strings[i],Name,i))
                {
                    UnicodeString tmp=L"Невозможно скачать файл " + ListBox3->Items->Strings[i];
                    Application->MessageBoxA(tmp.w_str(),L"Auto Updater",MB_OK);
                    updated=false;
                }
                else
                    updated=true;
            }
        }
        else
        {
            Download(ListBox3->Items->Strings[i],Name,i);
            updated=true;
        }
        ProgressBar1->Position++;
        Application->ProcessMessages();
    }
    ProgressBar1->Visible=false;
    Label2->Visible=false;
    Label3->Visible=false;
    if (updated) {
        Application->MessageBoxA(L"Обновления успешно установлены!",L"Auto Updater",MB_OK);
    }
    else
     Application->MessageBoxA(L"Ваш игровой клиент не нуждается в обновлениях.",L"Auto Updater",MB_OK);

    Form2->Close();

    //Form2->~TForm2();
    //URLDownloadToFile
}
//---------------------------------------------------------------------------
bool TForm2::Download(AnsiString url,AnsiString dest,int i)
{
    ProgressBar2->Position=0;
    ProgressBar2->Max=StrToInt(ListBox4->Items->Strings[i]);
    char buf[256];
    AnsiString str=dest,agent=0;

    int np;
    bool err;
    err=false;

    HINTERNET session,file;          //PRE_CONFIG_INTERNET_ACCESS INTERNET_OPEN_TYPE_PRECONFIG
    session = InternetOpen(agent.c_str(), PRE_CONFIG_INTERNET_ACCESS, 0, 0, 0);

    file    = InternetOpenUrl(session,url.c_str(), 0, 0, 0, 0);

    DWORD    Code = 0,
    Size = sizeof( Code );
    if (file==NULL)
        err=true;
    else
    if (HttpQueryInfo( file, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, ( LPVOID ) &Code, ( LPDWORD  ) &Size, NULL  ) )
        if (Code!=200)
            err=true;
        else
        {
            unsigned long len=0,offs=0;
            AnsiString buff="";

            if (file!=NULL)
            {
                DWORD Written;
                HANDLE hDestFile = CreateFile(str.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

                if (hDestFile == INVALID_HANDLE_VALUE)
                    err=true;
                else

                do
                {
                    Application->ProcessMessages();
                    InternetReadFile(file, buf, sizeof(buf), &len);
                    if (len>=0)
                    {
                        offs += len;
                        buff=buf;
                        WriteFile(hDestFile, buf, len, &Written, NULL);
                        ProgressBar2->Position+=len;
                        Application->ProcessMessages();
                    }

                    else
                    {
                        int error = GetLastError();
                        err=true;
                        InternetCloseHandle(file);
                        InternetCloseHandle(session);
                        Application->ProcessMessages();
                        ::Sleep(1000);
                        Application->ProcessMessages();
                        session = InternetOpen("Our Agent", PRE_CONFIG_INTERNET_ACCESS, 0, 0, 0);
                        file = InternetOpenUrl(session, url.c_str(), 0, 0, 0, 0);
                        InternetSetFilePointer(file, offs, 0, FILE_BEGIN, 0);
                    }

                } while (len);

                CloseHandle(hDestFile);

             }

            InternetCloseHandle(file);
            InternetCloseHandle(session);


            if (!err)
                return true;
            else
                return false;
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm2::FormDestroy(TObject *Sender)
{
    delete files;
    delete hash;
    delete urls;
    delete size;

    delete cfiles;
    delete chash;
}
//---------------------------------------------------------------------------


void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
    Action=caFree;
}
//---------------------------------------------------------------------------

void __fastcall TForm2::FormCreate(TObject *Sender)
{
    files=new TStringList;
    hash=new TStringList;
    urls=new TStringList;
    size=new TStringList;

    cfiles=new TStringList;
    chash=new TStringList;


}
//---------------------------------------------------------------------------

void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
    Timer1->Enabled=false;

    GetUpdateList();

    if (terminate) {
        return;    
    }
    files->Clear();
    hash->Clear();
    urls->Clear();
    size->Clear();

    cfiles->Clear();
    chash->Clear();
    ProgressBar1->Visible=true;
    Label2->Visible=true;
    Label3->Visible=true;
    Label1->Caption=L"Начата проверка игрового клиента. Пожалуйста дождитесь окончания.";
    Application->ProcessMessages();
    Search(ExtractFilePath(Application->ExeName));
}
//---------------------------------------------------------------------------


После того как происходить Форм Клоус, форм дестрой код в таймере дальше продолжает исполнятся... 
PM MAIL   Вверх
mrbrooks
Дата 11.1.2010, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Kirgston, могу посоветовать:
1. Отказаться от событий OnCreate/OnDestroy. На каком основании - смотри в хелпе или в этой ветке форума. Вопрос обсуждался. Замени соответственно на конструктор формы - где выделяешь память, тот же OnClose - для высвобождения.
2. Работу с сервером вынеси в отдельный класс.
PM MAIL   Вверх
Kirgston
Дата 11.1.2010, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Цитата(mrbrooks @  11.1.2010,  09:12 Найти цитируемый пост)
1. Отказаться от событий OnCreate/OnDestroy. На каком основании - смотри в хелпе или в этой ветке форума. Вопрос обсуждался. Замени соответственно на конструктор формы - где выделяешь память, тот же OnClose - для высвобождения.

Если не сложно скажите как приблизительно называлась тема? Перерыл 2 страницы нашел только 1 тему про форму и то не ту.

PM MAIL   Вверх
mrbrooks
Дата 11.1.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 167
Всего: 306



Цитата(Kirgston @  11.1.2010,  10:22 Найти цитируемый пост)
Если не сложно скажите как приблизительно называлась тема?

сказать не могу, ибо не помню.  smile  по большому счету там была ссылка из хелпа камрад:

Цитата

Note:    Use of the OnCreate event is discouraged in C++Builder because it can interact badly with the form’s constructor. It is recommended that you override the form constructor instead.

PM MAIL   Вверх
Kirgston
Дата 11.1.2010, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 792
Регистрация: 24.12.2007

Репутация: 2
Всего: 2



Кстати опять таки... сделал класс. Сделал свой конструктор + деструктор. Может я просто не так понимаю как оно должно работать... но...  smile 

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

Мне тогда что писать какие то переменные типа mayterminate и проверять их мол надо ли сделать сейчас return и выйти из ф-ции класса или продолжать код? А на выходе из класса уже ставить деструкторы? 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.1923 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.