13. marts 2004 - 15:20Der er
8 kommentarer og 2 løsninger
MDI 'børn' op og i
Åbner under-vinduer v.hj.a.:
procedure TForm1.demo21Click(Sender: TObject); begin Form2:=TForm2.create(Form1); Form2.Show; end;
Men vil gerne have at hvis der allerede findes en version af formen.
Har eksp. lidt med options-available forms - læst lidt osv.Det driller. Bruger: Action:=CaFree; til 'onClose' Kan udelade dette og få et acceptabelt resultat, men er der ikke andre løsninger ?.
Stoney: det lyder spændende.Kan dog ikke forstå det eller ikke få det til at virke. 'min egen kode* ?. Har en form2, der såmænd bare er en lille richediteditor:
procedure TForm2.Button1Click(Sender: TObject); begin If Form2.Caption='Unavngivent dokument' then SaveDialog1.Filename:='' //Hvis der er tale om et nyt dok
Else //tilskrives fildialogen et tomt filnavn Savedialog1.filename:=Form2.caption; //ellers det oprind IF Savedialog1.execute then //Hvis brugeren klikker gem
procedure TForm2.Button2Click(Sender: TObject); begin Edit1.CopyToClipboard; end;
procedure TForm2.Button3Click(Sender: TObject); begin RichEdit1.CopyToClipboard; end;
end.
Desuden har jeg min form1, der jo indeholder en 'mainmenu,, hvor et af punkterne er
...21click, der åbner form 2. Her har jeg prøvet at sætte din kode ind uden held.
Koden til form1 (som mere avancerede programmører sikkert ville kalde mainform)
kan jeg osse liste hvis det hjælper (har osse 2 andre forme i childsystemet - form7 og en a la 'help' - form (kaldes borlandemo..) og nogen standardting - luk winduer -tile.Form3 er en der åbnes ved start (kan ikke helt huske hvordan den opstod - noget med at dobbeltklikke på formen ?).
procedure demo21Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
uses frmmdi3, Unit7, form3bunit;
{$R *.DFM}
procedure TForm1.bn2Click(Sender: TObject); begin If opendialog1.execute then begin Form2:=Tform2.Create(self); Form2.caption:=opendialog1.filename; Form2.Richedit1.lines.loadfromfile(opendialog1.Filename);
Form2.edit1.Text := extractfilename(opendialog1.filename); end; end; procedure TForm1.bn3Click(Sender: TObject); begin If savedialog1.execute then begin
var i:Integer; begin for i:=form1.MDIChildCOUNT-1 downto 0 do Form1.MDIChildren[i].Close; end;
procedure TForm1.tilevinduer1Click(Sender: TObject); begin Tile; end;
procedure TForm1.luk2Click(Sender: TObject); begin Close; end;
procedure TForm1.bnDBigen1Click(Sender: TObject); begin Form3:=TForm3.create(Form1); Form3.Show; end;
procedure TForm1.lukallevinduer1Click(Sender: TObject); var i:Integer; begin For i:=form1.MDIChildCount-1 downto 0 do Form1.MDIChildren[i].close; end;
procedure TForm1.Borlanddemo1Click(Sender: TObject); begin showmessage('on creating a new record - remember to fil in the field = søgeord before toggeling to next record'); end;
procedure TForm1.mindemo1Click(Sender: TObject); begin Form7:=TForm7.create(Form1); Form7.Show; end;
procedure TForm1.demo21Click(Sender: TObject);
begin Form2:=TForm2.create(Form1); Form2.Show;
end;
end.
Håber du kan gennemskue hvad jeg ikke kan forstå ;D
Hej Jan - Sæt du fortsat Action := caFree. Jeg lavede nedenstående funktion for at sikre at jeg ikke åbnede en allerede eksisterende MDI-Child. Måden er meget simpel:
Du har en subform af klassetypen TfrmMDIChild og nu klikker brugeren på knappen igen. Her sender du bare klassen med over og så klarer rutinen det selv. Under alle omstændigheder returneres en instans af TfrmMDIChild (om den er ny eller eksisterende kan du være ligeglad med)
procedure TfrmMain.Button1Click(Sender : TObject); begin FindMDIChild(TfrmMDIChild).Show; end;
function TfrmMain.FindMDIChild(InstanceClass: TComponentClass): TForm; var i : integer; bFound : boolean; begin i := -1; bFound := false; while (i < MDIChildCount - 1) and not bFound do begin inc(i); bFound := MDIChildren[i] is InstanceClass; end; // while if bFound then result := MDIChildren[i] else result := TForm(InstanceClass.NewInstance).Create(self); end;
Humlen i mit SVAR er, at jeg gennemløber en liste af MDI-børn som ligger i main-formen.
Alle de MDI-childs som du kreerer, bliver placeret her og så er det bare at gennemløbe listen og oprette hvis den ikke findes.
Min version er lidt mere avanceret idet den fodres med typen på det MDI-child der skal vises (her TfrmMDIChild) og hvis den ikke findes så oprettes den vha. TForm(InstanceClass.NewInstance).Create(self); - og ja, linien er en smule nørdet men den virker (kan ikke selv forklare den ;-)).
hrc: ja, den ser lidt indviklet ud.Kan ikke helt gennemskue om jeg bare kan kalde min egen form det der mærkelige, men jeg prøver nok i aften så skal jeg melde tilbage Foreløbig tak for indsats.
I din MDIapplikations form laver du ovenstående FindMDIChild funktion (placér den i private delen af form-definitionen og tryk skift-ctrl-C. Fyld koden i og den er kørende.
På din knap kalder du funktionen med den klassedefinitionen på den subform som du vil have vist. Funktionen returnerer denne nedarving - og så kalder jeg den direkte med .Show - det sidste er lidt hacket, men jeg kan godt lide one-liners.
procedure TfrmMain.Button1Click(Sender : TObject); begin // Kald funktionen med definitionen på den form som du vil have vist. Det er // vigtigt at du forstår forskellen mellem en definition og en instans af den. // Her sendes der ingen objekter med over - kun definitionen. // ... og da den er garanteret at returnere en af TForm tillader jeg mig at // skrive .Show; bagefter
FindMDIChild(TfrmMDIChild).Show; end;
function TfrmMain.FindMDIChild(InstanceClass: TComponentClass): TForm; var i : integer; bFound : boolean; begin // Søg efter eksisterende instanser i listen af MDIChildren i := -1; bFound := false; while (i < MDIChildCount - 1) and not bFound do begin inc(i); bFound := (MDIChildren[i] is InstanceClass); // hvis true, så eksisterer den end; // while
// Hvis fundet så returnér den, ellers returnér nyoprettet if bFound then result := MDIChildren[i] else result := TForm(InstanceClass.NewInstance).Create(self); end;
Jeg håber at du kan få den til at virke for jeg vil ikke have points for noget der ikke dur. Jeg lavede rutinen idet jeg engang arbejdede på en applikation der åbnede 15+ MDI-børn. I første omgang måtte hver åbning MDI-børnene have deres egen variant af ovenstående søgerutine, hvor den ledte efter præcis deres definition - og det så ret dumt med al den redundante kode:
procedure TfrmMain.btnSubForm1Click(Sender : TObject); var i : integer; bFound : boolean; SubForm : TSubForm1; begin i := -1; bFound := false; while (i < MDIChildCount - 1) and not bFound do begin inc(i); bFound := MDIChildren[i] is TSubForm1; end; // while
if bFound then SubForm := MDIChildren[i] else begin SubForm := TSubForm.Create(self);
hrc: Jeg er åbenbart ikke så rutineret i MDI-applicationer, som du måske antager. Den eneste måde jeg kan se mig ud af det er hvis du har en eksempel fil jeg kan downloade eller få sendt. Jeg påskønner din indsats uanset om jeg opnår noget konkret resultat på stående fod.Somme tider har jeg kode liggende i noget tid og en eller anden dag når jeg så frem til mine fremskridt på programmeringsfronten. :)
Send mig din en mail på "hrc_public snabela hotmail dot com" så sender jeg dig et eksempel jeg har liggende.
Synes godt om
Ny brugerNybegynder
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.