Link to home
Start Free TrialLog in
Avatar of ZaSz
ZaSzFlag for Canada

asked on

My Tray Icon doesnt work like i want

I want my app to be on top with focus when I double click the tray Icon. I have tried lots of example but all of them leave my app in the back and flash my app in the task bar.
Here is my code for now:

// Loading
  TrayIcon.cbSize := SizeOf(TrayIcon);
  TrayIcon.Wnd := Self.Handle;
  TrayIcon.uID := 0;
  TrayIcon.uFlags := NIF_ICON or NIF_TIP or NIF_MESSAGE;
  TrayIcon.uCallbackMessage := WM_MOUSEMOVE;
  TrayIcon.hIcon := Application.Icon.Handle;
  TrayIcon.szTip := MyAppTip;
  Application.OnMinimize := MinTray;

// Minimize
procedure TPrinc.MinTray(Sender: TObject);
begin
  Shell_notifyIcon(NIM_ADD, @TrayIcon);
  Princ.Visible:= False;
  Application.ShowMainForm := Visible;
end;

//Maximise
procedure TPrinc.MaxTray;
begin
  Princ.Show;
  Application.ShowMainForm := Visible;
  SetForegroundWindow(Application.Handle);
  Shell_notifyIcon(NIM_DELETE, @TrayIcon);
end;

//Double click on the tray
procedure TPrinc.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if X = 515 then // Double click
    MaxTray;
end;

Sorry for my bad english :|
Thanks for helping me
ASKER CERTIFIED SOLUTION
Avatar of MannSoft
MannSoft

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Lukasz Lach
Lukasz Lach

procedure TPrinc.MaxTray;
begin
 Princ.Show;
 Application.ShowMainForm := Visible;
 SetForegroundWindow(Application.Handle);
 Shell_notifyIcon(NIM_DELETE, @TrayIcon);
end;

stupid ;/
should be:

procedure TPrinc.MaxTray;
begin
 ShowWindow(Handle, SW_SHOW);
 SetForegroundWindow(Handle);
 Shell_notifyIcon(NIM_DELETE, @TrayIcon);
end;
Avatar of ZaSz

ASKER

anAKin, the form doesnt even show up with your code...
Avatar of ZaSz

ASKER

Thanks MannSoft
depends in wchih state your form ism you can also try
Application.Restore -> if minimized,
Show -> the same
but the point is SetForegroundWindow(Handle); which i always use when form isn't minimized, only under other applications... that works and it's no need to use component for tray...
Avatar of ZaSz

ASKER

I had the SetForeGroundWindow, but it was only flashing the taskbar :(
procedure TForm1.FormCreate(Sender: TObject);
var
  LockTimeOut: Integer;
begin
  LockTimeOut := 0;
  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(LockTimeOut), SPIF_UPDATEINIFILE or SPIF_SENDCHANGE);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  LockTimeOut: Integer;
begin
  LockTimeOut := 40000;
  SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, Pointer(LockTimeOut), SPIF_UPDATEINIFILE or SPIF_SENDCHANGE);
end;

and simply use Application.BringToFront; in your MaxTray procedure ;-) I said there is no need to use component... The thing is that Tray components are just useless...
I think them being useless is a matter of personal opinion.  I have many programs that are loaded the entire time my computer is running.  Some are not interactive and it is wasteful to be in the system tray, but it is better than the taskbar where it would take even more space.

And some programs, like winamp for example, are interactive.  When it is minimized to the system tray not only does it take up less space than it would on the taskbar, but i can right click and control it from the popup menu without restoring the form.

So I think tray components definitely have their place.
Avatar of ZaSz

ASKER

And an other thing with component: It's easy to use!
I didn't say that placing icon in the tray is useless, i said it about using a component for that...

ZaSz:
So let's mabye use components for everyting:
TIntToStr, TStrToInt, TFormat, TInc and TDec, because it would be easier... Using component when there is realy no need to do that (cause you had it API like, the olny thing was that app was blinbing, bot showing) is needless...
I think that isnt a very good example.  How does using a component for simple functions make it easier?

A tray component certainly makes things easier.  Maybe not if you only write one application.  But what if you write 10 that use the system tray?  That means you need to rewrite the same code 10 times which really increases the possibility for error.  Either that or you copy and paste 10 times.  That's much easier, but what if you find you've made an error somewhere, or want to implement some new feature.  Now you have to go back and change the same code in 10 different places.  With a component you dont have to worry about that.  Fix the component once, recompile the applications that use it, and voila you are done.

To me it's all a matter of efficiency.  If one way is going to obviously save me time and effort and the other way only has disadvantages, it really isnt a hard decision to make...  But I guess everyone is entitled to their opinion.
Sure, you are right...
But are we supposed to use someone's component every time we have a litte problem while solvig the solution? That is not the best way to learn how to code, is it?
No of course simply using the component isnt the best way to learn how to code.  But I think thats why most component developers usually release the source code.  They realize other people might be interested in seeing how it works, and to me, seeing strange function calls and having to look them up to see what they do is a great way to learn.