** Владимир |
Отправлено: 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)->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 просто обьявить:
|
|
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
Согласен
|
|
** Владимир |
Отправлено: 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
|
а вообще — литературку читать надо. я Страуструпа люблю почитать иногда. и кто скажет, что это сложно, я отвечу — читайте Александреску, это действительтно СЛОЖНО.
|
|