We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

Making a 'recently used file' list in the File-menu at runtime (part2)

Peter Kiers
Peter Kiers asked
on
Medium Priority
207 Views
Last Modified: 2010-04-05
Hi,

A while a go I have asked how to implement Recent files in my mainmenu.
I received a good solution. As always I close the question to soon.

I have put the example on my site, click on the floppy-disk beneath the
Under Construction bar to download the example.

My question:

In the example when files has been opened it look like this:

Open
---------------
recent file1
recent file2
recent file3
recent file4


But I need the menu-item Exit beneath the recent files and a seperator. Like this:

Open
---------------
recent file1
recent file2
recent file3
recent file4
---------------
exit

And if its possible auto numbering the recent files: like this:
Open
---------------
1. recent file1
2. recent file2
3. recent file3
4. recent file4
---------------
exit

Who want to help me, because i can't do it on my own.
Another change to earn 500 points.

Kind Regards,

Peter Kiers
Comment
Watch Question

Top Expert 2007

Commented:
Hi, try this:


type
  TForm1 = class(TForm)
   ...
  private
    procedure ExitFile(Sender: TObject);
  public
    ...
 





procedure TForm1.LoadRecentFileList;
var
  i: Integer;
  RecentFileItem: TMenuItem;
  LFileItem, ExMenuItem: TMenuItem;

begin
  for i := 0 to FRecentFiles.Count - 1 do
  begin
    if Trim(FRecentFiles[i])<>'' then begin
      RecentFileItem := TMenuItem.Create(self);
      File1.add( RecentFileItem);
      RecentFileItem.Caption := IntToStr(i)+'   '+ExtractFileName(FRecentFiles[i]);
      RecentFileItem.Tag := i;
      RecentFileItem.Visible := true;
      RecentFileItem.OnClick := OpenRecentFile;
      RecentFileItem.Name := 'Recent' + IntToStr( i);
    end;
  end;
  LFileItem := TMenuItem.Create(self);
  File1.Add(LFileItem);
  LFileItem.Caption := '-';
  LFileItem.Visible := True;

  ExMenuItem := TMenuItem.Create(self);
  File1.add(ExMenuItem);
  ExMenuItem.Caption := 'Exit';
  ExMenuItem.Visible := true;
  ExMenuItem.OnClick := ExitFile;
end;
(*--------------------------------------------------*)


procedure TForm1.ExitFile(Sender: TObject);
begin
  Close;
end;
Peter KiersOperator

Author

Commented:
Almost...

When I open files i get this:

open
--------------------
Exit                            <======  ?????
 recent file1
 recent file2
--------------------
Exit

Peter
Top Expert 2007

Commented:
>When I open files i get this:

Yes, I've fixed that, hadn't checked what the whole program does, but first have a look at this, all recent files in a submenu. If you prefer the version without the submenu, just say so and I'll post the fix for the mentioned problem :)


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Open1: TMenuItem;
    N1: TMenuItem;
    OpenDialog1: TOpenDialog;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Open1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FRecentFiles: TStringList;
    procedure LoadRecentFileList;
    procedure SaveRecentFileList;
    procedure OpenRecentFile( Sender: TObject);
    procedure ReloadFileList( sFileName: String);
    procedure ClearList;
    procedure ExitFile(Sender: TObject);

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ClearList;
var
  i: Integer;
  FMenuItem: TMenuItem;
begin
  for i := 0 to FRecentFiles.Count - 1 do
  begin
    FMenuItem := TMenuItem( FindComponent( 'Recent' + IntToStr( i)));
    FreeAndNil( FMenuItem);
  end;
  FMenuItem := TMenuItem( FindComponent('ExitMenuItem'));
  FreeAndNil( FMenuItem);
  FMenuItem := TMenuItem( FindComponent('RecFilesItem'));
  FreeAndNil( FMenuItem);
  FMenuItem := TMenuItem( FindComponent('MenuLine1'));
  FreeAndNil( FMenuItem);
end;

(*--------------------------------------------------*)
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SaveRecentFileList;
end;
(*--------------------------------------------------*)
procedure TForm1.FormCreate(Sender: TObject);
begin
  FRecentFiles := TStringList.Create;
  FRecentFiles.Duplicates := dupIgnore;
  if FileExists( 'c:\MyRecentFileList.txt') then
    FRecentFiles.LoadFromFile( 'c:\MyRecentFileList.txt');
  LoadRecentFileList;
end;
(*--------------------------------------------------*)
procedure TForm1.LoadRecentFileList;
var
  i: Integer;

  RecentFileItem, SubRecentFileItem: TMenuItem;
  LFileItem, ExMenuItem: TMenuItem;

begin

  if TMenuItem(FindComponent('RecFilesItem'))=nil then begin
    RecentFileItem := TMenuItem.Create(self);
    File1.add(RecentFileItem);
    RecentFileItem.Name:='RecFilesItem';
    RecentFileItem.Caption :='Recent Files';
  end;
  for i := 0 to FRecentFiles.Count - 1 do
  begin
    if Trim(FRecentFiles[i])<>'' then begin
      SubRecentFileItem := TMenuItem.Create(self);
      RecentFileItem.add(SubRecentFileItem);
      SubRecentFileItem.Caption := IntToStr(i)+'  '+ExtractFileName(FRecentFiles[i]);
      SubRecentFileItem.Tag := i;
      SubRecentFileItem.Visible := true;
      SubRecentFileItem.OnClick := OpenRecentFile;
      SubRecentFileItem.Name := 'Recent' + IntToStr( i);
    end;
  end;
  if TMenuItem(FindComponent('ExitMenuItem'))=nil then begin
    LFileItem := TMenuItem.Create(self);
    File1.Add(LFileItem);
    LFileItem.Caption := '-';
    LFileItem.Visible := True;
    LFileItem.Name:='MenuLine1';
  end;

  if TMenuItem(FindComponent('ExitMenuItem'))=nil then begin
    ExMenuItem := TMenuItem.Create(self);
    File1.add(ExMenuItem);
    ExMenuItem.Caption := 'Exit';
    ExMenuItem.Visible := true;
    ExMenuItem.Name:='ExitMenuItem';
    ExMenuItem.OnClick := ExitFile;
  end;
end;
(*--------------------------------------------------*)


procedure TForm1.ExitFile(Sender: TObject);
begin
  Close;
end;



procedure TForm1.Open1Click(Sender: TObject);
var
  sFileName: String;
  i: Integer;
begin
  if OpenDialog1.Execute then
  begin
    sFileName := OpenDialog1.FileName;
    ShellExecute(Handle, 'open', PChar( sFilename), nil, nil, SW_SHOWNORMAL);
    i := FRecentFiles.IndexOf( sFileName);
    if i >= 0 then
      FRecentFiles.Delete( i);
    ReloadFileList( sFileName);
  end;
end;
(*--------------------------------------------------*)
procedure TForm1.OpenRecentFile(Sender: TObject);
var
  sFileName: String;
  i: Integer;
begin
  sFileName := FRecentFiles[ TMenuItem( Sender).Tag];
  i := FRecentFiles.IndexOf( sFileName);
  FRecentFiles.Delete( i);
  ReloadFileList( sFileName);
  ShellExecute(Handle, 'open', PChar( sFilename), nil, nil, SW_SHOWNORMAL);
end;
(*--------------------------------------------------*)
procedure TForm1.ReloadFileList(sFileName: String);
begin
  FRecentFiles.Insert(0, sFileName);
  if FRecentFiles.Count > 10 then
    FRecentFiles.Delete( 10);
  ClearList;
  LoadRecentFileList;
end;
(*--------------------------------------------------*)
procedure TForm1.SaveRecentFileList;
begin
  FRecentFiles.SaveToFile( 'c:\MyRecentFileList.txt');
  FreeAndNil( FRecentFiles);
end;
(*--------------------------------------------------*)
end.
Peter KiersOperator

Author

Commented:
Prefer the version without the submenu.

P.
Top Expert 2007
Commented:
>Prefer the version without the submenu.
Ok:


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Open1: TMenuItem;
    N1: TMenuItem;
    OpenDialog1: TOpenDialog;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Open1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FRecentFiles: TStringList;
    procedure LoadRecentFileList;
    procedure SaveRecentFileList;
    procedure OpenRecentFile( Sender: TObject);
    procedure ReloadFileList( sFileName: String);
    procedure ClearList;
    procedure ExitFile(Sender: TObject);

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ClearList;
var
  i: Integer;
  FMenuItem: TMenuItem;
begin
  for i := 0 to FRecentFiles.Count - 1 do
  begin
    FMenuItem := TMenuItem( FindComponent( 'Recent' + IntToStr( i)));
    FreeAndNil( FMenuItem);
  end;
  FMenuItem := TMenuItem( FindComponent('ExitMenuItem'));
  FreeAndNil( FMenuItem);
  FMenuItem := TMenuItem( FindComponent('RecFilesItem'));
  FreeAndNil( FMenuItem);
  FMenuItem := TMenuItem( FindComponent('MenuLine1'));
  FreeAndNil( FMenuItem);
end;

(*--------------------------------------------------*)
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SaveRecentFileList;
end;
(*--------------------------------------------------*)
procedure TForm1.FormCreate(Sender: TObject);
begin
  FRecentFiles := TStringList.Create;
  FRecentFiles.Duplicates := dupIgnore;
  if FileExists( 'c:\MyRecentFileList.txt') then
    FRecentFiles.LoadFromFile( 'c:\MyRecentFileList.txt');
  LoadRecentFileList;
end;
(*--------------------------------------------------*)
procedure TForm1.LoadRecentFileList;
var
  i: Integer;
  RecentFileItem: TMenuItem;
  LFileItem, ExMenuItem: TMenuItem;
begin
  for i := 0 to FRecentFiles.Count - 1 do
  begin
    if Trim(FRecentFiles[i])<>'' then begin
      RecentFileItem := TMenuItem.Create(self);
      File1.add(RecentFileItem);
      RecentFileItem.Caption := IntToStr(i)+'  '+ExtractFileName(FRecentFiles[i]);
      RecentFileItem.Tag := i;
      RecentFileItem.Visible := true;
      RecentFileItem.OnClick := OpenRecentFile;
      RecentFileItem.Name := 'Recent' + IntToStr( i);
    end;
  end;
  if TMenuItem(FindComponent('ExitMenuItem'))=nil then begin
    LFileItem := TMenuItem.Create(self);
    File1.Add(LFileItem);
    LFileItem.Caption := '-';
    LFileItem.Visible := True;
    LFileItem.Name:='MenuLine1';
  end;

  if TMenuItem(FindComponent('ExitMenuItem'))=nil then begin
    ExMenuItem := TMenuItem.Create(self);
    File1.add(ExMenuItem);
    ExMenuItem.Caption := 'Exit';
    ExMenuItem.Visible := true;
    ExMenuItem.Name:='ExitMenuItem';
    ExMenuItem.OnClick := ExitFile;
  end;
end;
(*--------------------------------------------------*)


procedure TForm1.ExitFile(Sender: TObject);
begin
  Close;
end;

procedure TForm1.Open1Click(Sender: TObject);
var
  sFileName: String;
  i: Integer;
begin
  if OpenDialog1.Execute then
  begin
    sFileName := OpenDialog1.FileName;
    ShellExecute(Handle, 'open', PChar( sFilename), nil, nil, SW_SHOWNORMAL);
    i := FRecentFiles.IndexOf( sFileName);
    if i >= 0 then
      FRecentFiles.Delete( i);
    ReloadFileList( sFileName);
  end;
end;
(*--------------------------------------------------*)
procedure TForm1.OpenRecentFile(Sender: TObject);
var
  sFileName: String;
  i: Integer;
begin
  sFileName := FRecentFiles[ TMenuItem( Sender).Tag];
  i := FRecentFiles.IndexOf( sFileName);
  FRecentFiles.Delete( i);
  ReloadFileList( sFileName);
  ShellExecute(Handle, 'open', PChar( sFilename), nil, nil, SW_SHOWNORMAL);
end;
(*--------------------------------------------------*)
procedure TForm1.ReloadFileList(sFileName: String);
begin
  FRecentFiles.Insert(0, sFileName);
  if FRecentFiles.Count > 10 then
    FRecentFiles.Delete( 10);
  ClearList;
  LoadRecentFileList;
end;
(*--------------------------------------------------*)
procedure TForm1.SaveRecentFileList;
begin
  FRecentFiles.SaveToFile( 'c:\MyRecentFileList.txt');
  FreeAndNil( FRecentFiles);
end;
(*--------------------------------------------------*)
end.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Top Expert 2007

Commented:
BTW, if you want the menu items to be numbered 1 2 3...  rather than 0 1 2...  then replace this line

RecentFileItem.Caption := IntToStr(i)+'  '+ExtractFileName(FRecentFiles[i]);

with this line
RecentFileItem.Caption := IntToStr(i+1)+'  '+ExtractFileName(FRecentFiles[i]);

in the procedure LoadRecentFileList;
Peter KiersOperator

Author

Commented:
Yip, that's what i ment.

500p comming your way.

Kind Regards,

Peter Kiers
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.