Trayicon problem

Reply

Join Date: Oct 2007
Posts: 26
Reputation: csy is an unknown quantity at this point 
Solved Threads: 1
csy csy is offline Offline
Light Poster

Trayicon problem

 
0
  #1
Oct 18th, 2007
I try to use trayicon in delphi 5, but I can't hide the main form completely as which contain a MDI child form. Any solution for it?
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,951
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: Trayicon problem

 
0
  #2
Oct 18th, 2007
I've not messed with MDI forms much, but when you create your mainform you have to modify some of the application's system window properties.
Pascal and Delphi Syntax (Toggle Plain Text)
  1. procedure FormCreate(...);
  2. begin
  3. exstyle := getWindowLong( application.hanle, GWL_EXSTYLE )
  4. end;
  5.  
  6. procedure FormShow(...);
  7. begin
  8. setWindowLong( application.handle, GWL_EXSTYLE, exstyle )
  9. end;
  10.  
  11. procedure FormHide(...);
  12. begin
  13. setWindowLong( application.handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW )
  14. end;
The exstyle should be a cardinal variable somewhere.
Now the window will not appear in the taskbar whenever it is hidden. If you never want it in the taskbar then forget the show and hide stuff and just set the exstyle to toolwindow in the create event.

Hope this helps.
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 26
Reputation: csy is an unknown quantity at this point 
Solved Threads: 1
csy csy is offline Offline
Light Poster

Re: Trayicon problem

 
0
  #3
Oct 18th, 2007
Dear friend, thanks for reply! I've try your advice, but the result same.
After closed the main form, taskbar should be nothing only trayicon there. However the main form still in taskbar as which contain a MDI child form (I've tried to take out the child form then result OK :the taskbar show nothing ).

Any advice?

My FormClose coding about :

procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caNone;
hide;
end;
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,951
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: Trayicon problem

 
0
  #4
Oct 18th, 2007
I'm afraid I've never used the trayicon component, but a lot of these inject code into your application's or main form's constructor. Make sure that isn't happening.

If the problem is one of MDI then you'll have to wait until I mess around with it to figure out why...

(I use my Delphi 5 IDE for everything. Best IDE ever as far as I'm concerned...)

Give me a day or two and if you (or someone else) haven't figured it out by then I'll post a more comprehensive response.

Sorry I couldn't be of more help in the meantime...
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 26
Reputation: csy is an unknown quantity at this point 
Solved Threads: 1
csy csy is offline Offline
Light Poster

Re: Trayicon problem

 
0
  #5
Oct 18th, 2007
Thank you so much! thanks for your willing help!!
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,951
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: Trayicon problem

 
0
  #6
Oct 19th, 2007
Me again. I just made an MDI that lives in the System Tray without any trouble (~30 min). My only guess is that the trayicon component is doing something that is messing you up. So... here's what I can do for you.

How to put your application in the system tray using Delphi 5.

File: SystemTray.pas
  1. unit SystemTray;
  2. interface
  3. uses Windows;
  4.  
  5. const
  6. WM_ICONTRAY = WM_USER +1;
  7.  
  8. NIM_ADD = 0;
  9. NIM_MODIFY = 1;
  10. NIM_DELETE = 2;
  11.  
  12. NIF_MESSAGE = $00000001;
  13. NIF_ICON = $00000002;
  14. NIF_TIP = $00000004;
  15. NIF_STATE = $00000008;
  16. NIF_INFO = $00000010;
  17. NIF_GUID = $00000020;
  18.  
  19. type
  20. tNotifyIconData = record
  21. size: cardinal;
  22. wnd: THANDLE;
  23. ID: cardinal;
  24. flags: cardinal;
  25. callbackMessage: cardinal;
  26. icon: HICON;
  27. tip: array[ 0..63 ] of char;
  28. end;
  29.  
  30. function Shell_NotifyIcon( message: cardinal; var pnid: tNotifyIconData ): BOOL;
  31. stdcall; external 'shell32.dll' name 'Shell_NotifyIcon';
  32.  
  33. implementation
  34. end.

File: MAIN.pas
  1. unit Main;
  2. interface
  3. uses
  4. ..., SystemTray; // add the new unit to the end of your uses clause
  5.  
  6. type
  7. TMainForm = class(TForm)
  8. ...
  9. private
  10. // used when hiding the application from the taskbar
  11. f_ExStyle: cardinal;
  12. // used to add the application's icon to the system tray
  13. f_TrayIconData: tNotifyIconData;
  14. ...
  15. public
  16. procedure TrayMessage( var msg: tMessage ); message WM_ICONTRAY;
  17. ...
  18. end;
  19.  
  20. implementation
  21.  
  22. ...
  23.  
  24. procedure TMainForm.FormCreate(Sender: TObject);
  25. begin
  26. // remember the proper display mode for the application
  27. f_ExStyle := getWindowLong( application.handle, GWL_EXSTYLE );
  28.  
  29. // add the application icon to the system tray
  30. with f_TrayIconData do begin
  31. size := sizeof( tNotifyIconData );
  32. wnd := handle;
  33. ID := 0;
  34. flags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
  35. callbackMessage := WM_ICONTRAY;
  36. icon := application.icon.handle;
  37. strpcopy( tip, copy( application.title, 1, 63 ) )
  38. end;
  39. Shell_NotifyIcon( NIM_ADD, f_TrayIconData )
  40. end;
  41.  
  42. procedure TMainForm.FormDestroy(Sender: TObject);
  43. begin
  44. // remove the application icon from the system tray
  45. Shell_NotifyIcon( NIM_DELETE, f_TrayIconData )
  46. end;
  47.  
  48. procedure TMainForm.FormShow(Sender: TObject);
  49. begin
  50. // add the application to the taskbar if visible
  51. setWindowLong( application.handle, GWL_EXSTYLE, f_ExStyle )
  52. end;
  53.  
  54. procedure TMainForm.FormHide(Sender: TObject);
  55. begin
  56. // remove the application from the taskbar if hidden
  57. setWindowLong( application.handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW )
  58. end;
  59.  
  60. procedure TMainForm.TrayMessage( var msg: tMessage );
  61. begin
  62. // show the form if the user left-clicks the tray icon
  63. if msg.lParam = WM_LBUTTONDOWN then show
  64. end;
  65.  
  66. ...
  67. end.
Now, a Delphi MDI application by default uses tMainForm.close to terminate, so if you want to capture the system menu close event (clicking the [X] button on the titlebar or chosing "Close" from the application's system menu or pressing Alt+F4) you'll have to account for actual attempts to terminate the application in the FormCanClose method. Personally, I like the way ZoneAlarm AntiVirus does it. If you click the [X] button it pops up a dialogue asking whether you really want to terminate or just to minimize to the system tray, and remembers the response. If you select minimize it gives you another dialogue with instructions on how to actually terminate the application.

Well, that's it.
Hope this helps.
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 26
Reputation: csy is an unknown quantity at this point 
Solved Threads: 1
csy csy is offline Offline
Light Poster

Re: Trayicon problem

 
0
  #7
Oct 20th, 2007
Thanks friend.
As the example, I need to custom the trayicon component, right?

I'll try it!

What my application request is :
At the starting only tray icon , after click the tray icon, the form display, after press the [x] to close the form, the form hidden but tryicon still fuction, only right click the trayicon and select the "terminate" the application will be terminate completly.

But I tried quite a long time still can't make the application hide completely (still display in task bar) as MDI child form.
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,951
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: Trayicon problem

 
0
  #8
Oct 22nd, 2007
Don't give up yet. I failed to account for the MDI child forms.

The icon/button you see on the taskbar actually belongs to the application, and not the main form. So if you have any windows other than the main form open (you can't hide a MDI child form) the application button will automagically appear on the taskbar.

The trick is to get rid of the application button and put the main form's button on the taskbar instead.

Like I said, I haven't played much with MDI applications before so I've had to learn some stuff to help. I'm cleaning up my code now. Give me another day or two and I'll post an example that does everything you want (and then some) with full source code you can scavenge as you like.
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 26
Reputation: csy is an unknown quantity at this point 
Solved Threads: 1
csy csy is offline Offline
Light Poster

Re: Trayicon problem

 
0
  #9
Oct 22nd, 2007
Thanks your encourage.

Here is my simple testing :


File: ChildForm.pas
  1. unit ChildForm;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
  7.  
  8. type
  9. TForm2 = class(TForm)
  10. private
  11. { Private declarations }
  12. public
  13. { Public declarations }
  14. end;
  15.  
  16. var
  17. Form2: TForm2;
  18.  
  19. implementation
  20.  
  21. {$R *.DFM}
  22.  
  23. end.


File: MainForm.pas
  1. unit MainForm;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7. TrayIcon, StdCtrls, ExtCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. TrayNotifyIcon1: TTrayNotifyIcon;
  12. Timer1: TTimer;
  13. procedure Timer1Timer(Sender: TObject);
  14. procedure FormCreate(Sender: TObject);
  15. procedure TrayNotifyIcon1DblClick(Sender: TObject);
  16. procedure TrayNotifyIcon1Click(Sender: TObject);
  17. private
  18. { Private declarations }
  19. procedure createchildform;
  20. public
  21. { Public declarations }
  22. end;
  23.  
  24. var
  25. Form1: TForm1;
  26.  
  27. implementation
  28. uses ChildForm;
  29. {$R *.DFM}
  30.  
  31. procedure TForm1.createchildform ;
  32. var tempChildForm : TForm2;
  33. begin
  34. try
  35. tempChildForm := TForm2.Create(Self);
  36. tempChildForm.FormStyle := fsMDIChild ;
  37.  
  38.  
  39. finally
  40.  
  41. end;
  42. end ;
  43.  
  44. procedure TForm1.Timer1Timer(Sender: TObject);
  45. begin
  46. Timer1.Enabled := False;
  47. try
  48. createchildform ;
  49. Finally
  50. End ;
  51. end;
  52.  
  53. procedure TForm1.FormCreate(Sender: TObject);
  54. begin
  55.  
  56. TrayNotifyIcon1.IconVisible := True;
  57.  
  58. end;
  59.  
  60. procedure TForm1.TrayNotifyIcon1DblClick(Sender: TObject);
  61. begin
  62. show ;
  63. end;
  64.  
  65. procedure TForm1.TrayNotifyIcon1Click(Sender: TObject);
  66. begin
  67. hide;
  68. end;
  69. end.

I'd set Application.ShowMainForm := False before application run.
Reply With Quote Quick reply to this message  
Join Date: Oct 2007
Posts: 1,951
Reputation: Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of Duoas has much to be proud of 
Solved Threads: 214
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: Trayicon problem

 
1
  #10
Oct 27th, 2007
Time enough has passed that I haven't answered here.

As I mentioned already, the reason you see a button on the taskbar is because the application puts it there. Your forms don't. You can see this by going to the main menu --> Project --> Options --> Application --> Title and giving your application a title that differs from the main form's caption. The button on the taskbar will show the application title, and not the mainform caption.

When you have MDI children, which cannot be hidden, the application button is restored to the taskbar because you technically still have windows showing... even if the MDI main form is hidden.

So, to get rid of it you have to turn it off explicitly. In MAIN.pas, make sure you have the following:
  1. interface
  2. type
  3. TMainForm = class(TForm)
  4. procedure ApplicationActivate(Sender: TObject);
  5. procedure FormCreate(Sender: TObject);
  6. private:
  7. procedure SysCommandMessage(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  8. protected:
  9. procedure CreateParams(var Params: TCreateParams); override;
  10. end;
  11.  
  12. implementation
  13.  
  14. procedure TMainForm.ApplicationActivate( Sender: TObject );
  15. begin
  16. // Remove the application button from the taskbar
  17. // (and make sure it stays that way)
  18. ShowWindow( Application.Handle, SW_HIDE )
  19. end;
  20.  
  21. procedure TMainForm.FormCreate( Sender: TObject );
  22. begin
  23. // Keep the application button out of the taskbar
  24. application.OnActivate := ApplicationActivate
  25. end;
  26.  
  27. procedure TMainForm.SysCommandMessage(var Msg: TWMSysCommand);
  28. begin
  29. // Routing WM_SYSCOMMAND messages through here instead of the default
  30. // handler prevents Delphi from trying to create a taskbar button for the
  31. // application when minimized and maximized, which when combined with
  32. // ApplicationActivate would otherwise cause flicker.
  33. //
  34. // You could capture the SC_MINIMIZE command here and instead hide the
  35. // window, but you would have to make sure to let the user know that the
  36. // window was minimized to the system tray. Otherwise it will look like the
  37. // window just disappeared...
  38. //
  39. // You could also remove biMinimize and biMaximize from the mainForm's
  40. // BorderIcons, and trap the SC_MINIMIZE button to do nothing... For
  41. // example:
  42. // if msg.CmdType <> SC_MINIMIZE then defaultHandler( msg )
  43. //
  44. defaultHandler(Msg)
  45. end;
  46.  
  47. procedure TMainForm.CreateParams(var Params: TCreateParams);
  48. begin
  49. // Add the main form's window button to the taskbar
  50. inherited CreateParams(Params);
  51. Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  52. Params.WndParent := GetDesktopWindow
  53. // If I understand things correctly, if you comment out the last line then
  54. // when you manipulate the window (say, restore it) other toplevel windows
  55. // belonging to the application will also be affected (say, restored). But
  56. // since this is an MDI application you shouldn't have any other toplevel
  57. // windows... And I haven't played around with this any...
  58. end;
If you insert this code into your main form you will get the taskbar button response you want. Weird stuff, huh?

I'll post back in a few days more with a fairly interesting example (I've been having fun with it, but my simple object pascal syntax highlighter needs a little more work...) which comes with all its own source code and demonstrates all kinds of weird things, such as how to make an application mutex to prevent multiple instances of the application from running at the same time, tray icon popup menus and animations, using XP style controls if available, etc.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Pascal and Delphi Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC