delphi 如何通过托盘图标,获取进程PID下面给出获取所有托盘图标的hint,但是要怎么样才可以通过这个获取到
delphi 如何通过托盘图标,获取进程PID
下面给出获取所有托盘图标的hint,但是要怎么样才可以通过这个获取到对应的进程PID呢,高手请帮忙 ,小弟感激不尽!
Delphi(Pascal) codefunction 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;
[解决办法]托盘区域这个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;