link9088 link9089 link9090 link9091 link9092 link9093 link9094 link9095 link9096 link9097 link9098 link9099 link9100 link9101 link9102 link9103 link9104 link9105 link9106 link9107 link9108 link9109 link9110 link9111 link9112 link9113 link9114 link9115 link9116 link9117 link9118 link9119 link9120 link9121 link9122 link9123 link9124 link9125 link9126 link9127 link9128 link9129 link9130 link9131 link9132 link9133 link9134 link9135 link9136 link9137 link9138 link9139 link9140 link9141 link9142 link9143 link9144 link9145 link9146 link9147 link9148 link9149 link9150 link9151 link9152 link9153 link9154 link9155 link9156 link9157 link9158 link9159 link9160 link9161 link9162 link9163 link9164 link9165 link9166 link9167 link9168 link9169 link9170 link9171 link9172 link9173 link9174 link9175 link9176 link9177 link9178 link9179 link9180 link9181 link9182 link9183 link9184 link9185 link9186 link9187 link9188 link9189 link9190 link9191 link9192 link9193 link9194 link9195 link9196 link9197 link9198 link9199 link9200 link9201 link9202 link9203 link9204 link9205 link9206 link9207 link9208 link9209 link9210 link9211 link9212 link9213 link9214 link9215 link9216 link9217 link9218 link9219 link9220 link9221 link9222 link9223 link9224 link9225 link9226 link9227 link9228 link9229
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