Mirror

How to access menuitems like an array and how to write just one onclick procedure for all of them (Views: 100)


Problem/Question/Abstract:

How to access menuitems like an array and how to write just one onclick procedure for all of them?

Answer:


// Suppose you have an application with a TMainMenu.
// Under the MenuItem, with caption "File" of the MainMenu, you can
// choose the "normal" things, like:
// "Open", "New", "Close", Save", "Print", "Printer Setup", "Exit" and
// so on.
// At the end of the "File" menu there is a recent file list with all
// the files in it which you recently opened with this application.
// (Just like in Word.) Suppose the names of these MenuItems are:
//
//    FileLastFile1 : TMenuItem;
//    FileLastFile2 : TMenuItem;
//    FileLastFile3 : TMenuItem;
//    FileLastFile4 : TMenuItem;
//    FileLastFile5 : TMenuItem;
//    FileLastFile6 : TMenuItem;
//    FileLastFile7 : TMenuItem;
//    FileLastFile8 : TMenuItem;
//    FileLastFile9 : TMenuItem;
//
// When the application starts, it opens a config file, where the drive,
// path and filenames of the recent file list are read. You can set the
// captions of the MenuItems with the following procedure:
//----------------------------------------------------------------------

procedure ReadConfigFile;

var
  // It is better to make this a global TMenuItem array so you only
  // have to assign once.
  aMenuItem: array[1..9] of TMenuItem
  f: TextFile;
  I: Integer;
  S: string;

begin
  // If this array is global, you only have to assign once. F.i. in the
  // procedure OnFormCreate. After that you can always access the
  // MenuItems like an array, with: aMenuItem[Index].
  aMenuItem[1] := FileLastFile1;
  aMenuItem[2] := FileLastFile2;
  aMenuItem[3] := FileLastFile3;
  aMenuItem[4] := FileLastFile4;
  aMenuItem[5] := FileLastFile5;
  aMenuItem[6] := FileLastFile6;
  aMenuItem[7] := FileLastFile7;
  aMenuItem[8] := FileLastFile8;
  aMenuItem[9] := FileLastFile9;

  // Now the MenuItems are in an TMenuItem array, we can get easy access
  // to the individual MenuItems. Like this:
  for I := 1 to 9 do
    aMenuItem[I].Caption := ''; // Make the caption empty.

  // Open the config file with the recent file list. Example:
  AssignFile(f, 'c:\my_ini_file.ini');
  Reset(f);

  // Read out the recent file names and put them in a global string array.
  // Example:
  for I := 1 to 9 do
    if not Eof(f) then
      ReadLn(f, aRecentfile[I]);
  System.CloseFile(f);
  //
  // Of course you can also do it the "windows" way with:
  // MyIniFile := TIniFile.Create('c:\my_ini_file.ini');
  // For I := 1 to 9 do
  //    aRecentFile[I] := MyIniFile.ReadString('Section','RecentFile' +
  //       Chr(I + Ord('0')), '');
  // MyIniFile.Free;
  //
  // If the content of the IniFile looks like this:
  //
  // [Section]
  // RecentFile1=c:\firstfile.bmp
  // RecentFile2=c:\secondfile.txt
  // ...
  //
  // Now you can assign the filenames to the caption of the TMenuItems.
  // Example:
  for I := 1 to 9 do
    aMenuItem[I].Caption := ExtractFileName(aRecentFile[I]);
end;
//----------------------------------------------------------------------
// You can also point ALL the OnClick events of the TMenuItems to just
// one procedure. F.i. the procedure below.
// The procedure finds out on which MenuItem is clicked, and opens the
// right file from the array with the recent filenames.
//----------------------------------------------------------------------

procedure TMainForm.FileLastFileClick(Sender: TObject);

var
  sFilename: string;
  I: Integer;
  sS: string;
  iErr: Integer;

begin
  // Assumes that the global string array aRecentFile[1..9] holds the
  // filenames of the recent file list, read during startup of the app.

  // Find out which one is clicked.
  // Get the name of the sender: FileLastFile1..FileLastFile9
  sS := (Sender as TComponent).Name;
  // Get the number at the end of the name of the sender, so you know
  // which one is clicked. Example:
  Val(sS[13], I, iErr);
  if iErr <> 0 then
  begin
    // sS[13] is an illegal character.
    Exit;
  end;

  // Now the variable "I" holds the number of the MenuItem, which was
  // clicked on.

  // Get the filename from the array of filenames and do something with
  // it. Example:
  sFileName := aRecentFile[I];
  if sFileName <> '' then
  begin

    if FileExists(sFileName) then
    begin
      // Open the file
      // Do your stuff
    end
    else
    begin
      // Something wrong! The file cannot be found.
      // Send a message. Example:
      // ShowMessage('Cannot find the requested file: ' + sFilename + '.');
      // Or grayout this MenuItem in the "File" menu. Example:
      // (Sender as TComponent).Enabled := False;
      // Or hide this MenuItem in the "File" menu. Example:
      // (Sender as TComponent).Hide;
    end;
  end;
end;
//----------------------------------------------------------------------

<< Back to main page