Avatar billede ultik Nybegynder
26. februar 2000 - 16:33 Der er 21 kommentarer og
1 løsning

TPanel - Container - MDI - Class ?

Hej !

Jeg vil lave en MDI applikation, uden standard MDI.........

Meningen er, at jeg vil have et TPanel, som jeg kan klone, istedet for at åbne et nyt child vindue.

Panelet skal indeholde ca. 8 kontroller, og man skal kunne skifte mellem paneler, ved hjælp af et TabSet, ( MEGET ligesom i Stone's Texttool b2 ).

Mit spørgsmål går så på om jeg kan oprette en class, ( af et panel ), der indeholder disse controls, og som jeg så bare kan skjule/vise,

eller kort :

kan jeg "klone" en container, og så få den nye til at indeholde de samme controls, som den samme ? Og hvordan gør jeg det ?

Undskyld for min "lettere" komplikering af dette simple problem...

På forhånd tak, og med venlig hilsen
Ulrik Jensen
ultik@cyberdude.com
Avatar billede lrj Nybegynder
26. februar 2000 - 16:57 #1
Tror du ville kunne drage nytte af at kigge på TFrames - en ny komponent, vistnok kommet til i Delphi 5. Den kan bruges til at lave dine egne sammensatte komponenter, så det er nemmere at genbruge et design.
Avatar billede ultik Nybegynder
26. februar 2000 - 17:21 #2
Er den gratis ? / Kan jeg bruge den til Delphi 3 standard ?

hvis ja til begge, hvor kan jeg så få den ?
Avatar billede lrj Nybegynder
26. februar 2000 - 17:50 #3
Gratis = den følger med Delphi 5 - det er en som Borland har lavet. Med andre ord - du er nødt til at opgradere for at få den.

Men efter at have kigget lidt nærmere på din beskrivelse, kan du jo bare lave et panel med de komponenter på du skal bruge, og så oprette de efterfølgende på nedenstående måde:

var
  nytPanel: TPanel;
begin
  nytPanel := TPanelMedTingPaa.create(Form1);
  nytpanel.parent:= form1;
  nytpanel.top := 34;//så det ikke bliver vist oven i det eksisterende...
end;

Mon det ikke var noget i den stil du ledte feter?

Avatar billede ultik Nybegynder
26. februar 2000 - 18:26 #4
Vil de controls der ligger på den så kunne henvises til som

nytPanel.lblLabelNavn.Caption := '..........'

hvis ikke, så har de jo samme navn som de andre ?
Avatar billede ultik Nybegynder
26. februar 2000 - 18:37 #5
Nej, det for det første kan jeg ikke bare bruge nytPanel.Kontrol

Den kan heller ikke genere det nye panel, den kommer med en fejl om at der allerede eksisterer en kontrol ved et specifikt navn ! Hvordan gør jeg det ?
Avatar billede lrj Nybegynder
26. februar 2000 - 19:45 #6
Jeg vender tilbage i morgen med noget der mindere mere om en løsning..
Avatar billede ultik Nybegynder
26. februar 2000 - 19:59 #7
tak
Avatar billede dj Nybegynder
26. februar 2000 - 20:11 #8
ultik: Det du lige står og mangler der har har jeg faktisk selv lavet til en IRC Klient som jeg er ved at lave som et eksamensprojekt, jeg har da ikke noget imod at give dig løsningen her, og det skal lige siges at nedenstående kode har taget mig en hel dag at få det til at virke ordentligt. Nu kan jeg jo godt se at du har givet pointene til en anden, men måske kan vi finde ud af noget alligevel, da hans forslag desværre nok ikke helt er det som du i dit tilfælde har brug for.

Start med at indsætte følgende komponenter på din form:

Komponent:      Navn:
Tabcontrol      Tabcontrol1
Listbox        LstTab
Listbox        LstIndex

//De 2 listbokse bruges kun til at holde styr på de forskellige paneler
//sådan at hvis man fjerner et panel, og opretter et igen, så bruges
//de tabeller i de 2 listbokse sådan at man sørger for at genbruge
//det hukommelsesområde som det forrige panel brugte.
//derfor skal du bare sætte visible:=false til begge af dem.


Men her er koden:

//Under public declarations tilføjer du følgende:
    { Public declarations }
    Richedit: Array[0..20] of TRichEdit;
    Editfield: Array[0..20] of Tedit;
    NickList: Array[0..20] of Tlistbox;
    Totalcount: integer;
    Sheet: Array[0..20] of Ttabsheet;
    procedure Addtab(navn: string);
    procedure Removetab(index: integer);
    Function tabexists(channel: string):boolean;
    Function tabindex(channel: string):integer;


//derefter tilføjer du disse procedurer og funktioner:

procedure Tform1.Addtab(navn: string);
var
I, index: integer;
begin
index:=tabcontrol1.pagecount;
for I:=0 to lstIndex.items.count-1 do begin
if lstIndex.Items.Strings[I]<>inttostr(I) then begin
index:=I;
break;
end;
end;
sheet[index] := Ttabsheet.create(self);
with sheet[index] do begin
PageControl := tabControl1;
name := 'Sheet'+inttostr(index);
Caption := navn;
end;
lsttab.Items.Insert(index,navn);
lstIndex.Items.insert(index,inttostr(index));
if (navn <> 'Status') and (navn <> 'Messages') then begin

//Istedet for at tilføje disse kontroller som jeg laver her
//Indsætter du istedet for de 8 kontroller som du vil have oprettet på panelet.
nicklist[index] := Tlistbox.Create(tabcontrol1);
with nicklist[index] do
  BEGIN
    Parent := sheet[index];
    width := 128;
    name := 'lstNick'+inttostr(index);
    left := (Form1.ClientWidth - width) div 2;
    top := (Form1.ClientHeight - height) div 2;
    Text:='';
    Multiselect:=true;
    popupmenu:=nickPopup;
    try
    font.name:='Comic Sans MS';
    except
    font.name:='Arial';
    end;
    font.size:=10;
    sorted:=true;
    align:=aLRight;
  END;
end;
Editfield[index] := Tedit.Create(tabcontrol1);
with editfield[index] do
  BEGIN
    Parent := sheet[index];
    width := 128;
    name := 'Edit'+inttostr(index);
    left := (Form1.ClientWidth - width) div 2;
    top := (Form1.ClientHeight - height) div 2;
    Text:='';
    //onkeypress:=EditKeypress;
    font.name:='Arial';
    font.size:=10;
    align:=aLbottom;
  END;
richedit[index] := TRichedit.Create(tabcontrol1);
with richedit[index] do
  BEGIN
    Parent := sheet[index];
    height := 100+totalcount;
    width := 128;
    left := (Form1.ClientWidth - width) div 2;
    top := (Form1.ClientHeight - height) div 2;
    scrollbars:=ssVertical;
    //Onchange:=richChange;
    //OnMouseDown:=RichEditMouseUp;
    lines.clear;
    font.name:='Arial';
    try
    font.name:='Comic Sans MS';
    except
    font.name:='Arial';
    end;
    font.size:=10;
    align:= ALclient;
    cursor:=crarrow;
    readonly:=true;
  END;
end;

procedure Tform1.Removetab(index: integer);
var
I: integer;
begin
if tabcontrol1.pages[index].caption='Status' then exit;
I:=lstchan.items.indexof(tabcontrol1.pages[index].caption);
editfield[I].free;
richedit[I].free;
sheet[I].Free;
lstIndex.Items.delete(I);
lsttab.Items.delete(I);
end;

Function Tform1.tabindex(tab: string):integer;
var
I: integer;
begin
for I:=0 to lsttab.items.count-1 do begin
  if lsttab.items.strings[I] = tab then
  result:=I;
end;
end;

Function Tform1.tabexists(tab: string):boolean;
var
I: integer;
begin
for I:=0 to lsttab.items.count-1 do begin
  if lsttab.items.strings[I] = tab then
  result:=true;
end;
end;


//Da koden er taget fra min IRC Klient som jeg er ved at lave, er der sikkert lige nogle ting som du har lyst til at ændre i koden, bl.a. under AddTab proceduren skal du ændre de 3 komponenter som jeg opretter Runtime til de 8 komponenter som du vil have på hvert panel, og så huske at angive højde, bredde, left og top + parent på alle komponenterne, men de kan bruge de 3 komponenter som jeg opretter som et eksempel på hvordan du skal oprette de 8 komponenter i runtime.

Jeg håber du er lidt erfaren med Delphi, for det vil der nok kræves for at du kan få det til at virke.

PS. De 2 sidste functioner jeg har oprettet og lagt med er nogle som du kan bruge til at finde et index for en af tabsene i panelet og den sidste finder ud af om navnet på en tab allerede findes, dette kan bruges til at undgå fejl senere i din kode.

Mvh. Daniel Møller
SGUFT Software
<<E-mail>>
Firma: sguft@software.dk
privat: dj@software.dk
<<Web>>
Firma: http://surf.to/guf
Avatar billede ultik Nybegynder
26. februar 2000 - 20:47 #9
Jeg har ca. 2 dages erfaring med Delphi, men har tidligere arbejdet i både C++, og for nogle år siden lavede jeg nogle simple Turbo Pascal programmer, men ellers ikke.............

jeg har lavet et point spørgsmål,  gå ind og svar, så kan du få dine points....

Irj : Jeg kan stadig godt bruge din løsning, så kan jeg sammenligne og evt. optimere............
Avatar billede ultik Nybegynder
26. februar 2000 - 20:50 #10
både C++ og Basic skulle der stå............
Avatar billede dj Nybegynder
26. februar 2000 - 20:58 #11
Hej Ultik, Jeg kan desværre ikke se dit spørgsmål nogle stedet, vil du ikke lige sige hvor du har oprettet det henne af ? :)
Avatar billede ultik Nybegynder
26. februar 2000 - 21:02 #12
sorry, sad og læste dit svar efter at have skrevet mit eget........

det skulle være der nu, i Delphi kategorien.......
Avatar billede ultik Nybegynder
26. februar 2000 - 21:03 #13
Avatar billede ultik Nybegynder
26. februar 2000 - 21:05 #14
hmm........

er der ikke et memory problem, jeg mener du allokerer vel plads til 20 af hver af dine controls, trækker det ikke nogle ressourcer ?
Avatar billede dj Nybegynder
26. februar 2000 - 21:09 #15
Ikke noget der kan mærkes, jeg har før lavet controlarrays der går op til omkring 1000 uden at det kunne mærkes på min PIII'er med 192 mb ram.
Så jeg 20 burde enhver maskine kunne trække uden problemer, det svarer jo bare til at du havde 20 af sådan nogle editfelte eller hvad det nu var for en kontrol i et program.

Men hvis du synes kan du jo justere den værdi sådan at den passer til dit program.
Avatar billede ultik Nybegynder
26. februar 2000 - 21:26 #16
jaja, selvfølgelig.......

jeg har tjekket at det virker, og det før det... med enkelte justeringer, ( i en bar applikation altså )

Så tak, collect your points........
Avatar billede lrj Nybegynder
26. februar 2000 - 22:36 #17
Vil du gerne lave din brugergrænseflade 100% dynamisk, kan du bruge TList i stedet for arrays - du kan stadig tilgå med liste[index] måden, men selvfølgelig ikke over max-antal. Fordelen er så, at du kan bruge liste.add(item) når du skal tilføje noget, og kan slette igen med liste.delete(index). Og du kan vente med at oprette de forskellige forms og lignende indtil programmet har brug for det.

Oprettelse af forms i opstarten af et program kan i ekstreme tilfælde tage flere minutter, også på en hurtigere maskine. En Piii med 192 mb ram er jo ikke ligefrem en main-stream-maskine - i hvert fald kan man ikke forvente det af en evt. slutbrugers maskine. Bare en lille note.
Avatar billede ultik Nybegynder
27. februar 2000 - 00:47 #18
Ok, god ide, for her skal jeg tjekke at den ikke tilføjer mere end max, ellers kommer der jo en fejl når den skal deallokere det !

Avatar billede ultik Nybegynder
27. februar 2000 - 12:01 #19
Hmm..........

Den holder da egentlig ikke !

Hvis man bruger TList istedet for arrays, så bliver typen vel til en string, right ?

Paneler : Array[0..20] of TPanel;

Så har man 20 paneler man kan referere til,

men

Paneler : TList;

Så har man vel bare nogle text strenge i en listbox, og kan på den måde ikke komme til at ændre på de forskellige controls ?
Avatar billede lrj Nybegynder
27. februar 2000 - 12:57 #20
En TList indeholder en liste af pointere - det kan være alt fra PChar til forme og hjemmelavede objekter. En TStringList derimod, bruges til at opbevare strenge.

Måde du bruger det på med TPaneler er:

Paneler := TList.creat;
paneler.add(testpanel);

Når du så skal hente et panel ud igen, bruger du ex.:

TPanel(paneler[i]).visible:=true;

altså, du skal typecaste værdien du får ud, da den kun er defineret som et TObject - men typecaster du med TPanel, som er typen på det du har gemt i den (tlisten), har du igen adgang til dit panel.
Avatar billede ultik Nybegynder
27. februar 2000 - 14:18 #21
Okay, sejt nok......

tak !
Avatar billede lrj Nybegynder
27. februar 2000 - 14:21 #22
Intet problem :o)
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