Search code examples
delphidelphi-2007

Minimize Application (NOT using trayicon)


I have read much about this but I seem to get more confused, the more I read. I'm using Delphi 2007 and I want to minimize my application at startup, I am not interested in system tray icon, just need a taskbar icon in order to be able to restore the application.

If you take the simplest of all projects with just a main form and in the .dpr file set:

Application.MainFormOnTaskBar := true;
Application.ShowMainForm := false;

and run the application, there is NO TASKBAR ICON visible thus no way to restore and activate the application.

What is the proper way to minimize on startup without showing the main form then making it minimized? This would seem so simple but for me it is not.


Solution

  • Indeed this is simple and explained in the documentation but a bit difficult to find since it is not linked from where you might expect/search for it.

    System.CmdShow

    Specifies the flags for displaying the application's main window.


    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CmdShow := SW_SHOWMINNOACTIVE;
      ...
    


    It is not documented but the only supported flags are SW_SHOWMINNOACTIVE and SW_SHOWMAXIMIZED, so you can't use SW_SHOWMINIZED.

    Also, don't forget to remove the ShowMainForm := false; statement, otherwise the form won't be visible and hence there won't be any taskbar icon.

    Update

    There's a bug in D2007's TApplication.Run (which is corrected at least in XE2) that causes the above solution to prevent the main form to be shown at all. That's a missing FInitialMainFormState := wsMinimized; statement in the SW_SHOWMINNOACTIVE case branch.

    In D2007 use WindowState, but OnCreate of the form is too early to set it, the VCL assigns the main form after OnCreate runs and modifies some of the window styles. Use OnShow together with a flag so that you don't set the window state in the lifetime of the application other than at the startup.

    type
      TForm1 = class(TForm)
        ..
      private
        FRunOneTime: Boolean;
        ..
    
    procedure TForm1.FormShow(Sender: TObject);
    begin
      if not FRunOneTime then begin
        WindowState := wsMinimized;
        FRunOneTime := True;
      end;
    end;