delphi 如何通过托盘图标,获取进程PID

bf505052826 2012-06-16 08:46:24
下面给出获取所有托盘图标的hint,但是要怎么样才可以通过这个获取到对应的进程PID呢,高手请帮忙 ,小弟感激不尽!
function TrayHWnd: HWND;
var
h,hTmp: HWND;
begin
h := FindWindow('Shell_TrayWnd', nil);
h := FindWindowEx(h, 0, 'TrayNotifyWnd', nil);
hTmp := FindWindowEx(h, 0, 'SysPager', nil);
if hTmp <> 0 then h := hTmp;
hTmp := FindWindowEx(h, 0, 'ToolbarWindow32', nil);
if hTmp <> 0 then h := hTmp;
Result := h;
end;
{提取列表}
procedure TForm1.Button1Click(Sender: TObject);
var
h: HWND;
count,size,num: Cardinal;
pid, ph: Cardinal;
p: Pointer;
icoBtn: TTBButton;
buf: array[0..255] of WideChar;
i: Integer;
item: TListItem;
begin
h := TrayHWnd;
count := SendMessage(h, TB_BUTTONCOUNT, 0, 0);
size := SizeOf(TTBButton);

GetWindowThreadProcessId(h, pid);
ph := OpenProcess(PROCESS_VM_READ, False, pid);

for i := 0 to count - 1 do
begin
SendMessage(h, TB_GETBUTTON, i, DWORD(p));
ReadProcessMemory(ph, p, @icoBtn, size, num);
ReadProcessMemory(ph, Pointer(icoBtn.iString), @buf, Length(buf)*SizeOf(buf[0]), num);
item := ListView1.Items.Add;
item.Caption := buf;
end;
CloseHandle(ph);

Button2.Enabled := True;
Button3.Enabled := True;
end;


...全文
227 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
无条件为你 2012-06-18
  • 打赏
  • 举报
回复
只要有句柄就可以获取进程唯一的PID了。但反过来不行,因为一个PID可能对应多个窗口,多个句柄。
s11ss 2012-06-17
  • 打赏
  • 举报
回复
托盘区域这个TTBButton结构的dwData实际上是指向用于接收对应图标的通知消息的窗口句柄(即NOTIFYICONDATA结构的hWnd)的指针,根据此句柄就可以得到PID了!
还有个小问题,就是应当事先分配内存p。以下红色部分是新增加的内容。
procedure TForm1.Button1Click(Sender: TObject);
var
h: HWND;
count,size,num: Cardinal;
pid, ph: Cardinal;
p: Pointer;
icoBtn: TTBButton;
buf: array[0..255] of WideChar;
i: Integer;
item: TListItem;
dwData: DWORD;
begin
h := TrayHWnd;
count := SendMessage(h, TB_BUTTONCOUNT, 0, 0);
size := SizeOf(TTBButton);

GetWindowThreadProcessId(h, pid);
ph := OpenProcess(PROCESS_VM_READ {or PROCESS_VM_WRITE} or PROCESS_VM_OPERATION, False, pid);
p := VirtualAllocEx(ph, nil, size, MEM_COMMIT, PAGE_READWRITE);

for i := 0 to count - 1 do
begin
SendMessage(h, TB_GETBUTTON, i, DWORD(p));
ReadProcessMemory(ph, p, @icoBtn, size, num);
ReadProcessMemory(ph, Pointer(icoBtn.iString), @buf, Length(buf)*SizeOf(buf[0]), num);
ReadProcessMemory(ph, Pointer(icoBtn.dwData), @dwData, SizeOf(dwData), num);
GetWindowThreadProcessId(dwData, pid);

item := ListView1.Items.Add;
item.Caption := buf;
item.SubItems.Add(IntToStr(pid))
end;
VirtualFreeEx(ph, nil, 0, MEM_RELEASE);
CloseHandle(ph);

Button2.Enabled := True;
Button3.Enabled := True;
end;

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧