Solved

Saving/loading MDI forms

Posted on 2004-04-26
4
313 Views
Last Modified: 2010-04-05
I am trying to create a MDI application. Here's what I've got so far:

procedure TForm1.NewItemClick(Sender: TObject);
var
  Child: TPage;
begin
  { New Child }
  Inc(Count);
  Child := TPage.Create(Self);
  Child.Caption := Child.Caption + ' ' + IntToStr(Count);
end;

I need to know how to:

1. Save the current page.
2. Save all the pages.
3. Load a file.

Any help would be greatly appreciated. I am giving the maximum 500 points for this as it is URGENT. I am using Delphi 6.
0
Comment
Question by:rincewind666
4 Comments
 
LVL 3

Expert Comment

by:Kunfufaresi
ID: 10916591
hello you can loop through available children with

  for i := 0 to MDIForm.MDIChildCount - 1 do
  begin
    listbox1.add(MDIForm.MDIChildren[i].Caption);
  end;

  you can access the components on the child form with

var
 DataFromOtherForm:String;

with (MDIForm.MDIChildren[I] as TMDIChildForm).Edit1 do
      DataFromOtherForm := Text;

Kunfu Faresi
0
 
LVL 3

Assisted Solution

by:MikProg
MikProg earned 250 total points
ID: 10916893
Preferrable to implement required functions in TPage class

TPage = ....
....
function Save(FileName: string): boolean; // must retrun result success/fail
function Load(FileName: string): boolean; // must retrun result success/fail
end;

function TPage.Save(FileName: string): boolean;
begin
    // You can use here FileSaveAs dialog to assign FileName or use existing value
    // Open file and save contents you need
end;

function TPage.Load(FileName: string): boolean;
begin
    // You can use here FileOpen dialog to assign FileName or use existing value
    // Open file and load contents.
end;

In main MDI form you need to insert into menu commands Save and SaveAll
procedure TForm.SaveActive(Sender: TObject);
begin
  if Assigned(ActiveMDIChild) and (ActiveMDIChild is TPage) then
    TPage(ActiveMDIChild).Save(ActiveMDIChild.Caption);
end;

procedure TForm.SaveAll(Sender: TObject);
var
  i: integer
begin
  for i := 0 to MDIChildCount - 1 do
    if (MDIForm.MDIChildren[i] is TPage) then
      TPage(MDIForm.MDIChildren[i]).Save(MDIForm.MDIChildren[i].Caption);
end;
and (if you need) implement OnClose.

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i: integer
begin
  for i := 0 to MDIChildCount - 1 do
    if (MDIForm.MDIChildren[i] is TPage) then
      if not TPage(MDIForm.MDIChildren[i]).Save(MDIForm.MDIChildren[i].Caption) then
      begin
        Action:=caNone;
        Exit;
     end;
end;
0
 
LVL 22

Accepted Solution

by:
Ferruccio Accalai earned 250 total points
ID: 10918183
My version using Form streaming....

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Page};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

//unit1.dfm  MDImain

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 696
  Height = 480
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsMDIForm
  Menu = MainMenu1
  OldCreateOrder = False
  OnClose = FormClose
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object MainMenu1: TMainMenu
    Left = 124
    Top = 38
    object File1: TMenuItem
      Caption = 'File'
      object NewPage1: TMenuItem
        Caption = 'New Page'
        OnClick = NewPage1Click
      end
    end
    object AvailableWindows1: TMenuItem
      Caption = 'Available Windows'
    end
  end
end

//unit1.pas

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus,IniFiles,Unit2;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    NewPage1: TMenuItem;
    AvailableWindows1: TMenuItem;
    procedure MyClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure NewPage1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure WriteToIni(Form: TPage);
  end;
var
  Form1: TForm1;
  Ini: TInifile;
  Count: Integer;
  list: TStrings;
implementation


{$R *.dfm}
procedure TForm1.WRiteToIni(Form: TPage);
var
  MemStr : TMemoryStream;
  FileStr : TFileStream;
begin

  MemStr := TMemoryStream.Create;
  FileStr := TFileStream.Create(('c:\'+Form.Caption+'.dat'),fmCreate);  //use your preferred path
  try
    Ini.WriteString('Forms',Form.Caption,Form.Caption+'.dat');
    MemStr.WriteComponent(Form);
    MemStr.Position := 0;
    ObjectBinaryToText(MemStr, FileStr);
  finally
    MemStr.Free;
    FileStr.Free;
  end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
Item: TMEnuItem;
begin
   Ini := TiniFile.Create('c:\Forms.ini');
   List := TStringlist.create;
   try
      ini.ReadSection('Forms',List);
      for i := 0 to LIst.Count-1 do
         begin
            Item := TMenuItem.Create(self);
            Item.Caption := List[i];
            Item.OnClick := MyClick;
            AvailableWindows1.Add(Item);
         end;
   finally
      Count := List.Count;
   end;
end;

procedure TForm1.MyClick(Sender: TObject);
function RemoveAmpersand(Text: String):String;
   begin
      Result := StringReplace(Text,'&','',[]);
   end;
var
MemStr : TMemoryStream;
FileStr : TFileStream;
begin
Application.CreateForm(TPage, Page);
With Page do
   begin
   FileStr := TFileStream.Create(('c:\'+RemoveAmpersand(TMenuItem(sender).Caption)+'.dat'),fmOpenRead);
   MemStr:= TMemoryStream.Create;
   try
    ObjectTextToBinary(FileStr,MemStr);
    MemStr.position := 0;
    MemStr.ReadComponent(Page);
   finally
    MemStr.Free;
    FileStr.Free;
  end;
   Show;
  end;
end;

procedure TForm1.NewPage1Click(Sender: TObject);
var
  Child: TPage;
  item: TMenuItem;
begin
  { New Child }
  inc(Count);
  Child := TPage.Create(Self);
  Child.Name := Child.Name+IntToStr(Count);
  WriteToIni(Child);
  Item := TMenuItem.Create(self);
  Item.Caption := Child.Caption;
  Item.OnClick := MyClick;
  AvailableWindows1.Add(Item);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
List.Free;
Ini.Free;
end;

end.

// unit2.dfm TPage
object Page: TPage
  Left = 192
  Top = 107
  Width = 696
  Height = 480
  Caption = 'Page'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsMDIChild
  OldCreateOrder = False
  Position = poDefault
  Visible = True
  OnClose = FormClose
  PixelsPerInch = 96
  TextHeight = 13
end
//unit2.pas

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TPage = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Page: TPage;

implementation

uses Unit1;

{$R *.dfm}

procedure TPage.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Form1.writetoini(Self);
  action := CaFree;
end;
end.
0
 

Author Comment

by:rincewind666
ID: 10958087
Many thanks for your help.
0

Featured Post

Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question