Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Application does not terminate on shutdown

Posted on 1997-05-14
9
Medium Priority
?
363 Views
Last Modified: 2010-04-04
I coded an application with delphi2 which runs in the system tray.
I am using the TrayIcon component for this.
But when shutting down Windows while my application runs, it does only terminate if it is not minimized.
Seems as if it could have something to do with TrayIcon...

Of course I read several FAQs on this topic and found some hints concerning WM_QUERYENDSESSION and WM_ENDSESSION, but if my application is minimized the message handler does not even get the WM_QUERYENDSESSION message.

What's wrong?
0
Comment
Question by:tier
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
9 Comments
 
LVL 3

Accepted Solution

by:
sperling earned 300 total points
ID: 1336245
Hmmm. I wrote a trayicon component once which in its first revision had this problem... I had not added handling for WM_QUERYENDSESSION to the trayicons message handler. This could very well be the problem, try to return 1 for this message in the  trayicons windowproc. If you've got source, please post the message handler and I'll look at it.

Regards,

Erik.
0
 
LVL 1

Author Comment

by:tier
ID: 1336246
The TrayIcon's WindowProc is as follows. I do not really know how to do the changes you proposed. Please have a look and tell me:

procedure TTrayIcon.WndProc(var Msg:TMessage);
begin
     with Msg
     do
       begin
            if msg = WM_CallBack_Message
            then
                case lParam
                of
                  WM_LButtonDblClk : if Assigned(fOnDblClick) then fOnDblClick(Self);
                  WM_LButtonUp     : if Assigned(fOnClick) then fOnClick(Self);
                  WM_RButtonUp     : HandleRightClick(Self);
                end
            else
                Result:=DefWindowProc(fWindowHandle,Msg,wParam,lParam);
       end;
end;

0
 
LVL 1

Author Comment

by:tier
ID: 1336247
Adjusted points to 100
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 1

Author Comment

by:tier
ID: 1336248
Hello?! Anyone out there?
Please answer the question, it's urgent...
0
 
LVL 3

Expert Comment

by:sperling
ID: 1336249
Could you post the entire TrayIcon source file, or point me to the URL where you found it.

Regards,

Erik.
0
 
LVL 1

Author Comment

by:tier
ID: 1336250
OK, this is the entire source:

unit TrayIcon;

{ TrayIcon v1.0
  Copyright (c) 1996 James Roberts-Thomson (com3roberjd@ntu.ac.uk)

  Based on TrayIcon v1.1, Tempest Software and
           TrayIcon v1.3, Peter Ness (102347.710@compuserve.com)

  A Delphi2 component designed to make creating SystemTray icons easier.
  Adding this component to a form, and when the control is active, the
  application will minimize to the SystemTray instead of the TaskBar.
  A popup menu may be made available (via a right-click on the icon).

  The component operates in two modes - if the "SeparateIcon" property is
  False (default), then the SysTray icon only appears when/if the application
  is minimized.  Setting the "SeparateIcon" property true allows both taskbar
  and SystemTray icons to appear, and also a SystemTray icon when the
  application isn't minimized.

  Requires Delphi 2.0 (32-bit), and either Windows95 or Windows-NT v4.0
  Component will compile and run with NT v3.51; but functionality is
  automatically disabled (NT v3.51 doesn't have a SystemTray).

  This component is Freeware, as were those it was based on.  You may freely
  use this component in any Application (be it Commercial, Shareware, or
  Freeware) without fee or royalty, provided this copyright notice remains
  intact.  Some minor form of recognition for commercial or shareware software
  would be nice.
 }

interface

uses
  Windows, Messages, SysUtils, ShellApi, Classes, Graphics, Controls,
  Forms, Menus;

Const WM_CallBack_Message = WM_User + 1;

type
  TTrayIcon = class(TComponent)
  private
    {Properties}
    fActive:Boolean;
    fHint:String;
    fIcon:TIcon;
    fPopupMenu:TPopupMenu;
    fSeparateIcon:Boolean;

    {events}
    fOnClick:TNotifyEvent;
    fOnDblClick:TNotifyEvent;
    fOnRightClick:TMouseEvent;
    fOnMinimize:TNotifyEvent;
    fOnRestore:TNotifyEvent;

    {Internal variables}
    fData:TNotifyIconData;
    fWindowHandle:hwnd;
    fWinVer4:Boolean;
    fMinimized:Boolean;
    fNoTrayIcon:Boolean;

  protected
    procedure SetActive(Value:Boolean);
    procedure SetHint(Value:String);
    procedure SetIcon(Icon:TIcon);
    procedure SetSeparateIcon(Value:Boolean);

    procedure AddIconToTray;
    procedure RemoveIconFromTray;
    procedure UpdateTrayIcon;
    procedure WndProc(var Msg:TMessage);
    procedure HandleRightClick(Sender:TObject);
    procedure HandleMinimize(Sender:TObject);
    procedure HandleRestore(Sender:TObject);

  public
    constructor Create(Owner:TComponent); override;
    destructor Destroy; override;

  published
    property Active:Boolean read fActive write SetActive;
    property Hint:string read fHint write SetHint;
    property Icon:TIcon read fIcon write SetIcon;
    property PopupMenu:TPopupmenu read fPopupMenu write fPopupMenu;
    property SeparateIcon:Boolean read fSeparateIcon write SetSeparateIcon;

    property OnClick:TNotifyEvent read fOnClick write fOnClick;
    property OnDblClick:TNotifyEvent read fOnDblClick write fOnDblClick;
    property OnRightClick:TMouseEvent read fOnRightClick write fOnRightClick;
    property OnMinimize:TNotifyEvent read fOnMinimize write fOnMinimize;
    property OnRestore:TNotifyEvent read fOnRestore write fOnRestore;
  end;

procedure Register;

implementation

{Create the Component}
constructor TTrayIcon.Create(Owner:TComponent);
var Hint:String;
    OSVerInfo:TOSVersionInfo;
    WindowPlacement:TWindowPlacement;
begin
     {Call inherited create method}
     Inherited Create(Owner);

     {Create the fIcon object, and assign the Application Icon to it}
     fIcon:=TIcon.Create;
     fIcon.Assign(Application.Icon);

     GetVersionEx(OSVerInfo);
     if OSVerInfo.dwMajorVersion > 3
     then
         fWinVer4:=True
     else
         fWinVer4:=False;

     fNoTrayIcon:=True;

     if not (csDesigning in ComponentState)
     then
         {At RunTime *only*, perform the following:}
         begin
              FillChar(fData, SizeOf(fData), 0);

              fWindowHandle:=AllocateHWnd(WndProc);

              fData.cbSize:=SizeOf(fData);
              fData.wnd:=fWindowHandle;
              fData.hIcon:=fIcon.Handle;
              fData.uFlags:=NIF_Icon OR NIF_Message;
              fData.uCallbackMessage:=WM_CallBack_Message;

              if fHint = ''
              then
                  Hint:=Application.Title
              else
                  Hint:=fHint;

              if Hint <> ''
              then
                  begin
                       fData.uFlags:=fData.uFlags OR NIF_Tip;
                       StrPLCopy(fData.szTip,Hint,SizeOf(fData.szTip)-1);
                  end;

              Application.OnMinimize:=HandleMinimize;
              Application.OnRestore:=HandleRestore;

              FillChar(WindowPlacement,SizeOf(WindowPlacement),0);
              WindowPlacement.length:=SizeOf(WindowPlacement);
              GetWindowPlacement(Application.Handle,@WindowPlacement);
              if WindowPlacement.showCmd = SW_ShowMinimized
              then
                  fMinimized:=True
              else
                  fMinimized:=False;

              if fActive and fMinimized
              then
                  AddIconToTray;
         end;
end;

{Destroy the Component}
destructor TTrayIcon.Destroy;
begin
     if fActive
     then
         RemoveIconFromTray;

     if not (csDesigning in ComponentState)
     then
         DeAllocateHWnd(FWindowHandle);

     fIcon.Free;
     inherited Destroy;
end;

procedure TTrayIcon.SetSeparateIcon(Value:Boolean);
begin
     if fSeparateIcon <> Value
     then
         fSeparateIcon:=Value;

     if not (csDesigning in ComponentState)
     then
         case fSeparateIcon
         of
           False:if fActive and (NOT fMinimized)
                 then
                     RemoveIconFromTray;
           True:if fActive
                then
                    AddIconToTray;
         end;
end;

procedure TTrayIcon.SetActive(Value:Boolean);
begin
     if fActive <> Value
     then
         fActive:=Value;

     if not (csDesigning in ComponentState)
     then
         if fActive and (fMinimized xor fSeparateIcon)
         then
             AddIconToTray
         else
             RemoveIconFromTray;
end;

procedure TTrayIcon.SetHint(Value:String);
begin
     if fHint <> Value
     then
         begin
              fHint:=Value;

              if not (csDesigning in ComponentState)
              then
                  begin
                       StrPLCopy(fData.szTip,fHint,SizeOf(fData.szTip)-1);
                       if fHint <> ''
                       then
                           fData.uFlags:=fData.uFlags OR NIF_Tip
                       else
                           fData.uFlags:=fData.uFlags AND NOT NIF_Tip;
                       UpdateTrayIcon;
                  end;
         end;
end;

procedure TTrayIcon.SetIcon(Icon:TIcon);
begin
     if fIcon <> Icon
     then
         begin
              fIcon.Assign(Icon);
              fData.hIcon:=Icon.Handle;
              UpdateTrayIcon;
         end;
end;

procedure TTrayIcon.AddIconToTray;
begin
     if fActive AND fWinVer4 AND fNoTrayIcon
     then
         if not Shell_NotifyIcon(NIM_Add,@fData)
         then
             raise EOutOfResources.Create('Cannot create shell notification icon')
         else
             fNoTrayIcon:=False;
end;

procedure TTrayIcon.RemoveIconFromTray;
begin
     if fWinVer4
     then
         Shell_NotifyIcon(NIM_Delete,@fData);
     fNoTrayIcon:=True;
end;

procedure TTrayIcon.UpdateTrayIcon;
begin
     if (fActive AND fWinVer4) AND not (csDesigning in ComponentState)
     then
         Shell_NotifyIcon(NIM_Modify,@fData);
end;

procedure TTrayIcon.WndProc(var Msg:TMessage);
begin
     with Msg
     do
       begin
            if msg = WM_CallBack_Message
            then
                case lParam
                of
                  WM_LButtonDblClk : if Assigned(fOnDblClick) then fOnDblClick(Self);
                  WM_LButtonUp     : if Assigned(fOnClick) then fOnClick(Self);
                  WM_RButtonUp     : HandleRightClick(Self);
                end
            else
                Result:=DefWindowProc(fWindowHandle,Msg,wParam,lParam);
       end;
end;

procedure TTrayIcon.HandleRightClick(Sender:TObject);
var CursorPos:TPoint;
begin
     if Assigned(fPopupMenu) AND ((NOT IsWindowVisible(Application.Handle)) OR
                                  fSeparateIcon)
     then
         begin
              GetCursorPos(CursorPos);
              fPopupMenu.Popup(CursorPos.X,CursorPos.Y);
         end;

     if Assigned(fOnRightClick)
     then
         fOnRightClick(Sender,mbRight,[],CursorPos.X,CursorPos.Y);
end;

procedure TTrayIcon.HandleMinimize(Sender:TObject);
begin
     if fActive
     then
         begin
              ShowWindow(Application.Handle,SW_Hide);
              if fNoTrayIcon
              then
                  AddIconToTray;
         end;
     fMinimized:=True;
     if Assigned(fOnMinimize)
     then
         fOnMinimize(Sender);
end;

procedure TTrayIcon.HandleRestore(Sender:TObject);
begin
     if fActive
     then
         begin
              ShowWindow(Application.Handle,SW_Restore);
              if not fSeparateIcon
              then
                  RemoveIconFromTray;
         end;
     if Assigned(fOnRestore)
     then
         fOnRestore(Sender);
     fMinimized:=False;
end;

procedure Register;
begin
  RegisterComponents('3rd Party', [TTrayIcon]);
end;

end.

0
 
LVL 3

Expert Comment

by:sperling
ID: 1336251
Try changing WndProc a bit.
Change:
---
end
else
  Result:=DefWindowProc(fWindowHandle,Msg,wParam,lParam);
end;
---
To:
---
end else if msg.msg = WM_ENDSESSION then begin
  if (msg.wParam<>0) then begin
    Active := FALSE;
  end;
end else if msg.msg = WM_QUERYENDSESSION then begin
  msg.Result := WORD(TRUE);
end
else
  Result:=DefWindowProc(fWindowHandle,Msg,wParam,lParam);
end;



Might help, but I ain't sure....

Regards,

Erik.

0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1336252
Bought This Question.
0
 
LVL 1

Author Comment

by:tier
ID: 1336253
What does it mean?
Why did you 'buy' this damn old question?
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

722 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question