Avatar billede janbb Juniormester
13. marts 2004 - 15:20 Der 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 ?.

M.v.h. Jan
Avatar billede janbb Juniormester
13. marts 2004 - 15:22 #1
ad: Hvis versionen findes skal der ikke åbnes flere formvinduer af samme type altså.
Avatar billede stoney Nybegynder
13. marts 2004 - 15:56 #2
Check om den findes i forvejen inden du creater den

procedure TForm1.Button3Click(Sender: TObject);
var
  myhandle : Hwnd;
begin
myHandle:=FindWindow(nil,'Form1');// form1 er caption

  if myHandle<>0 then
  begin
    // din kode
    showmessage('Form1 findes i forvejen');
  end
  else ShowMessage('Kan ikke finde form1');
end;

Stoney
Avatar billede janbb Juniormester
14. marts 2004 - 02:46 #3
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:

unit frmmdi42;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, DBCtrls, ExtCtrls, Db, DBTables, Grids, DBGrids;

type
  TForm2 = class(TForm)
    RichEdit1: TRichEdit;
    SaveDialog1: TSaveDialog;
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    Button3: TButton;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure SaveDialog1CanClose(Sender: TObject; var CanClose: Boolean);
 
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=CaFree;
end;


procedure TForm2.SaveDialog1CanClose(Sender: TObject;
  var CanClose: Boolean);
begin

richedit1.plaintext := true;
showmessage(richedit1.lines.text);



Richedit1.lines.Savetofile(SaveDialog1.Filename);
//richedit1.plaintext := false;
end;

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

Richedit1.lines.Savetofile(SaveDialog1.Filename);
end;

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 ?).

unit mdiunit52x;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,frmmdi42,
  Menus, ComCtrls, ToolWin, StdCtrls, DBCtrls, Mask, ExtCtrls, ShellApi, Db, DBTables,
  jpeg;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    StatusBar1: TStatusBar;
    OpenDialog1: TOpenDialog;
    bn1: TMenuItem;
    bn2: TMenuItem;
    vindue1: TMenuItem;
    lukvinduer1: TMenuItem;
    tilevinduer1: TMenuItem;
    luk2: TMenuItem;
    ToolBar1: TToolBar;
    demo21: TMenuItem;
    starthelp1: TMenuItem;
    SaveDialog1: TSaveDialog;
    procedure bn2Click(Sender: TObject);
    procedure lukvinduer1Click(Sender: TObject);
    procedure tilevinduer1Click(Sender: TObject);
    procedure luk2Click(Sender: TObject);
    procedure bnDBigen1Click(Sender: TObject);
    procedure bn3Click(Sender: TObject);
    procedure lukallevinduer1Click(Sender: TObject);
    procedure Borlanddemo1Click(Sender: TObject);
    procedure mindemo1Click(Sender: TObject);

    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

Form3.caption:=savedialog1.filename;
Form3.Richedit1.lines.savetofile(savedialog1.Filename);

end;
end;

procedure TForm1.lukvinduer1Click(Sender: TObject);

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
Avatar billede hrc Mester
14. marts 2004 - 16:19 #4
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;
Avatar billede hrc Mester
15. marts 2004 - 01:52 #5
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 ;-)).
Avatar billede janbb Juniormester
15. marts 2004 - 06:46 #6
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.
Avatar billede janbb Juniormester
16. marts 2004 - 03:11 #7
hrc: kan ikke få det til at virke.Det er åbenbart mere kringlet end jeg har
tålmodighed til i øjeblikket så jeg må lade det ligge lidt.
Avatar billede hrc Mester
16. marts 2004 - 11:09 #8
janbb: Nej. Det er faktisk meget simpelt:

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.

TfrmMain = class(TForm)
  procedure Button1Click(Sender : TObject);
private
  function FindMDIChild(InstanceClass: TComponentClass): TForm;
end;

implementation

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);

  SubForm.Show;
end;
Avatar billede janbb Juniormester
18. marts 2004 - 14:38 #9
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. :)
Avatar billede hrc Mester
18. marts 2004 - 17:30 #10
Send mig din en mail på "hrc_public snabela hotmail dot com" så sender jeg dig et eksempel jeg har liggende.
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

IT-JOB

Politiets Efterretningstjeneste

Fullstack softwareudvikler i PET

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Cyberdivisionen søger IT-Supporter til lokal IT støtte i Oksbøl

Forsvarsministeriets Materiel- og Indkøbsstyrelse

Cyberdivisionen søger Entreprise Arkitekt

Digitaliseringsstyrelsen

IT-arkitekt hos Digitaliseringsstyrelsen