AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Tray-Icon entfernen nach Beenden des Prozesses
Thema durchsuchen
Ansicht
Themen-Optionen

Tray-Icon entfernen nach Beenden des Prozesses

Ein Thema von ernschd · begonnen am 3. Dez 2009 · letzter Beitrag vom 7. Dez 2009
Antwort Antwort
ernschd

Registriert seit: 16. Jan 2008
165 Beiträge
 
Delphi XE8 Professional
 
#1

Tray-Icon entfernen nach Beenden des Prozesses

  Alt 3. Dez 2009, 14:21
Hi,
ich habe eine Routine, um einen Windows-Prozess zu beenden(ein fremdes Programm). Danach wird aber immer noch das Icon im SysTray angezeigt. Also habe ich eine vorhandene(und funktionierende) VB6-Funktion in Delphi konvertiert. Leider funktioniert sie dort jedoch nicht.

Ich habe schon die verschiedenen Kombinationen durchprobiert, unter anderem:
Delphi-Quellcode:
InvalidateRect(hSysTray, @rRect, True);
SendMessage(hSysTray, WM_PAINT, 0, 0);
SendMessage(hTray, WM_MOUSEMOVE, 0, 0);
Alles ohne Erfolg.

Hat jemand ein funktionierendes Codebeispiel für mich?

Danke & Gruß,
Ernschd
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 3. Dez 2009, 19:50
Wie entfernst du denn bei Programmende das Icon aus der TNA?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 3. Dez 2009, 20:53
@Luckie: lies am besten nochmal den ersten Beitrag Er killt ein fremdes Programm welches ein Trayicon hat. Und mit dem geposteten Code versucht er dann das Trayicon des fremden Programmes weg zu bekommen.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 3. Dez 2009, 20:59
Mist, habe ich überlesen. Aber ich meine das Problem hatten wir schon mal. Hast du mal im Forum gesucht? Stimmt das Handle? Wie ermittelst du es?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von toms
toms
(CodeLib-Manager)

Registriert seit: 10. Jun 2002
4.648 Beiträge
 
Delphi XE Professional
 
#5

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 4. Dez 2009, 00:08
Hallo,

Du könntest das TNA Icon vor dem Beenden des Prozesses verstecken. Nach dem Beenden des Prozesses ist es dann ganz weg.
// Achtung: Nur mit D6, Vista 32 getestet....

Delphi-Quellcode:
uses
  PsAPI, CommCtrl;

function HideTNAIcon(ProcPath: AnsiString; HideIcon: Boolean = True): Boolean;

  function GetProcPath(wnd: HWND): AnsiString;
  var
    hProc: HWND;
    ProcId, cbNeeded: DWord;
    hMod: HMODULE;
    ModuleName: array[0..MAX_PATH - 1] of Char;
  begin
    Result := '';
    GetWindowThreadProcessId(wnd, @ProcId);
    hProc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcId);
    if hProc <> 0 then
      try
        if EnumProcessModules(hProc, @hMod, SizeOf(hMod), cbNeeded) then
          if GetModuleFilenameEx(hProc, hMod, ModuleName, SizeOf(ModuleName)) > 0 then
            Result := string(ModuleName);
      finally
        CloseHandle(hProc);
      end;
  end;

  function FindToolBar: HWND;
  var
    wnd: HWND;
  begin
    Result := 0;
    wnd := FindWindow('Shell_TrayWnd', '');
    if wnd > 0 then
      wnd := FindWindowEx(wnd, 0, 'TrayNotifyWnd', nil);
    if wnd > 0 then
      wnd := FindWindowEx(wnd, 0, 'SysPager', nil);
    if wnd > 0 then
      Result := FindWindowEx(wnd, 0, 'ToolbarWindow32', nil);
  end;

  function FindTrayNotify: HWND;
  var
    wnd: HWND;
  begin
    Result := 0;
    wnd := FindWindow('Shell_TrayWnd', '');
    if wnd > 0 then
      Result := FindWindowEx(wnd, 0, 'TrayNotifyWnd', nil);
  end;

type
  TTrayData2 = record
    cbSize: DWORD;
    Wnd: HWND;
    uID: UINT;
    uFlags: UINT;
    uCallbackMessage: UINT;
    hIcon: HICON;
    szTip: array[0..127] of AnsiChar;
    dwState: DWORD;
    dwStateMask: DWORD;
    szInfo: array[0..255] of AnsiChar;
    uTimeout: UINT;
    szInfoTitle: array[0..63] of AnsiChar;
    dwInfoFlags: DWORD;
  end;

type
  TTrayData = record
    wnd: HWND;
    uID: UINT;
    uCallbackMessage: UINT;
    Reserved: array[0..1] of DWORD;
    hIco: HICON;
  end;
var
  pRem, pLoc: PTBButtonInfo;
  NumBytes, ProcId: Cardinal;
  count, loop: Integer;
  hProc, hToolBar, hTrayNotify: HWND;
  IconData: TTrayData; //TNotifyIconData;
  r, r2: TRect;
begin
  Result := False;
  hToolBar := FindToolBar;
  hTrayNotify := FindTrayNotify;
  if hToolBar > 0 then
  begin
    GetWindowThreadProcessId(hToolBar, @ProcId);
    hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
      PROCESS_VM_WRITE, False, ProcId);
    if hProc = 0 then
      MessageDlg(Format('Fehler bei OpenProcess %s',
        [SyserrorMessage(GetLastError)]), mtError, [mbOk], 0)
    else
      try
        pRem := VirtualAllocEx(hProc, nil, SizeOf(TBButtonInfo), MEM_COMMIT, PAGE_READWRITE);
        if Assigned(pRem) then
          try
            pLoc := VirtualAlloc(nil, SizeOf(TBButtonInfo), MEM_COMMIT, PAGE_READWRITE);
            if Assigned(pLoc) then
              try
                count := SendMessage(hToolBar, TB_BUTTONCOUNT, 0, 0);
                if count = 0 then
                  MessageDlg('Fehler bei TB_BUTTONCOUNT', mtError, [mbOk], 0);
                pLoc^.cbSize := SizeOf(TBButtonInfo);
                pLoc^.dwMask := TBIF_LPARAM or TBIF_STATE;
                if WriteProcessMemory(hProc, pRem, pLoc, SizeOf(TBButtonInfo), NumBytes) then
                  for loop := 0 to count do
                    if SendMessage(hToolBar, TB_GETBUTTONINFO, loop, Cardinal(pRem)) <> 0 then
                      if ReadProcessMemory(hProc, pRem, pLoc, SizeOf(TBButtonInfo), NumBytes) then
                        if ReadProcessMemory(hProc, Pointer(pLoc^.lParam),
                          @IconData.Wnd, SizeOf(TTrayData), NumBytes) then
                          if IsWindow(IconData.Wnd) then
                          begin
                            if SameText(ProcPath, GetProcPath(IconData.Wnd)) then
                            begin
                              if HideIcon then
                              begin
                                if pLoc^.fsState and TBSTATE_HIDDEN = 0 then //sichtbar
                                begin
                                  pLoc^.fsState := pLoc^.fsState or TBSTATE_HIDDEN;
                                  if WriteProcessMemory(hProc, pRem, pLoc, SizeOf(TBButtonInfo), NumBytes) then
                                    if SendMessage(hToolBar, TB_SETBUTTONINFO, loop, Cardinal(pRem)) <> 0 then
                                      Result := True;
                                end;
                              end
                              else
                              begin
                                if pLoc^.fsState and TBSTATE_HIDDEN > 0 then //unsichtbar
                                begin
                                  pLoc^.fsState := pLoc^.fsState and not TBSTATE_HIDDEN;
                                  if WriteProcessMemory(hProc, pRem, pLoc, SizeOf(TBButtonInfo), NumBytes) then
                                    if SendMessage(hToolBar, TB_SETBUTTONINFO, loop, Cardinal(pRem)) <> 0 then
                                      Result := True;
                                end;
                              end;
                              Break;
                            end;
                          end;
              finally
                VirtualFree(pLoc, 0, MEM_RELEASE);
              end;
          finally
            VirtualFreeEx(hProc, pRem, 0, MEM_RELEASE);
          end
        else
          MessageDlg(Format('Fehler bei VirtualAllocEx %s',
            [SyserrorMessage(getLastError)]), mtError, [mbOk], 0);
      finally
        CloseHandle(hProc);
      end;
  end
  else
    MessageDlg(Format('Kein gültiges Fenster Handle %d', [hToolBar]), mtError, [mbOk], 0);
end;
Thomas
  Mit Zitat antworten Zitat
ernschd

Registriert seit: 16. Jan 2008
165 Beiträge
 
Delphi XE8 Professional
 
#6

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 4. Dez 2009, 10:30
Muss ich der Funktion den Namen des Prozesses übergeben, den Dateipfad zur Exe, oder was anderes?
Die ersten beiden Varianten habe ich ausprobiert, aber es hat leider nicht funktioniert.
  Mit Zitat antworten Zitat
Madtrax

Registriert seit: 15. Sep 2003
19 Beiträge
 
#7

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 4. Dez 2009, 13:30
Hallo

Ich habe das gleiche Problem die Tage auch gehabt und eine sehr einfache und schöne Lösung gefunden.
Das Icon verschwindet wenn man mit der Maus darüber fährt, richtig ?
Also machen wir uns das zunutze und machen das mit Sourcecode. Gesagt sei dabei, dass die Maus nicht wirklich verschoben wird.
Habe den Code im Internet gefunden. Weiß allerdings auch nicht mehr wo genau. Schau es dir mal an....

Delphi-Quellcode:
Procedure KillTrayIcon;
var
    wnd : cardinal;
    rec : TRect;
    w,h : integer;
    x,y : integer;
begin
    // find a handle of a tray
    wnd := FindWindow('Shell_TrayWnd', nil);
    wnd := FindWindowEx(wnd, 0, 'TrayNotifyWnd', nil);
    wnd := FindWindowEx(wnd, 0, 'SysPager', nil);
    wnd := FindWindowEx(wnd, 0, 'ToolbarWindow32', nil);
    // get client rectangle (needed for width and height of tray)
    windows.GetClientRect(wnd, rec);
    // get size of small icons
    w := GetSystemMetrics(sm_cxsmicon);
    h := GetSystemMetrics(sm_cysmicon);
    // initial y position of mouse - half of height of icon
    y := w shr 1;
    while y < rec.Bottom do begin // while y < height of tray
        x := h shr 1; // initial x position of mouse - half of width of icon
        while x < rec.Right do begin // while x < width of tray
            SendMessage(wnd, wm_mousemove, 0, y shl 16 or x); // simulate moving mouse over an icon
            x := x + w; // add width of icon to x position
        end;
        y := y + h; // add height of icon to y position
    end;
end;
-----------------------------------
Madtrax
  Mit Zitat antworten Zitat
generic

Registriert seit: 24. Mär 2004
Ort: bei Hannover
2.415 Beiträge
 
Delphi XE5 Professional
 
#8

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 4. Dez 2009, 13:41
Wird nicht einfach durch die Maus ein Invalidate bzw. neu zeichnen ausgelöst?
Coding BOTT - Video Tutorials rund um das Programmieren - https://www.youtube.com/@codingbott
  Mit Zitat antworten Zitat
Madtrax

Registriert seit: 15. Sep 2003
19 Beiträge
 
#9

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 4. Dez 2009, 13:49
Gute Frage...

Was auf jeden Fall nicht geht, ist ein Invalidate auf den Tray Bereich, weil der dann komplett ausgehebelt wird (Schwarzer Block auf grauem Grund). Nur ein "Normales" Anzeigen der Tray hilft dir nach dem Invalidate wieder weiter (Tray wird dann wieder korrekt gezeichnet).
-----------------------------------
Madtrax
  Mit Zitat antworten Zitat
ernschd

Registriert seit: 16. Jan 2008
165 Beiträge
 
Delphi XE8 Professional
 
#10

Re: Tray-Icon entfernen nach Beenden des Prozesses

  Alt 7. Dez 2009, 09:00
Mit dem letzten Programmcode funktioniert es wunderbar.

Danke schön.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:32 Uhr.
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