![]() |
Tray-Icon entfernen nach Beenden des Prozesses
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:
Alles ohne Erfolg.
InvalidateRect(hSysTray, @rRect, True);
SendMessage(hSysTray, WM_PAINT, 0, 0); SendMessage(hTray, WM_MOUSEMOVE, 0, 0); Hat jemand ein funktionierendes Codebeispiel für mich? Danke & Gruß, Ernschd |
Re: Tray-Icon entfernen nach Beenden des Prozesses
Wie entfernst du denn bei Programmende das Icon aus der TNA?
|
Re: Tray-Icon entfernen nach Beenden des Prozesses
@Luckie: lies am besten nochmal den ersten Beitrag :mrgreen: 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.
|
Re: Tray-Icon entfernen nach Beenden des Prozesses
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?
|
Re: Tray-Icon entfernen nach Beenden des Prozesses
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; |
Re: Tray-Icon entfernen nach Beenden des Prozesses
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. |
Re: Tray-Icon entfernen nach Beenden des Prozesses
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; |
Re: Tray-Icon entfernen nach Beenden des Prozesses
Wird nicht einfach durch die Maus ein Invalidate bzw. neu zeichnen ausgelöst?
|
Re: Tray-Icon entfernen nach Beenden des Prozesses
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). |
Re: Tray-Icon entfernen nach Beenden des Prozesses
Mit dem letzten Programmcode funktioniert es wunderbar.
Danke schön. :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz