  
  SystrayApplication.pas

  Borland Delphi 4.0 Component.
  Programmed 1999 by Jan Bohlen. <jan.bohlen@tu-clausthal.de>

  Please feel free to distribute this component, but inform
  me about any source code changes that you make.

  Any comments to improve this component would be helpful.


  HOW TO USE:
  -----------

  0. All the examples below use a 'Systray: TSystrayApplication'
     field in your main form's declaration. Of course you can
     assign a name other than 'Systray'.


  1. This component is meant for applications that totally rely
     on a system tray icon and don't have any visible main form.
     This means:

     a) You design your application as usual, but your main form
        is just a container for TSystrayApplication and any other
        (non-visual) components that you would like to use. Your
        main form will only be visible during draft time.

     b) Your system tray application is controled by a user-de-
        fined TPopupMenu. You MUST assign a TPopupMenu component
        during draft time, otherwise an ESystrayApplication
        exception is raised (simply because your application
        could not be controled without a TPopupMenu).

     c) You MUST NOT (!) declare an event handler for the 'OnShow'
        event of your MAIN FORM. Any other form's 'OnShow'-
        event handler may be declared as usual. (This is because
        TSystrayApplication overrides the main form's 'OnShow'
        handler to hide the main form. For further details look
        at the source code.)


  2. To bring up a MessageBox or another form (modal or normal)
     use TSystrayApplication's methods:

     a) function TSystrayApplication.MessageBox(...)

        Parameters and return value like TApplication.MessageBox
        except that strings are used instead of PChar (makes it
        easier for you). ALWAYS use this type of message box
        instead of MessageDlg, TApplication.MessageBox or
        Windows.MessageBox. This method does essentially the
        same (and more).


     b) procedure TSystrayApplication.Show(const AForm: TForm;
         ForbidRightClick: Boolean = False);

        AForm = Form that you want to bring up;

        ForbidRightClick = Optional parameter to prevent
        the user from right mouse button clicks, while the
        form is visible; in this case you must execute the
        'AllowRightClick' method in the form's 'OnClose' event
        handler (usually you will use the following ShowModal
        method instead of this method, so don't think about
        it too much!);


     c) function TSystrayApplication.ShowModal(const AForm: TForm): Integer;

        AForm = Form that you want to bring up modal;

        Return value = Modal result of the form (if used);


     Q: WHY should I use these methods instead of
        TApplication.MessageBox, TForm.Show and TForm.ShowModal?

     A: TSystrayApplication internally counts open windows by
        these methods. While any window is open, you won't be
        able to right click the application's system tray icon
        to bring up the TPopupMenu. (This is reasonable, because
        otherwise it would for example be possible to simul-
        taniously open a result form and an options form. The
        result form works with set options, and the options
        are changed, while the result form is visible. There-
        fore the result form would not show the correct result
        depending on the options. Complex, but perhaps you see
        what I mean!?).


     Q: Examples for these methods?

     A: ModRes := Form2.ShowModal;

            ... would be...

        ModRes := Systray.ShowModal(Form2);


        Application.MessageBox('Text', 'Caption', mb_OK);

                       ... would be...

        Systray.MessageBox('Text', 'Caption', mb_OK);


     Q: Will my forms and message boxes pop up 'WS_TOPMOST'
        even if other apps are currently active?

     A: Yes. This is another advantage of TSystrayApplication's
        methods.


  3) If your application is in a 'critical section' (maybe you
     use a timer that checks something every _ minutes), you
     would also like to prevent the user from bringing up your
     application's TPopupMenu. To do so, use the following pro-
     perties:

     a) property CriticalSectionHint: string;

        A hint that is displayed during your critical section, if
        the user moves her/his mouse pointer over the system tray
        icon.


     b) property CriticalSection: Boolean;

        Set 'True', if you enter your critical section,
        set 'False', if you exit your critical section (the sys-
        tem tray icon's hint is restored to its previous hint).


     Q: Examples for these properties?

     A: procedure MyForm.TimerTimer(Sender: TObject);
        begin
          MyTimer.Enabled := False;

          Systray.CriticalSectionHint := 'Calculating...';
          Systray.CriticalSection := True;

          ... // Your calculations

          Systray.CriticalSection := False;
          MyTimer.Enabled := True;
        end;


  4) Use of the RightClickAllowed method:

     function TSystrayApplication.RightClickAllowed: Boolean;

     There is a possibility (if you use timers), that the
     user is currently browsing your TPopupMenu, while your
     timer's event handler is called. So your application is
     in a critical section, but the user nevertheless is able
     to execute a TPopupMenu's command, which would cause
     trouble in certain circumstances. To prevent the user
     from executing TPopupMenu's commands use the following
     code (example for an exit command in your TPopupMenu):

     procedure MyForm.puExit(Sender: TObject);
     begin
       Close;
     end;

                ... would be...

     procedure MyForm.puExit(Sender: TObject);
     begin
       if RightClickAllowed then
         Close;
     end;


   5) General properties:

      a) property Icon: TIcon;

         Usually TSystrayApplication uses the icon which is
         set in your project options (Application.Icon). If
         you want to change the system tray icon during run
         time, use the Icon property. Example:

         Systray.Icon := LoadIcon(0, IDI_WINLOGO);

         ... // Your code

         Systray.Icon := Application.Icon; // Restores the icon


      b) property Hint: string;

         Use this property to set your system tray icon's hint
         during draft or run time.


      c) property PopupMenu: TPopupMenu;

         Self explaining: Assign your application's TPopupMenu
         (ONLY (!) during draft time, otherwise an ESystray-
         Application exception is raised).


      d) property OnDblClick: TNotifyEvent;

         Assign your event handler for a double click on your
         system tray icon. If unassigned, a double click does
         nothing.


   6) A single left mouse button click always puts your appli-
      cation into the foreground.


   7) Now go ahead, and build your own system tray application.
