delphi 隐藏指定程序的托盘图标
2017-01-10 15:23
751 查看
业务上有需要内嵌一个外部程序,然后,最好把这个外部的程序在桌面上的表现都通通隐藏起来;用户操作起来就比较整洁,心无旁骛...
参考网上别人的代码,整理了一下,此过程经在delphi XE2上调试通过,一步到位,分享出来:
// 删除指定进程的托盘图标 图标提示包含文字 Astr
// 只是删托盘图标 进程不受影响
{ uses CommCtrl }
procedure DeleltIcon(AStr: String);
var
TargetHwnd: HWND;
TBHWND: HWND;
dwProcessID: Dword;
i, count: integer;
PID, PRC: THandle;
Buff: pchar;
Info: _TBBUTTON;
R: NativeUInt;
s: array [0 .. 1024] of char;
function GetSysTrayWnd: HWND; // 得到系统托盘的句柄
begin
Result := FindWindow('Shell_TrayWnd', nil);
Result := findwindowex(Result, 0, 'TrayNotifyWnd', nil);
Result := findwindowex(Result, 0, 'SysPager', nil);
Result := findwindowex(Result, 0, 'ToolbarWindow32', nil);
end;
begin
TBHWND := GetSysTrayWnd; // 得到托盘的窗口ID
if TBHWND = 0 then
begin
//showmessage('得到托盘的窗口ID失败');
Exit;
end;
GetWindowThreadProcessID(TBHWND, @PID); // 通过托盘窗口ID到得到托盘进程ID
PRC := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
PROCESS_VM_WRITE, False, PID); // 得到托盘进程的句柄
if PRC = 0 then
begin
//showmessage('得到进程的句柄失败');
Exit;
end;
Buff := VirtualAllocEx(PRC, nil, 4096, MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE);
// 托盘中button的个数,不一定是图标的个数,有些button是隐藏的。
count := SendMessage(TBHWND, TB_BUTTONCOUNT, 0, 0);
for i := 0 to count - 1 do
begin
FillChar(Info, SizeOF(Info), 0);
WriteProcessMemory(PRC, Buff, @Info, SizeOF(Info), R);
// 消息使用的内存空间必须在Shell之内,所以利用ReadProcessMemoery和WriteProcessMemory。
SendMessage(TBHWND, TB_GETBUTTON, i, integer(Buff));
ReadProcessMemory(PRC, Buff, @Info, SizeOF(Info), R);
SendMessage(TBHWND, TB_GETBUTTONTEXT, Info.idCommand,
integer(integer(@Buff[0]) + SizeOF(Info)));
ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOF(Info)), @s[0],
SizeOF(s), R);
// 如果button的TEXT中包含AStr
// showmessage(StrPas(S));
//Form1.Memo_DeleteIcon.Lines.Add(inttostr(i) + ' ' + StrPas(s));
if pos(AStr, StrPas(s)) > 0 then
begin
SendMessage(TBHWND, TB_DELETEBUTTON, i, 0); // 删除
Break;
end;
// ReadProcessMemory(PRC, Pointer(Info.dwData), @TargetHwnd, 4, R);
// GetWindowThreadProcessID(TargetHwnd, @dwProcessID);
// if dwProcessID = TargetProcessID then
// begin
// SendMessage(TBHWND, TB_DELETEBUTTON, i, 0);
// Break;
// end;
end;
VirtualFreeEx(PRC, Buff, 0, MEM_RELEASE);
CloseHandle(PRC);
end;
参考网上别人的代码,整理了一下,此过程经在delphi XE2上调试通过,一步到位,分享出来:
// 删除指定进程的托盘图标 图标提示包含文字 Astr
// 只是删托盘图标 进程不受影响
{ uses CommCtrl }
procedure DeleltIcon(AStr: String);
var
TargetHwnd: HWND;
TBHWND: HWND;
dwProcessID: Dword;
i, count: integer;
PID, PRC: THandle;
Buff: pchar;
Info: _TBBUTTON;
R: NativeUInt;
s: array [0 .. 1024] of char;
function GetSysTrayWnd: HWND; // 得到系统托盘的句柄
begin
Result := FindWindow('Shell_TrayWnd', nil);
Result := findwindowex(Result, 0, 'TrayNotifyWnd', nil);
Result := findwindowex(Result, 0, 'SysPager', nil);
Result := findwindowex(Result, 0, 'ToolbarWindow32', nil);
end;
begin
TBHWND := GetSysTrayWnd; // 得到托盘的窗口ID
if TBHWND = 0 then
begin
//showmessage('得到托盘的窗口ID失败');
Exit;
end;
GetWindowThreadProcessID(TBHWND, @PID); // 通过托盘窗口ID到得到托盘进程ID
PRC := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or
PROCESS_VM_WRITE, False, PID); // 得到托盘进程的句柄
if PRC = 0 then
begin
//showmessage('得到进程的句柄失败');
Exit;
end;
Buff := VirtualAllocEx(PRC, nil, 4096, MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE);
// 托盘中button的个数,不一定是图标的个数,有些button是隐藏的。
count := SendMessage(TBHWND, TB_BUTTONCOUNT, 0, 0);
for i := 0 to count - 1 do
begin
FillChar(Info, SizeOF(Info), 0);
WriteProcessMemory(PRC, Buff, @Info, SizeOF(Info), R);
// 消息使用的内存空间必须在Shell之内,所以利用ReadProcessMemoery和WriteProcessMemory。
SendMessage(TBHWND, TB_GETBUTTON, i, integer(Buff));
ReadProcessMemory(PRC, Buff, @Info, SizeOF(Info), R);
SendMessage(TBHWND, TB_GETBUTTONTEXT, Info.idCommand,
integer(integer(@Buff[0]) + SizeOF(Info)));
ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOF(Info)), @s[0],
SizeOF(s), R);
// 如果button的TEXT中包含AStr
// showmessage(StrPas(S));
//Form1.Memo_DeleteIcon.Lines.Add(inttostr(i) + ' ' + StrPas(s));
if pos(AStr, StrPas(s)) > 0 then
begin
SendMessage(TBHWND, TB_DELETEBUTTON, i, 0); // 删除
Break;
end;
// ReadProcessMemory(PRC, Pointer(Info.dwData), @TargetHwnd, 4, R);
// GetWindowThreadProcessID(TargetHwnd, @dwProcessID);
// if dwProcessID = TargetProcessID then
// begin
// SendMessage(TBHWND, TB_DELETEBUTTON, i, 0);
// Break;
// end;
end;
VirtualFreeEx(PRC, Buff, 0, MEM_RELEASE);
CloseHandle(PRC);
end;
相关文章推荐
- 隐藏指定程序托盘图标的方法
- 隐藏指定程序托盘图标的方法
- VC++中实现程序启动后隐藏窗口,最小化到托盘图标。
- VC++中实现程序启动后隐藏窗口,最小化到托盘图标。
- BCB如何隐藏任务栏上对应的程序图标按钮,不是托盘上的
- 浅谈c#实现隐藏任务栏图标的Windows托盘程序
- MFC 为程序制作一个系统托盘图标、显示隐藏任务栏图标
- 浅谈c#实现隐藏任务栏图标的Windows托盘程序
- Delphi 在任务栏隐藏程序图标
- Delphi 在任务栏隐藏程序图标
- 32位程序在64位系统下隐藏托盘图标
- 如何设置delphi程序托盘图标
- Delphi刷新托盘,去掉非正常退出的程序的托盘图标
- Delphi刷新托盘,去掉非正常退出的程序的托盘图标
- 浅谈c#实现隐藏任务栏图标的Windows托盘程序
- delphi程序启动时不让其显示图标,也不在托盘中显示。
- Windows系统托盘图标程序之Java实现
- 在Delphi中隐藏程序进程的方法[3]--异常死亡进程的自动复活法
- Delphi实现系统托盘图标
- delphi编写系统托盘程序