TechTricks
Technical answers from the trenches 
 
 
 
 

     
   
Adding Commands to a Form's System Menu
 
   
 Posted: 8 October 2002
 
   
 
Audience: Intermediate
 
       
   

Question: I want to add a menu command to the System menu. How do I do this?

Answer: This is a three step process:

  1. Give your form the ability to respond to system command messages,
  2. Add the menu items you need,
  3. Add code to respond to your menu items.

The following code sample illustrates each step by adding a separator and an About command to a form's System menu.

unit mainform;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    // Lets form respond to system command messages
    procedure wmSysCommand( var msg: TMessage ); message WM_SYSCOMMAND;
  public
    { Public declarations }
  end;

const
   // Define WM_USER constants for custom
   // menu commands.
   ID_SYS_ABT = WM_USER + 1024; // About command constant
   ID_SYS_SEP = ID_SYS_ABT + 1;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
// Adds items to the system menu
var
   hSysMenu : tHandle;

begin
   hSysMenu := getSystemMenu( Handle, False );

   InsertMenu( hSysMenu, Word( 5 ),
               MF_SEPARATOR + MF_BYPOSITION, ID_SYS_SEP, '' );

   InsertMenu( hSysMenu, Word( 6 ), MF_BYPOSITION,
               ID_SYS_ABT, 'About' );
end;

procedure TForm1.wmSysCommand;
// Responds to system command messages.
begin
   case Msg.wParam of
      ID_SYS_ABT : showMessage( 'About this application...' );
   end;
   inherited;
end;

Please note that we also declared a constant for the About command to simplify the evaluation of the wParam parameter in wmSysCommand. While this particular example could have used a simple IF statement to evaluate wParam, SWITCH statements require less code when adding multiple wParam alternatives. Use the approach that seems most appropriate for your needs.

When using this approach, please keep the following in mind:

  1. The second parameter of the InsertMenu API function, documented in the Win32 Programmers Reference Help file provided with Delphi, indicates the position of the new item. Set this to -1 to append your new items to the bottom of the menu.

  2. If you are trying to add separators and they keep appearing at the bottom of the System menu, the most likely problem is that you are not adding the MF_POSITION flag to the MF_SEPARATOR flag, as shown above.

  3. This particular technique works with normal forms, however, it doesn't work with MDI children as written. This is left as an exercise for the reader.

  4. While this particular example requires Delphi 5 or later, the underlying technique should work in all versions of Delphi, including v1.02.

  5. Windows has long provided a range of constants for custom behavior in your applications and this example leverages this to support the ID_SYS_ABT menu constant. For complete details, refer to the WM_USER topic in the Windows SDK Help file provided with Delphi.

    Also, keep in mind that some WM_USER values may already be defined by Delphi's RTL. For more details, consult the MESSAGES.PAS source file provided with Professional and Enterprise versions of Delphi. (Specifically, search for the string "{ Dialog Messages }".) While these shouldn't conflict with most applications, it's best to avoid potential problems by using different values. (We generally use WM_USER + 1024 and above.)

 

       

Top

Feedback About Paradox Delphi Assorted Web Stuff
 
 
Copyright © 2000-2004, techtricks.com; All Rights Reserved.
Acknowledgements, Disclaimers, Terms and Conditions.
Article last updated on 31 May 2003

 

Other Sites: Paradox, Delphi, Perl, Web Stuff, and More


 

[- End -]