| | |
Trayicon problem
![]() |
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.
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.
Pascal and Delphi Syntax (Toggle Plain Text)
procedure FormCreate(...); begin exstyle := getWindowLong( application.hanle, GWL_EXSTYLE ) end; procedure FormShow(...); begin setWindowLong( application.handle, GWL_EXSTYLE, exstyle ) end; procedure FormHide(...); begin setWindowLong( application.handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW ) end;
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.
•
•
Join Date: Oct 2007
Posts: 26
Reputation:
Solved Threads: 1
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;
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;
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...
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...
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
File: MAIN.pas
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.
How to put your application in the system tray using Delphi 5.
File: SystemTray.pas
Pascal Syntax (Toggle Plain Text)
unit SystemTray; interface uses Windows; const WM_ICONTRAY = WM_USER +1; NIM_ADD = 0; NIM_MODIFY = 1; NIM_DELETE = 2; NIF_MESSAGE = $00000001; NIF_ICON = $00000002; NIF_TIP = $00000004; NIF_STATE = $00000008; NIF_INFO = $00000010; NIF_GUID = $00000020; type tNotifyIconData = record size: cardinal; wnd: THANDLE; ID: cardinal; flags: cardinal; callbackMessage: cardinal; icon: HICON; tip: array[ 0..63 ] of char; end; function Shell_NotifyIcon( message: cardinal; var pnid: tNotifyIconData ): BOOL; stdcall; external 'shell32.dll' name 'Shell_NotifyIcon'; implementation end.
File: MAIN.pas
Pascal Syntax (Toggle Plain Text)
unit Main; interface uses ..., SystemTray; // add the new unit to the end of your uses clause type TMainForm = class(TForm) ... private // used when hiding the application from the taskbar f_ExStyle: cardinal; // used to add the application's icon to the system tray f_TrayIconData: tNotifyIconData; ... public procedure TrayMessage( var msg: tMessage ); message WM_ICONTRAY; ... end; implementation ... procedure TMainForm.FormCreate(Sender: TObject); begin // remember the proper display mode for the application f_ExStyle := getWindowLong( application.handle, GWL_EXSTYLE ); // add the application icon to the system tray with f_TrayIconData do begin size := sizeof( tNotifyIconData ); wnd := handle; ID := 0; flags := NIF_MESSAGE or NIF_ICON or NIF_TIP; callbackMessage := WM_ICONTRAY; icon := application.icon.handle; strpcopy( tip, copy( application.title, 1, 63 ) ) end; Shell_NotifyIcon( NIM_ADD, f_TrayIconData ) end; procedure TMainForm.FormDestroy(Sender: TObject); begin // remove the application icon from the system tray Shell_NotifyIcon( NIM_DELETE, f_TrayIconData ) end; procedure TMainForm.FormShow(Sender: TObject); begin // add the application to the taskbar if visible setWindowLong( application.handle, GWL_EXSTYLE, f_ExStyle ) end; procedure TMainForm.FormHide(Sender: TObject); begin // remove the application from the taskbar if hidden setWindowLong( application.handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW ) end; procedure TMainForm.TrayMessage( var msg: tMessage ); begin // show the form if the user left-clicks the tray icon if msg.lParam = WM_LBUTTONDOWN then show end; ... end.
Well, that's it.
Hope this helps.
•
•
Join Date: Oct 2007
Posts: 26
Reputation:
Solved Threads: 1
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.
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.
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.
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.
•
•
Join Date: Oct 2007
Posts: 26
Reputation:
Solved Threads: 1
Thanks your encourage.
Here is my simple testing :
File: ChildForm.pas
File: MainForm.pas
I'd set Application.ShowMainForm := False before application run.
Here is my simple testing :
File: ChildForm.pas
Delphi Syntax (Toggle Plain Text)
unit ChildForm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm2 = class(TForm) private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation {$R *.DFM} end.
File: MainForm.pas
Delphi Syntax (Toggle Plain Text)
unit MainForm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, TrayIcon, StdCtrls, ExtCtrls; type TForm1 = class(TForm) TrayNotifyIcon1: TTrayNotifyIcon; Timer1: TTimer; procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure TrayNotifyIcon1DblClick(Sender: TObject); procedure TrayNotifyIcon1Click(Sender: TObject); private { Private declarations } procedure createchildform; public { Public declarations } end; var Form1: TForm1; implementation uses ChildForm; {$R *.DFM} procedure TForm1.createchildform ; var tempChildForm : TForm2; begin try tempChildForm := TForm2.Create(Self); tempChildForm.FormStyle := fsMDIChild ; finally end; end ; procedure TForm1.Timer1Timer(Sender: TObject); begin Timer1.Enabled := False; try createchildform ; Finally End ; end; procedure TForm1.FormCreate(Sender: TObject); begin TrayNotifyIcon1.IconVisible := True; end; procedure TForm1.TrayNotifyIcon1DblClick(Sender: TObject); begin show ; end; procedure TForm1.TrayNotifyIcon1Click(Sender: TObject); begin hide; end; end.
I'd set Application.ShowMainForm := False before application run.
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:
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.
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:
Delphi Syntax (Toggle Plain Text)
interface type TMainForm = class(TForm) procedure ApplicationActivate(Sender: TObject); procedure FormCreate(Sender: TObject); private: procedure SysCommandMessage(var Msg: TWMSysCommand); message WM_SYSCOMMAND; protected: procedure CreateParams(var Params: TCreateParams); override; end; implementation procedure TMainForm.ApplicationActivate( Sender: TObject ); begin // Remove the application button from the taskbar // (and make sure it stays that way) ShowWindow( Application.Handle, SW_HIDE ) end; procedure TMainForm.FormCreate( Sender: TObject ); begin // Keep the application button out of the taskbar application.OnActivate := ApplicationActivate end; procedure TMainForm.SysCommandMessage(var Msg: TWMSysCommand); begin // Routing WM_SYSCOMMAND messages through here instead of the default // handler prevents Delphi from trying to create a taskbar button for the // application when minimized and maximized, which when combined with // ApplicationActivate would otherwise cause flicker. // // You could capture the SC_MINIMIZE command here and instead hide the // window, but you would have to make sure to let the user know that the // window was minimized to the system tray. Otherwise it will look like the // window just disappeared... // // You could also remove biMinimize and biMaximize from the mainForm's // BorderIcons, and trap the SC_MINIMIZE button to do nothing... For // example: // if msg.CmdType <> SC_MINIMIZE then defaultHandler( msg ) // defaultHandler(Msg) end; procedure TMainForm.CreateParams(var Params: TCreateParams); begin // Add the main form's window button to the taskbar inherited CreateParams(Params); Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; Params.WndParent := GetDesktopWindow // If I understand things correctly, if you comment out the last line then // when you manipulate the window (say, restore it) other toplevel windows // belonging to the application will also be affected (say, restored). But // since this is an MDI application you shouldn't have any other toplevel // windows... And I haven't played around with this any... end;
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.
![]() |
Similar Threads
- Problem with Windows Update and WinXP (Web Browsers)
- Installing Windows 98 On VMware. Floppy problem (Windows 95 / 98 / Me)
- Windows XP keeps restarting since a new video card (Windows NT / 2000 / XP)
- Redhat Linux 6.2 - ipop3d problem? (*nix Software)
- Problem with T720 (Cellphones, PDAs and Handheld Devices)
- Connection Problems (Networking Hardware Configuration)
- Encoding (Unicode) problem in IE 6.0 (Web Browsers)
- .htaccess mod_rewrite problem (Linux Servers and Apache)
- Javascript/HTML problem!!! (JavaScript / DHTML / AJAX)
Other Threads in the Pascal and Delphi Forum
- Previous Thread: How to Make a tray icon bright/ change colour
- Next Thread: Web Enabling Applications
| Thread Tools | Search this Thread |






