Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SaveToFile - Which Memo In An MDI App?

Status
Not open for further replies.

TBaz

Technical User
Jun 6, 2000
65
ES
I have a simple MDI app in which the children all have the DreamMemo component on. My problem is that when I have multiple documents open, I don't know how to access the correct memo to save the contents to disk.

My code is based on one of the MDI demos supplied with Delphi5, so the children are opened with:

Child := TMDIChild.Create(Application);
Child.DCMemo1.Lines.LoadFromFile(Name);

... but the demo doesn't have any code in the Save or SaveAs sections and if you try to use:

Child.DCMemo1.Lines.SaveToFile(Name);

... it says that 'Child' is an undeclared identifier - even though it is used earlier in Main when the children are created.

I did a search on here and found a suggestion which said to use MDIChildren[0], but the line:

MainForm.MDIChildren[0].DCMemo1.Lines.SaveToFile(Name);

... then says 'DCMemo1' is an undeclared identifier although:

ShowMessage(MainForm.MDIChildren[0].Name);

... works fine.

I'm obviously being very stupid here, so can someone point me in the right direction please?

Barrie
 
Where is the variable Child defined ?

Can you copy and paste the actual code from your unit so that we can examine it?

Andrew
 
Child is defined in Main as follows:

procedure TMainForm.CreateMDIChild(const Name: string);
Var
Parse, RowVal, ColVal: String;
EndPos: Integer;
Child: TMDIChild;
begin
{ create the new MDI child window }
Child := TMDIChild.Create(Application);
Child.Caption := Name;
Child.Tag := MDIChildCount-1;
FileSaved[Child.Tag]:=False;

if FileExists(Name) then
Begin
// Load File
Child.DCMemo1.Lines.LoadFromFile(Name);
StatusBar.Panels[0].Text := 'Saved';
FileSaved[Child.Tag]:=True;
End
else
Begin
// New File
Child.DCMemo1.Lines.Add('Rem Created: '+DateToStr(Date)+' '+TimeToStr(Time));
Child.DCMemo1.Lines.Add('Rem Author: ');
Child.DCMemo1.Lines.Add('');
StatusBar.Panels[0].Text := 'Unsaved';
FileSaved[Child.Tag]:=False;
End;
Parse:=Child.DCMemo1.CurPosText;
EndPos:=Pos(':', Parse)-1;
RowVal:=Copy(Parse,1,EndPos);
StatusBar.Panels[1].Text := ' Line: '+RowVal;
ColVal:=Copy(Parse,EndPos+2,6);
StatusBar.Panels[2].Text := ' Column:'+ColVal;
If CapsLock=True Then
StatusBar.Panels[3].Text := 'CAPS'
Else
StatusBar.Panels[3].Text := ' ';
If NumLock=True Then
StatusBar.Panels[4].Text := 'NUM'
Else
StatusBar.Panels[4].Text := ' ';
If Insert=True Then
StatusBar.Panels[5].Text := 'INS'
Else
StatusBar.Panels[5].Text := 'OVR';
end;

The save button is also on the Main Form, but I'm at a loss as to what to put in the TMainForm.SaveDBAClick procedure. At the moment I have the following code (as you can see I've been experimenting, so please excuse the mess):

procedure TMainForm.SaveDBAClick(Sender: TObject);
begin
if (MainForm.MDIChildCount > 0) then
ShowMessage(MDIChildren[0].Caption);
ActiveMDIChild.DCMemo1.Lines.SaveToFile(Name);

// MainForm.MDIChildren[0].DCMemo1.Lines.SaveToFile(Name);
// MainForm.MDIChild(ActiveMDIChild).DCMemo1.Lines.SaveToFile(Name);
end;

ShowMessage works fine so when there are multiple documents open I can get the currently highlighted child's caption (or name) to appear and it's correct. However I can't figure out how to utilize this information to access the DCMemo on any particular child form.

I hope someone can help as it's driving me crazy now - having spent the last week trying to figure it out!

As I said, it's based around the supplied MDI demo which came with Delphi 5 - it's the one without any code in the save or save as sections. I can see why now! :)

Barrie
 
I haven't examined your code very closely (nor have I written an MDI program before) but your 'child' variable goes out of scope when the CreateMDIChild procedure completes. Therefore it is not accessible by the Save procedure.

Surely you should be declaring Child in the TForm1 (or whatever it is called) class?

Andrew
 
"nor have I written an MDI program before"

Me neither! As I said, I used a Delphi Demo as the building blocks for my program and that's where child was declared.

I'll see if anything good happens if I move it! :)

Thanks for the suggestion.

Barrie
 
Hi.

These things may be helpful :)

1. Drop a "TSaveDialog" on your main form if you have not got one there already.

The code to save should be placed in the action for save not on the button click event.

2. Doubble click on "ActionList1", then select "All Actions" so you can see them all. Doubble click on "FileSaveAs1", this will make a procedure for your code to go in.

3. Here is the procedure to save...
Code:
procedure TMainForm.FileSaveAs1Execute(Sender: TObject);
var
   sFileName: string;
begin
   if (SaveDialog1.Execute) then
   begin
      sFileName := SaveDialog1.FileName;
      TMDIChild(MainForm.MDIChildren[0]).Memo1.Lines.SaveToFile(sFileName);
   end; //if
end;

4. What you have to do is typecast the result from "MainForm.MDIChildren[0])" so you can access the memo you need to save.

Hope this helps.

Tim
SNL Computing
 
OK thanks - I'll try that tomorrow too!

Barrie
 
No, I'm afraid that I had no luck with any of the suggestions. However, I have managed to solve the problem myself by changing the method of actually creating the child windows:

I now use:

Application.CreateForm(TForm2,Form2);

then set the child form's tag property to the new child window number and save the required file and path info in an array. This allows me to access the arrays using (ActiveMDIChild as TForm2).Tag and save the contents of the memo with:

(ActiveMDIChild as TForm2).DCMemo1.Lines.SaveToFile(SaveFName);

Thanks for all the suggestions though!

BC
 
...then set the child form's tag property to the new child window number and save the required file and path info in an array. This allows me to access the arrays using (ActiveMDIChild as TForm2).Tag...

This approach will yield undesired results!
Your main form already maintains an array of its children in its MDIChildren property though which you can access and control every attribute. If you open 3 child windows and then close the first one, the other 2 will be out-of-sync with your array.
 
What can I say? My program now works perfectly!

I understand what you are saying, but after reading what you said, I created 5 new documents, put separate text in each of them (including ID numbers 1 to 5), then saved them all.

I then deleted doc 3 and added an extra line of text with the same respective number in it. I then saved and closed all of them.

Finally I loaded them all back in and all contained the same (correct) text.

BC
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top