Registriert seit: 27. Jun 2004
450 Beiträge
|
Re: Taskleiste aktualisieren
9. Mär 2007, 12:34
so ich hab dazu eine lösung im netz gefunden,
die ist allerdings nicht ganz unproblematisch.
Delphi-Quellcode:
uses
CommCtrl, ShellAPI;
...
function TMainForm.RefreshTray: Boolean;
function GetTrayHandle: THandle;
var ShellTrayHandle: THandle;
begin
ShellTrayHandle := FindWindow('Shell_TrayWnd', nil);
if ShellTrayHandle <> 0 then
Result := FindWindowEx(ShellTrayHandle, 0, 'TrayNotifyWnd', nil)
else
Result := 0;
end;
function FindToolbar(Window: THandle; var ToolbarHandle: THandle): BOOL; stdcall;
var Buf: array[Byte] of Char;
begin
GetClassName(Window, Buf, SizeOf(Buf));
// Set result to false when we have found a toolbar
Result := StrIComp(Buf, TOOLBARCLASSNAME) <> 0;
if not Result then
ToolbarHandle := Window;
end;
function GetToolbarHandle: THandle;
var TrayHandle: THandle;
begin
Result := 0;
TrayHandle := GetTrayHandle;
if TrayHandle = 0 then
Exit;
EnumChildWindows(TrayHandle, @FindToolbar, Longint(@Result));
end;
type
TExtraData = packed record
Wnd: THandle;
uID: UINT;
end;
var
ToolbarHandle: THandle;
ProcessID: DWORD;
Process: THandle;
ButtonCount: Integer;
Data: Pointer;
Index: Integer;
BytesRead: DWORD;
Button: TTBButton;
ExtraData: TExtraData;
IconData: TNotifyIconData;
begin
Result := False;
// The trayicons are actually buttons on a toolbar
ToolbarHandle := GetToolbarHandle;
if ToolbarHandle = 0 then
Exit;
ButtonCount := SendMessage(ToolbarHandle, TB_BUTTONCOUNT, 0, 0);
if ButtonCount < 1 then
Exit;
FillChar(IconData, SizeOf(IconData), #0);
IconData.cbSize:= SizeOf(IconData);
// We want to get data from another process - it's not possible
// to just send messages like TB_GETBUTTON with a locally
// allocated buffer for return data. Pointer to locally allocated
// data has no usefull meaning in a context of another
// process (since Win95) - so we need
// to allocate some memory inside Tray process.
// Use @ProcessId for C5/D5 compatibility
if GetWindowThreadProcessId(ToolbarHandle, @ProcessID) = 0 then
Exit;
Process := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessID);
if Process = 0 then
Exit;
try
// Allocate needed memory in the context of the tray process. We reuse
// Data to read multiple parts so we set it to the biggest chunk we need
// (TTBButton)
Data := VirtualAllocEx(Process, nil, SizeOf(TTBButton), MEM_COMMIT, PAGE_READWRITE);
if Data = nil then
Exit;
try
for Index := ButtonCount - 1 downto 0 do
begin
// First we have to determine if the button with index Index is our
// button.
SendMessage(ToolbarHandle, TB_GETBUTTON, Index, Longint(Data));
// Read the data from the tray process into the current process.
Result := ReadProcessMemory(Process, Data, @Button, SizeOf(Button), BytesRead) and (BytesRead = SizeOf(Button));
if not Result then
Continue;
// Read the extra data, Button.dwData points to its location
Result := ReadProcessMemory(Process, Pointer(Button.dwData),
@ExtraData, SizeOf(ExtraData), BytesRead) and (BytesRead = SizeOf(ExtraData));
if not Result then
Continue;
if not IsWindow(ExtraData.Wnd) then
begin
IconData.Wnd:= ExtraData.Wnd;
IconData.uID:= ExtraData.uID;
Shell_NotifyIcon(NIM_DELETE, @IconData);
end;
end;
finally
VirtualFreeEx(Process, Data, 0, MEM_RELEASE);
end;
finally
CloseHandle(Process);
end;
end;
|