Selective Tiling in MDI Editors

The Window/Tile menu item is useful if only two files are open. This

code implements a more useful "Tile Top 2 of N Windows" that doesn't

lose other files that may be open.



Selective Tiling in MDI Editors



By Gene Fowler

acorioso@earthlink.net


May 28, 2001 - Change When I added window tracking in a lter article, Tracking Window Numbers in MDI Editors, I found that I had not set Tag values when reopening the files closed before tiling. I have made this change in the TFrameForm.Tile2ofN1Click:



// Borrowed guts from Open1Click to replace

// ReopenIt in eWriter's complex interweaving

with TEditForm.Create(Self) do

  begin

    Open(TileTwo[i]);

    Tag := 3 + i;

    end;



Replaces:



// Borrowed guts from Open1Click to replace

// ReopenIt in eWriter's complex interweaving

with TEditForm.Create(Self) do

  Open(TileTwo[i]);



Some Added CodeIf you have set up Tile Top 2 of N Windows in TextEdit to look at the code's working, you will want to add this SaveAs1Click routine to MDIEdit.pas. You may have noticed that if you had a new file, saved or not, you got some strange results. Add this and you will not get odd results if you save the file (giving it a pathname). You should not use this menu item if you have an unsaved new file.



The loss of Restore sizing is not one of the strange effects. Tiling1 produces that effect and I call it in Tile Top 2 of N Windows.



procedure TEditForm.Saveas1Click(Sender: TObject);

begin

  SaveFileDialog.FileName := PathName;

  if SaveFileDialog.Execute then

  begin

    PathName := SaveFileDialog.FileName;

    Caption := ExtractFileName(PathName);

    OpenFiles.Insert(Tag, Pathname); // list new Pathname

    Save1Click(Sender);

  end;

end;





Warning: The test-bed for this code is Borland's TextEdit demo that comes with Delphi. If you are compiling in Delphi 5 or 5.01, you will need the modified forms.pas which I direct you to in my earlier article, Programming System/Next (Prev) in MDI editors.





When you compile and run Borland's TextEdit (demos/doc/TextEdit) and click the Window menu, you find two file arranging menu items: Tile and Cascade. The Tile command is a design wonder. If you have two files open, they are stacked vertically. This is a very useful work arrangement. But lets go on. If you have three files open, they are still stacked vertically. Now, there isn't much work area in any of them. If you have four files open, they occupy quadrants of the client area. I have not dared try with five files open. I fear pixels popping out of the screen.



Tile is most useful if you have just two files open. In the context of a project, however, you might want to have a half dozen close at hand. What you need is a way to set all the files but two aside, with a mouse-click, and, later, bring them back with a mouse-click.



You don't want to worry about whether files are tiled or not when making that second click. The code below implements this with a new item on the Window menu below Tile. Click Tile Top 2 of N Windows. All the files other than the top two are closed and the top two are tiled. The menu item is checked. Click it while checked, and the files are re-opened, files are maxed, and the one that was active before the re-opening is on top.



On TFrameForm, put a menu item in the Window menu between Tile and Cascade. At the top of the Code section below, I give a Caption (for the user to see) and remind that the Checked property should be False. Everything else can be left as is (since that is what I've done while checking this). The Name property can be shortened as shown. In the Events sheet, Double Click the onClick to get the handler. TFrameForm.Tile2ofN1Click is given here in full. All the declarations (and initializations) are given first.



This is not going to compile, yet. I've worked this thread loose from a complex "son of TextEdit," and I've worked up minimal support infrastructure here. In the properties table below, note that TEditForm should have WindowState set to wsMaximized. Under Support Code, I give replacement routines for TEditForm.FormClose and TEditForm.Open. My modifications are necessary for keeping track of what files are open and getting pathnames to re-open.



Way down at the bottom is something I should have included in my first article. All the tests of my code involve bringing a gang of files into TextEdit. Opening one at a time is a drag. So I include a replacement TFrameForm.Open1Click to handle gang loading. A note just before the routine tells you how to modify the dialog's properties.



Code:



Some property settings:

In TFrameForm, insert a new menu item between Window/Tile and Window/Cascade. Tile Top &2 of N Windows (Menu item caption)

Name can be chopped down to Tile2ofN1

Checked is false
TEditForm WindowState: wsmaximized



TFrameForm

  ...

var (global)

  ...

  TileTwo: TstringList;

  OpenFiles: TstringList;



initialization

// TileTwo is for the main code

TileTwo := TStringList.Create;

TileTwo.Text := '';

// OpenFiles is a juri-rigged system for keeping track of open files

OpenFiles := TStringList.Create;

OpenFiles.Text := '';



{ The main code, a TFrameForm routine }



procedure TFrameForm.Tile2ofN1Click(Sender: TObject);

var

  i, j: integer;



begin

  if MDIChildCount < 2 then Exit;

  if (MDIChildCount = 2) and (Tile2ofN1.Checked = False) then

    begin

      Tile1Click(Sender);


      Exit;

    end;

  If (MDIChildCount > 2) and not Tile2ofN1.Checked then

    begin

    Tile2ofN1.Checked := True;

      for i := 2 to MDIChildCount - 1 do

        begin

          for j := 0 to OpenFiles.Count - 1 do

            if pos(MDIChildren[i].Caption, OpenFiles.strings[j]) <> 0 then

              begin

                TileTwo.Add(OpenFiles.strings[j]);

                MDIChildren[i].Close;

                Break;

              end;

        end;

      Tile2ofN1.Checked := True;

      messageDlg('In this demo, I need ' +

      'an interruption after closing files and before ' +

      'calling Tile1Click so Child Count is ' +

      'recalculated. Go figure.', mtInformation, [mbOK],0);

      LockWindowUpdate(Handle);

      Tile1Click(Sender);

      LockWindowUpdate(0);

    end

  else if Tile2ofN1.Checked and (TileTwo.Text <> '') then

     begin

       LockWindowUpdate(Handle);

       for i := 0 to TileTwo.Count - 1 do

       // Borrowed guts from Open1Click to replace

      // ReopenIt in eWriter's complex interweaving

       with TEditForm.Create(Self) do

         begin

             Open(TileTwo[i]);

             Tag := 3 + i;

         end;

       MDIChildren[MDIChildCount - 2].BringToFront;

       LockWindowUpdate(0);

       TileTwo.Text := '';

       Tile2ofN1.Checked := False;

     end;

end;



Support Code:



{These two routines in TEDitForm track and handle file opens and closes and replace routines already there}



procedure TEditForm.FormClose(Sender: TObject; var Action: TCloseAction);

var

 i: Longint;

begin

  for i := 0 to OpenFiles.Count - 1 do

    if OpenFiles[i] = Pathname then

      begin

       OpenFiles.Delete(i);

       break;

      end;

  Action := caFree;

end;



procedure TEditForm.Open(const AFileName: string);

begin

  PathName := AFileName;

  Caption := ExtractFileName(AFileName);

  // put Pathname into OpenFiles list

  OpenFiles.Add(Pathname);

  with Editor do

  begin

    Lines.LoadFromFile(PathName);

    SelStart := 0;

    Modified := False;

  end;

end;



{Taking in multiple files to run tests will be easier if you select TFrameForm's OpenDialog1 and, under options, make multiple selections True. Then, substitute the routine below for Open1Click}



procedure TFrameForm.Open1Click(Sender: TObject);

var

  i: integer;



begin

  if OpenFileDialog.Execute then

  LockWindowUpdate(Handle);

  For i := 0 to OpenFileDialog.Files.count - 1 do

  with TEditForm.Create(Self) do

    Open(OpenFileDialog.Files[i]);

  LockWindowUpdate(0);

end;

Interlaced Bibliography
I began ad-libbing these articles on doing some of the things I do

 in eWriter in the Delphi demo TextEdit (from which I built eWriter).

 It's natural to accumulate all these in one copy of TextEdit. And

 you might have to go back and forth to fill in new, missed, or

 changed support routines. Boxed notes appear most places. Figure

 it's on-going "shop" conversation...

  1. Programming System/Next (Prev) in MDI editors





    http://www.HowToDoThings.com/showarticle.asp?article=143




  2. Selective Tiling in MDI Editors





    http://www.HowToDoThings.com/showarticle.asp?article=147



  3. Tracking Window Numbers in MDI Editors





    http://www.HowToDoThings.com/showarticle.asp?article=154



  4. Paragraph "pouring" from a text editor





    http://www.HowToDoThings.com/showarticle.asp?article=178


 

Share this article!

Follow us!

Find more helpful articles: