C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Указатель на форму или как?
** Владимир
Отправлено: 20.09.2004, 12:04


Не зарегистрирован







Есть формы MainForm, Form1 и Form2.
Необходимо по выбору в CheckBox1 присвоить указателю FormX адрес формы 1 или 2,
а потом по нажатию на кнопку:
- Button1 вывести соответствующее окно
- Button2 выполнить функцию соответствующей формы.

Подскажите, пожайлуста, как это дело исправить?
Формы Form1 и Form2 должны создаваться.

MainForm.h:

class TMainForm : public TForm
{
...
public:
void *FormX;
};

MainForm.cpp:

#include "Unit1.h" //заголовок Form1
#include "Unit2.h" //заголовок Form2

__fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner)
{
FormX = 0;
}

void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
if(FormX!=0) delete FormX;
}

void __fastcall TMainForm::CheckBox1Click(TObject *Sender)
{
if(FormX!=0) delete FormX;
if(CheckBox1->Checked)
FormX = (TForm1*) new TForm1(this);
else
FormX = (TForm2*) new TForm2(this);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Button1Click(TObject *Sender)
{
if(FormX==0) return;
FormX->ShowModal();  — ОШИБКА
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Button2Click(TObject *Sender)
{
if(FormX==0) return;
FormX->OutSoo();
}
//---------------------------------------------------------------------------

В Form1 и Form2 есть функция OutSoo(), которая допустим выводит сообщение.
AVC
Отправлено: 20.09.2004, 12:55


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE
Подскажите, пожайлуста, как это дело исправить?

Либо Form1 и Form2 должны иметь общего предка, содержащего метод OutSoo
Либо можно добавить свойство у MainForm типа FormNNActive. Тогда код будет смотреться так:
CODE

void __fastcall TMainForm::Button2Click(TObject *Sender)
{
if (FormNNActive == 1) ((TForm1*)(FormaX))->OutSoob();
else if (FormNNActive == 2) ((TForm2*)(FormaX))->OutSoob();
else ???;
}

+
исправьте void* FormaX на TForma* FormaX — тогда заработает вызов FormaX_>ShowModal();
или явно преобразуйте FormaX к классу TForma
+
Это не существенно, но указатели принято сравнивать со значением NULL а не с 0

PS. Форма это не более чем класс.
Doga
Отправлено: 20.09.2004, 13:01


Мастер участка

Группа: Участник
Сообщений: 575



Либо обьявите FormX как:

CODE

TForm *FormX;


либо вызывайте её так:

CODE

((TForm *)FormX)->ShowModal();


Вызов OutSoo() можно сделать так:

CODE

if (((TObject *)FormX)->ClassNameIs("TForm1"))
{
 ((TForm1 *)FormX)->OutSoo();
}
else if (((TObject *)FormX)->ClassNameIs("TForm2"))
{
 ((TForm2 *)FormX)->OutSoo();
}


Или сделать TForm1 и TForm2 наследниками от общего класса с обьявленным методом OutSoo() (напр. TFormOutSoo). Тогда не нужны будут проверки класса формы, а в TMainForm просто обьявить:

CODE

TFormOutSoo *FormX;
Konstantine
Отправлено: 20.09.2004, 13:19


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE (AVC @ 20/09/2004, 13:57)
Либо Form1 и Form2 должны иметь общего предка, содержащего метод OutSoo...

ИМХО, этот метод более удобный, т.к. позволяет бес проблем добавлять новые общие методы, переменные и т.д.
Doga
Отправлено: 20.09.2004, 13:25


Мастер участка

Группа: Участник
Сообщений: 575



2Konstantine

Согласен smile.gif
** Владимир
Отправлено: 22.09.2004, 13:14


Не зарегистрирован







QUOTE (Konstantine @ 20/09/2004, 14:21)
QUOTE (AVC @ 20/09/2004, 13:57)
Либо Form1 и Form2 должны иметь общего предка, содержащего метод OutSoo...

ИМХО, этот метод более удобный, т.к. позволяет бес проблем добавлять новые общие методы, переменные и т.д.

А можно немножко поподробнее?
Как мне в данном случае сделать общего предка?
Konstantine
  Отправлено: 22.09.2004, 13:41


Мастер участка

Группа: Модератор
Сообщений: 545



В *.h файле замечал строку типа:
CODE
class TForm1 : TForm ...
Так вот Это и есть наследование.
Поэтому пишешь объявляешь общий код (напр.: TComForm) с предком TForm, а потом твои две формы должны иметь предком уже не TForm, а TComForm.
Если твои формы должны делать разные действия при вызове общих функций, то эти функции можно переписать.
Причём, насколько Я помню можно даже так:
CODE
class TComForm1:TForm
{virtual void __fastcall ComMetod1();
  virtual void __fastcall ComMetod2(параметры);
  ...
 }
и так далее... Эти методы описывать (писАть код функций) не нада
далее:
CODE
class TForm1:TForm
{void __fastcall ComMetod1();
  void __fastcall ComMetod2(параметры);
  ...
 }
...
аналогично
CODE

class TForm2:TForm
{void __fastcall ComMetod1();
  void __fastcall ComMetod2(параметры);
  ...
 }
...

И в этих классах описываешь эти функции по своему усмотрению.
В общем всё это где-то так и есть...(см.подпись), на завтра уточню и, если никто не положит, то выложу!
Doga
Отправлено: 22.09.2004, 14:22


Мастер участка

Группа: Участник
Сообщений: 575



Создаёшь в проекте новый юнит напр. CommonForm, который будет предком для твоих форм.


CommonForm.h
CODE

//Абстрактный класс
class TCommonForm : public TForm
{
public:
//Абстрактный метод
virtual void __fastcall CommonMethod(...) = 0;
}


Далее...

TForm1.h
CODE

#include "CommonForm.h"

class TForm1 : public TCommonForm
{
public:
virtual void __fastcall CommonMethod(...);
}


TForm1.cpp
CODE

void __fastcall TForm1::CommonMethod(...)
{
//тело процедуры
}


То же самое и для TForm2...

Отредактировано Doga — 23/09/2004, 12:39
AVC
Отправлено: 22.09.2004, 14:42


Ветеран

Группа: Модератор
Сообщений: 1583



2** Владимир
Судя по вашим вопросам напишете, как советовал Doga
CODE

if (((TObject *)FormX)->ClassNameIs("TForm1"))  ((TForm1 *)FormX)->OutSoo();
else if (((TObject *)FormX)->ClassNameIs("TForm2")) ((TForm2 *)FormX)->OutSoo();
else if ...
else ...

и не парьтесь.
Konstantine
Отправлено: 22.09.2004, 15:14


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE (AVC @ 22/09/2004, 15:44)
2** Владимир
...
и не парьтесь.

Но такой код нада писАть при каждом вызове!!!
AVC
Отправлено: 22.09.2004, 15:35


Ветеран

Группа: Модератор
Сообщений: 1583



2Konstantine
Неа. Достаточно написать метод главной формы, который инкапсулирует эти вызовы.
Я же ни в коем случае не настаиваю, что так лучше. Просто это проще для Владимира. (или вам придется рассказывать теорию наследования в примерах, чем окончательно запутаете вопрошающего)
Konstantine
Отправлено: 22.09.2004, 15:53


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE (AVC @ 22/09/2004, 16:37)
2Konstantine
... который инкапсулирует эти вызовы...

Ну.... ДА, тогда согласен.... (в такой обстановке — ДА)
olegenty
Отправлено: 22.09.2004, 15:56


Ветеран

Группа: Модератор
Сообщений: 2412



а вообще — литературку читать надо. я Страуструпа люблю почитать иногда. и кто скажет, что это сложно, я отвечу — читайте Александреску, это действительтно СЛОЖНО.

Вернуться в Вопросы программирования в C++Builder