Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Remove tray icon when killing program (https://www.delphipraxis.net/177126-remove-tray-icon-when-killing-program.html)

WojTec 17. Okt 2013 20:09

Delphi-Version: 2010

Remove tray icon when killing program
 
I TerminateProcess() another program.
Is possible to remove from tray this program icon (if any)?

himitsu 17. Okt 2013 20:37

AW: Remove tray icon when killing program
 
You can not, because when the program is terminated, it can do nothing more.

jaenicke 17. Okt 2013 20:50

AW: Remove tray icon when killing program
 
There are a few dirty solutions out in the internet, but no really good solution.

The following method works, but I would not recommend it:
Move the mouse cursor over the tray icons, let the mouse click on the button to expand the tray icons, move the mouse over all icons...
If you do this with your programm, all tray icons are clean then, but for the user it is not really a good solution I think.

Luckie 17. Okt 2013 22:47

AW: Remove tray icon when killing program
 
If you get shot in your head, will you be able to tell the police afterwards who shot you? Or if a process was able to do something after ist was killed, it could restart it self. Ergo the function TerminateProcess would be needles.

CCRDude 18. Okt 2013 07:03

AW: Remove tray icon when killing program
 
Injecting code that removes the tray icon would also work, at least as long as you're speaking about a fixed process (you need to find the right handle) and not in general.

Furtbichler 18. Okt 2013 07:24

AW: Remove tray icon when killing program
 
Zitat:

Zitat von jaenicke (Beitrag 1232363)
The following method works, but I would not recommend it:

Why wouldn't you recommend it. It's safe, easy to implement, harmless and robust. What else do you want from a good solution? ;-)

BTW: A 'Tray-icon-cleaner' as a separate process would solve the problem. It would run constantly (just another useless process) and cleans the icon area once a second. Don't know if it is possible though, but why not.

No need to use zombies ('shot in the head and go to the police'). This is a job for a 'witness' or a 'sentinel', right?

himitsu 18. Okt 2013 08:50

AW: Remove tray icon when killing program
 
TerminateProcess ist nicht der "normale" Weg, um eine Anwendung zu beenden.
Man könnte natürlich auch versuchen sein Programm so zuverlässig zu schreiben, daß ein derartiger Schritt nicht notwendig ist. :angle2:

WojTec 18. Okt 2013 09:59

Re: Remove tray icon when killing program
 
Windows don't have any routine to refresh tray, like graphical objects has in Delphi? How it do it when program remove icon themself?

Ok, anyway, I have another idea, but don't know how to code it: send close command and whait let's say 2secs to execute, if not executed then kill it. 1: how to perform close command when only icon in try? 2: How to wait for execution n seconds?

DeddyH 18. Okt 2013 10:10

AW: Remove tray icon when killing program
 
Just a few thoughts: you know the ProcessHandle, which is needed for TerminateProcess. To retrieve the corresponding ProcessID you could call OpenProcess. Once you have this ID you could call EnumWindows and within its callback compare your ProcessID to the one of the current window using GetWindowThreadProcessId. If they match, send your Close-Command to that window. I think this should work, but did not try it.

Der schöne Günther 18. Okt 2013 10:27

AW: Remove tray icon when killing program
 
That might indeed sound pretty complicated but there are a lot of free code snippets for "How do I find a window handle if I only have the process ID?". It's also what I'd strongly suggest since TerminateProcess is pretty much like shooting someone in the head... from behind.

Always give the other application a fair change to shut down and clean up. This also includes the remaining unwanted tray icon (blood splatter?).

Here's an excerpt of how I search for the Window handle of a process I only have the ID of for later sending a WM_CLOSE message. I believe it has a few shortcomings like only returning the first window that matches but it always served me well.

Delphi-Quellcode:
   TEnumInfo = record
      ProcessID: DWORD;
      HWND: THandle;
   end;

   //Prozess-ID muss stimmen. Das Fenster muss nicht aktiviert oder sichtbar sein!
   function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
   var
      PID: DWORD;
   begin
      GetWindowThreadProcessID(Wnd, @PID);
      Result := (PID <> EI.ProcessID);
      //or IsWindowVisible(WND)) or (not IsWindowEnabled(WND));

      if not Result then EI.HWND := WND; //Die Enumeration durch alle Fenster
      // geht NUR weiter, wenn diese Funktion TRUE liefert!
   end;

   //Wird kein Fenster gefunden, ist die Rückgabe 0
   function FindFirstWindow(PID: DWORD): DWORD;
   var
      EI: TEnumInfo;
   begin
      EI.ProcessID := PID;
      EI.HWND := 0;
      EnumWindows(@EnumWindowsProc, Integer(@EI));
      Result := EI.HWND;
   end;
Most of it was probably "borrowed" from this very forum.

You can then just get the Windowhandle
Delphi-Quellcode:
evilWindowHandle := FindFirstWindow(evilProcess.dwProcessId);
and send a WM_CLOSE:
Delphi-Quellcode:
PostMessage(evilWindowHandle, WM_CLOSE, LPARAM(False), WPARAM(False));


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:47 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz