Avatar billede intel4004 Novice
21. februar 2003 - 07:44 Der er 17 kommentarer og
1 løsning

Adressere variable object-variabler i C++ Builder 5

Jeg har problemer med følgende problemstilling:

Jeg husker at VB6 er muligt at lave noget der kaldes control arrays, hvor man laver et array af objekter på en form.

Er dette muligt i C++ builder.

Eksempel:

for (int i=0; i < 3; i++)
{
  ListBox{i}->Items->Add("Noget tekst");
}

Koden "ListBox{i}" fungerer jo ikke, men er min tankegang klar? I for-løkken vil jeg have 3 listboxe som jeg tilføjer en linie til, automatisk vha. af løkkens-tællevariabel.

Er dette muligt i Borland C++ Builder 5??

Mvh Intel4004
Avatar billede olennert Nybegynder
21. februar 2003 - 08:34 #1
Jeg har aldrig arbejdet med C++ Builder, men rent C++-mæssigt bør det være muligt. C++ Builder må tilbyde dig en type, der beskriver dine listboxe, ellers kan du ikke referere til dem fra din kode. Lad os lade som om C++ Builder typen hedder CBListBox. Så laver du

#include <vector>
typedef std::vector<CBListBox*> CBListBoxVector;

og så smider du adressen på hver af dine tre list boxe ind i den vector, og så itererer du igennem vector'en, og kalder Add-metoden (eller hvad den nu kommer til at hedde i C++ Builder).

På denne måde laver du dit eget control array. Det er så muligt at C++ Builder selv understøtter control arrays direkte, men som sagt, jeg aner intet om C++ Builder.
Avatar billede olennert Nybegynder
21. februar 2003 - 08:35 #2
Ups, jeg har kun defineret vector-typen, ikke nogen instans. Så husk at lave en instans af CBListBoxVector. Det er så ind i denne instans du skal smide adressen på hver af dine tre list boxe.
Avatar billede intel4004 Novice
21. februar 2003 - 12:50 #3
Øhh jeg tror jeg ved hvad du mener men jeg startede på C++ for ca. 2 uger siden. Hvordan laver du en instans af vektoren??? ListBoxe i Builder er af typen TListBox og ændre jeg din linie efter den type, får jeg ingen kompiler-fejl, så noget må jo virke :)

Intel4004
Avatar billede doctorseb Nybegynder
21. februar 2003 - 15:02 #4
Hej,

Controller på en form kan refereres vha. af formens Components og Controls list. De holder referencer til hhv. controller eget (owner) af formen og controller der rent visuelt er børn af formen (parent). Det er begge lister du kan tilgå i en for-løkke.

Hvis du ønkser at samholde et antal controller (som er det dit spørgsmål går på), kan du ganske simpelt benytte en TList. Denne kan du så bruge i stil med dit eget eksempel...
Avatar billede intel4004 Novice
21. februar 2003 - 15:30 #5
doctorseb>

Hej - jeg tror nok skal bruge nogle færdige kodeeksempler til den der TList. C++ Builder help forstår jeg for det meste minus af.

Hvor finder jeg den der Component og Controls list ??

Intel4004
Avatar billede doctorseb Nybegynder
21. februar 2003 - 15:44 #6
OK, jeg skal forsøge efter bedste hukommelse (det er lææænge siden jeg har brugt BCB). Til at starte med kan du bare glemme Components og Controls (som iøvrigt er member af TForm, som er den klasse alle dine normale forms arver fra).

Nå.. Når du har smidt de controller (feks. tre listbokse LB1, LB2, LB3) på din form kan du (eksempelvis i formens OnCreate) smide dem ind i en TList således:

FList = new TList(this); /* jeg kan altså ikke huske denne, men det er std ctor for din TList */

FList->Items->Add(LB1);
FList->Items->Add(LB2);
FList->Items->Add(LB3);

for ( int idx = 0; idx < FList->Count; idx++ )
  FList->Items[idx] ... /* er slet ikke sikker på syntaxen her. Afhængig af hvad du vil skal du bruge en typecast, idét FList's items "tror" de er af typen *TObject. */

Det var det.. husk at slette din FList igen når du ikke har brug for den længere.
Avatar billede intel4004 Novice
21. februar 2003 - 16:47 #7
doctorseb>

Nej hvor er C++ Builder hjælpen bare god (NOT)...

Den vil ikke finde sig i (this), hvor du declarer FList.

Fejl: 'this' can only be used within a member function

Intel4004
Avatar billede doctorseb Nybegynder
21. februar 2003 - 20:18 #8
Hejsa,

Jeg har været for hurtig på aftrækkeren. TList ctor'en har ingen parametre. Derfor:

I din klasses (formens) "private:" lav en
  TList FList;

I din klasses OnCreate (eller lignende sted) lav en:
  FList = new TList;

I din klasses OnDestroy lav en:
  delete FList;

Det skulle være det.

Hvis du ikke ønsker besværet med en TList, kan du vælge at placere dine controls på eksempelvis et TPanel. På denne måde bliver dine controls automatisk stoppet ind i TPanel'ets Controls. Så kan du fange dem således:

  for ( int idx = 0; idx < Panel->ControlCount; idx++ )
    ShowMessage(Panel->Controls[idx]->ClassName());

Det fungerer nøjagtigt som ved brug af TList...
Avatar billede doctorseb Nybegynder
21. februar 2003 - 20:21 #9
... og så skal du iøvrigt lige være lidt "opfindsom" med pointere i ovenstående kode. Jeg er vandt til at arbejde med VCL'et i Delphi. (TList FList burde selvfølgelig erklæres som TList *FList)
Avatar billede intel4004 Novice
22. februar 2003 - 13:33 #10
doctorseb>

Ok - nu tror jeg at jeg er tæt på at få det til at fungere :)

Jeg bruger som sagt Borland C++ Builder 5.

Jeg forsøger i øjeblikket med en TPanel kaldet Panel1. I denne eksisterer der 3stk TListBox med navnene LB1, LB2 og LB3.

Jeg forsøger at eksperimentere med de pointere.

Det sidste problem ligger vistnok i for-løkken hvor jeg skal arbejde dynamisk med de 3 listboxe.

Men jeg kan ikke blot skrive:

for (int idx=0; idx < Panel1->ControlCount; idx++)
{
  Panel1->Controls[idx]->Items->Add("Hej");
}

Den siger at items ikke er medlem af TPanel. Skal jeg typecaste noget her, eller ...??

Men fair nok, så prøver jeg det her istedet:

TListBox *FLB; // Denne deklareres globalt

for (int idx=0; idx < Panel1->ControlCount; idx++)
{
  FLB = new TListBox(Panel1->Controls[idx]);
  FLB->Items->Add("hej");
  delete FLB;
}

Ved klik på min TButton som det hele ved, kommer en error frem:
... raised exception class EInvalidOperation with message 'Control '' has no parent window'.

Hvad gør jeg galt ? :)

Intel4004
Avatar billede doctorseb Nybegynder
22. februar 2003 - 16:14 #11
Du bør (og vil!) ikke indsætte ting direkte i Controls-listen. Det jeg skrev var at du ENTEN skal bruge et TPanel eller en TList. Ved TPanel gælder det at dine controller du på design-time dropper på formen, automatisk bliver en del af TPanel's Controls[]. Ved TList skal du gøre det selv...

Hvis du dynamisk vil placere tre listboxe på et eksisterende TPanel, gør således:

for (int idx=0; idx < 3; idx++)
{
  FLB = new TListBox(DinForm);
  FLB->Parent = DitPanel;
  FLB->Items->Add("hej");
}

Formen DinForm er nu owner af dine listbokse, hvilket betyder at den er ansvarlig for at deallokerer dem igen. DitPanel er parent, hvilket betyder at rent visuelt tilhører dine controls DitPanel (hvilket iøvrigt er grunde til fejlbekskeden).

Du har nu tre FLB'ere på dit panel (det er muligt du ikke kan se dem på formen lige med det samme, men der er der). Som en ekstra bonus behøver du ikke selv slette dem igen, idet formen selv gør det.
Avatar billede intel4004 Novice
22. februar 2003 - 22:25 #12
Jeg tror du har mistforstået hvad det er jeg forsøger at gøre.

Jeg vil ikke automatisk oprette nogle komponenter - jeg vil arbejde med dem dynamisk.

Jeg vil kunne addressere til mine tre listboxe via en for-løkke.

Forresten bør jeg nok nævne at det med pointere og ting - er et kapitel jeg endnu ikke er noget til endnu... Jeg er total newbie i C++...

Derfor skal jeg bruge hele eksempler af kode, ikke småstykker :)

Lad os tage en helt anden problemstilling:

Jeg har flere ComboBoxe på min form. Samtidig har ligeså mange edit-felter(TEdit). Hvordan er det muligt at få noget data ind i det edit-felt som ligger lige ved siden af hver combobox ?? Hver par af combobox og edit-felt har samme Tag ...

Intel4004

(Ellers tak for hjælpen indtil videre)
Avatar billede intel4004 Novice
22. februar 2003 - 22:26 #13
Ok - måske ikke total newbie - men ihvertfald begynder...
Avatar billede intel4004 Novice
22. februar 2003 - 22:30 #14
OK - nøgleordet "new" skaber altså et nyt element på formen eller i panelet... Det er ikke det som jeg skal bruge, er det???
Avatar billede doctorseb Nybegynder
23. februar 2003 - 15:33 #15
Pointere er en essentiel del af C(++), som du bør tage fat på i en fart. Specielt i sammenhæng med BCB's VCL er de meget brugte. Alle de steder du ser en * og en -> har du fat i pointere.

Ok... så du har på design-time placeret tre listboxe på et TPanel, er det korrekt? Hvis det er de eneste controller på panelet, kan du adressere dem således:

for ( int idx = 0; idx < Panel->ControlCount; idx++ )
{
  TListBox *L;
  L = (TListBox*)Panel->Controls[idx];
  L->Items->Add("Hej");
}

Mht. til dine comboboxe er der flere muligheder. Den bedste løsning afhænger af flere ting. Hvis du alligevel har valt at benytte Tag-proptertien, kan du vælge at placere adressen på edit-boksen i tag'en på combo'en. Så behøver du ikke "lede" efter den. Prøv følgende:

Combo->Tag = (int)Edit;

Så burde der stå et eller andet i Combo.Tag, som du kan brug som følger:

TEdit *E;
E = (TEdit*)Combo->Tag;
E->Text = "Hej";

Igen snakker vi pointere og fæle typecasts. Derfor: lær dem at kende hurtigst muligt :)
Avatar billede doctorseb Nybegynder
23. februar 2003 - 15:36 #16
Operatoren "new" allokerer plads til en ny "dims" på heapen og returnerer en.. you guessed it.. pointer til starten af det nys allokerede. Og jo, du kommer til at bruge new mange, mange gange...
Avatar billede intel4004 Novice
25. februar 2003 - 07:46 #17
doctorseb>

Jeg takker mange gange for din tålmodighed - min var nemlig ved at løbe ud :)

Men nu fungerer det med TList og det med TPanel endelig. Dog synes jeg det er lettere at bruge en TList, det gør ikke noget man selv skal smide elementerne ind i den.

Men jeg ser nu kraften i sproget - takker mange gange.

Mvh Ole
Avatar billede intel4004 Novice
01. oktober 2013 - 23:35 #18
Det er nu sjovt at læse igen :) Fattede hat dengang - på 2. semester :P
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester