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

 
Элементы на форме, Динамич.создание/удаление элементов
Schumi
Отправлено: 11.10.2003, 10:25


Машинист паровоза

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



Нужно на форме создать определённое количество,к примеру Label и Memo,установить позицию,а затем удалить.
Понятно,что создавать надо через new,а как потом удалять.
Что нужен массив указателей,чтобы знать ,что удалять?
Admin
Отправлено: 11.10.2003, 10:50


Владимир

Группа: Администратор
Сообщений: 1190



CODE

TLabel *Tl;

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Tl = new TLabel(this);
    Tl->Parent = Form1;
    Tl->Top = 50; Tl->Left = 20; Tl->Caption = "MyLabel1";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
    delete Tl;
}
//------------------------------------------

Георгий
Отправлено: 11.10.2003, 19:55


Почетный железнодорожник

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



Да массив указателей нужен, но можно использовать STL — например контейнер типа стек (проект прилагается):
CODE

stack <TLabel* > LabelPtrs;
stack <TMemo*  > MemoPtrs;

void __fastcall TForm1::Button1Click(TObject *Sender)
{
TLabel* ptrLabel;
ptrLabel=new TLabel(this);
if (!ptrLabel)
       {
       throw Exception("Не достаточно памяти");
       }
LabelPtrs.push(ptrLabel);
ptrLabel->Top=((LabelPtrs.size()-1)%(this->ClientHeight/50))*50;
ptrLabel->Left=((LabelPtrs.size()-1)/(this->ClientHeight/50))*20;
ptrLabel->Caption=LabelPtrs.size();
ptrLabel->Parent=this;

TMemo* ptrMemo;
ptrMemo=new TMemo(this);
if (!ptrMemo)
       {
       throw Exception("Не достаточно памяти");
       }
MemoPtrs.push(ptrMemo);
ptrMemo->Top=((MemoPtrs.size()-1)%(this->ClientHeight/50))*50 + 20;
ptrMemo->Left=((MemoPtrs.size()-1)/(this->ClientHeight/50))*20;
ptrMemo->Height=20;
ptrMemo->Width=20;
ptrMemo->Parent=this;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (!LabelPtrs.empty())
       {
       TLabel* ptrLabel;
       ptrLabel=LabelPtrs.top();
       delete ptrLabel;
       LabelPtrs.pop();
       }
if (!MemoPtrs.empty())
       {
       TMemo* ptrMemo;
       ptrMemo=MemoPtrs.top();
       delete ptrMemo;
       MemoPtrs.pop();
       }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
while (!MemoPtrs.empty())
       {
       delete MemoPtrs.top();
       MemoPtrs.pop();
       }
while (!LabelPtrs.empty())
       {
       delete LabelPtrs.top();
       LabelPtrs.pop();
       }
}


User Attached Image Скачать файл
DynamicCreate.rar


Admin
Отправлено: 12.10.2003, 11:12


Владимир

Группа: Администратор
Сообщений: 1190



А можем это организовать через TList.

CODE

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
TList *MemoList;
TList *LabelList;

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
   MemoList  = new TList;
   LabelList = new TList;
}
//---------------------------------------------------------------------------
// create new TLabel
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   static int i=0;
   TLabel* Tl = new TLabel(this);
   Tl->Parent = Form1;
   Tl->Top = i*15 + 50; Tl->Left = 20;
   Tl->Tag = i++;
   Tl->Caption = "Label"+IntToStr(i);
   Tl->Name = "Label"+IntToStr(i);

   LabelList->Add(Tl);
}
//---------------------------------------------------------------------------
// Create new TMemo
void __fastcall TForm1::Button2Click(TObject *Sender)
{
   static int j=0;
   TMemo* Tm = new TMemo(this);
   Tm->Parent = Form1;
   Tm->Top = j*70 + 50; Tm->Left = 80;
   Tm->Tag = j++;
   Tm->Width = 50; Tm->Height = 50;
   Tm->Name = "Memo"+IntToStr(j);

   MemoList->Add(Tm);
}
//---------------------------------------------------------------------------
// delete component TMemo or TLabel — name for delete — in Edit1
void __fastcall TForm1::Button3Click(TObject *Sender)
{
   AnsiString DeleteName = Edit1->Text;
   TComponent* Tc = Form1->FindComponent(DeleteName);
   if(!Tc) { ShowMessage("Component not found !"); return; }
   TMemo  *vTm;
   TLabel *vTl;
   if(dynamic_cast<TMemo*>(Tc)){ // delete TMemo
      vTm = dynamic_cast<TMemo*>(Tc);
      for(int i=0; i<MemoList->Count; i++)
      if(((TMemo*)MemoList->Items[i])->Tag == vTm->Tag)
         { MemoList->Delete(i); delete vTm; break; }
      }
   else
    if(dynamic_cast<TLabel*>(Tc)){ // delete TLabel
      vTl = dynamic_cast<TLabel*>(Tc);
      for(int i=0; i<LabelList->Count; i++)
       if(((TLabel*)LabelList->Items[i])->Tag == vTl->Tag)
          { LabelList->Delete(i); delete vTl; break; }
      }
    else ShowMessage("Component not in TMemo or TLabel");
}
//---------------------------------------------------------------------------
// set value to TMemo or TLabel from Edit2->Text
void __fastcall TForm1::Button4Click(TObject *Sender)
{
  TComponent* Tc = Form1->FindComponent(Edit1->Text);
  if(!Tc) { ShowMessage("Component not found !"); return; }
  TMemo  *vTm;
  TLabel *vTl;

  if(dynamic_cast<TMemo*>(Tc)){
      vTm = dynamic_cast<TMemo*>(Tc);
      for(int i=0; i<MemoList->Count; i++)
      if(((TMemo*)MemoList->Items[i])->Tag == vTm->Tag)
         { vTm->Lines->Text = Edit2->Text; break; }
      }

  if(dynamic_cast<TLabel*>(Tc)){
      vTl = dynamic_cast<TLabel*>(Tc);
      for(int i=0; i<LabelList->Count; i++)
       if(((TLabel*)LabelList->Items[i])->Tag == vTl->Tag)
          { vTl->Caption = Edit2->Text; break; }
      }
}
//--------------------------------------------------------------

Admin
Отправлено: 12.10.2003, 11:40


Владимир

Группа: Администратор
Сообщений: 1190



Наверное можно и через 1 общий TList
и без Tag, а по имени.

CODE

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
TList *MLList;

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
  MLList  = new TList;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  static int i=0;
  TLabel* Tl = new TLabel(this);
  Tl->Parent = Form1;
  Tl->Top = i*15 + 50; Tl->Left = 20;
  Tl->Caption = "Label"+IntToStr(i);
  Tl->Name = "Label"+IntToStr(i);
  i++;
  MLList->Add(Tl);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  static int j=0;
  TMemo* Tm = new TMemo(this);
  Tm->Parent = Form1;
  Tm->Top = j*70 + 50; Tm->Left = 80;
  Tm->Width = 50; Tm->Height = 50;
  Tm->Name = "Memo"+IntToStr(j);
  j++;
  MLList->Add(Tm);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
  AnsiString DeleteName = Edit1->Text;
  TComponent* Tc = Form1->FindComponent(DeleteName);
  if(!Tc) { ShowMessage("Component not found !"); return; }

  for(int i=0; i<MLList->Count; i++){
    if(dynamic_cast<TMemo*>(Tc) &&
       dynamic_cast<TMemo*>((TMemo*)MLList->Items[i]))
       {
       TMemo *vTm = dynamic_cast<TMemo*>(Tc);
       if(((TMemo*)MLList->Items[i])->Name == vTm->Name)
         { MLList->Delete(i); delete vTm; break; }
       }
  else
    if(dynamic_cast<TLabel*>(Tc) &&
       dynamic_cast<TLabel*>((TLabel*)MLList->Items[i]))
       {
       TLabel *vTl = dynamic_cast<TLabel*>(Tc);
       if(((TLabel*)MLList->Items[i])->Name == vTl->Name)
         { MLList->Delete(i); delete vTl; break; }
       }
   }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
  TComponent* Tc = Form1->FindComponent(Edit1->Text);
  if(!Tc) { ShowMessage("Component not found !"); return; }

  for(int i=0; i<MLList->Count; i++){
    if(dynamic_cast<TMemo*>(Tc) &&
       dynamic_cast<TMemo*>((TMemo*)MLList->Items[i]))
       {
       TMemo *vTm = dynamic_cast<TMemo*>(Tc);
       if(((TMemo*)MLList->Items[i])->Name == vTm->Name)
         { vTm->Lines->Text = Edit2->Text; break; }
       }
  else
    if(dynamic_cast<TLabel*>(Tc) &&
       dynamic_cast<TLabel*>((TLabel*)MLList->Items[i]))
       {
       TLabel *vTl = dynamic_cast<TLabel*>(Tc);
       if(((TLabel*)MLList->Items[i])->Name == vTl->Name)
         { vTl->Caption = Edit2->Text; break; }
       }
   }
}
//------------------------------------



Отредактировано Admin — 12/10/2003, 12:52
Admin
Отправлено: 12.10.2003, 15:33


Владимир

Группа: Администратор
Сообщений: 1190



Конечно быстрее и проще вот так:

CODE

// удаляем из TList
void __fastcall TForm1::Button3Click(TObject *Sender)
{
AnsiString DeleteName = Edit1->Text;
TComponent* Tc = Form1->FindComponent(DeleteName);
if(!Tc) { ShowMessage("Component not found !"); return; }
if(!dynamic_cast<TMemo*>(Tc) && !dynamic_cast<TLabel*>(Tc))
{ ShowMessage("Component not Memo/Label !"); return; }

AnsiString cName = Tc->Name;
int n;
if((n = MLList->IndexOf(Tc)) == -1) return;

if(dynamic_cast<TMemo*>(Tc)){
TMemo *vTm = dynamic_cast<TMemo*>(Tc);
MLList->Delete(n); delete vTm; vTm = NULL;
}
else
if(dynamic_cast<TLabel*>(Tc)){
TLabel *vTl = dynamic_cast<TLabel*>(Tc);
MLList->Delete(n); delete vTl; vTl = NULL;
}
}
//---------------


// меняем значение Caption у Label, Text у Memo
void __fastcall TForm1::Button4Click(TObject *Sender)
{
TComponent* Tc = Form1->FindComponent(Edit1->Text);
if(!Tc) { ShowMessage("Component not found !"); return; }
if(!dynamic_cast<TMemo*>(Tc) && !dynamic_cast<TLabel*>(Tc))
{ ShowMessage("Component not Memo/Label !"); return; }

AnsiString cName = Tc->Name;
int n;
if((n = MLList->IndexOf(Tc)) == -1) return;

if(dynamic_cast<TMemo*>(Tc))
((TMemo*)Tc)->Lines->Text = Edit2->Text;
else
if(dynamic_cast<TLabel*>(Tc))
((TLabel*)Tc)->Caption = Edit2->Text;
}
//----------------------------------------



Отредактировано Admin — 12/10/2003, 16:36
Георгий
Отправлено: 12.10.2003, 16:28


Почетный железнодорожник

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



Владимир ну ты и разошёлся — сейчас опять будут обвинять, что мы когото пытались запутать smile.gif
Admin
Отправлено: 12.10.2003, 16:51


Владимир

Группа: Администратор
Сообщений: 1190



Да просто сижу на работе, делать нечего, вопросов мало...вот и... smile.gif

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