Search code examples
delphivcltaskbar

Why is the taskbar button context menu of my Delphi 2006 application incomplete?


When I create a new VCL application in Delphi 2006 and run it (without adding any of my own code or refernce any of my own units), the application won't have all of menu items one would expect in the context menu of it's taskbar button. The application's system menu (the menu you get when left-clicking the form's icon), however, has all the regular menu items. As you can see in the following screenshots, Move (Verschieben), Size(Größe ändern) and Maximize(Maximieren) are missing from the former

enter image description here enter image description here

I could not reproduce this in Delphi XE (the only other vesion of Delphi I have access to) and I haven't found anybody else reporting this behavior, either.

I have also looked through the properties of TForm and TApplication whether there was one to control these menus, but haven't found one.

All applications I know of have the same set of menu items in those two menus and I would like my application to do, too. How do I get these two menus to show the same set of items?


Solution

  • The difference lies in Application.MainFormOnTaskBar, a property introduced in D2007 which is set automatically True.

    To acquire the same effect in earlier versions, I always use the following approach:

    Project.dpr:

    uses
      Windows,
      ...
    
      Application.CreateForm(TMainForm, MainForm);
      ShowWindow(Application.Handle, SW_HIDE);
      Application.Run;
    

    FMain.pas:

      TMainForm = class(TForm)
      private
        procedure WMSysCommand(var Message: TWMSysCommand);
          message WM_SYSCOMMAND;
      protected
        procedure CreateParams(var Params: TCreateParams); override;
      ...
    
    procedure TMainForm.CreateParams(var Params: TCreateParams);
    begin
      inherited CreateParams(Params);
      with Params do
      begin
        ExStyle := ExStyle or WS_EX_APPWINDOW;
        WndParent := GetDesktopWindow;
      end;
    end;
    
    procedure TMainForm.WMSysCommand(var Message: TWMSysCommand);
    begin
      if Message.CmdType = SC_MINIMIZE then
        ShowWindow(Handle, SW_MINIMIZE)
      else
        inherited;
    end;
    

    This works only when MainForm.Visible is set True design time.