delphi 隐藏指定程序的托盘图标

来源:互联网 发布:js手册中文版 编辑:程序博客网 时间:2024/05/22 02:04

业务上有需要内嵌一个外部程序,然后,最好把这个外部的程序在桌面上的表现都通通隐藏起来;用户操作起来就比较整洁,心无旁骛...

参考网上别人的代码,整理了一下,此过程经在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;

0 0
原创粉丝点击