获取系统托盘区图标坐标

/// 获取系统托盘某个图标的坐标区域,如果要隐藏某个图标例如音量的图标,也很方便,改改就可以了
function GetSysTrayIconRect(Text: string): TRect;
{
   返回系统托盘中指定文字的图标的矩形区域。
   例如返回音量控制图标的矩形区域:
   GetSysTrayIconRect(‘音量’);
}
begin
   result := GetToolBarButtonRect(GetSysTrayWnd, Text);
end;

function GetSysTrayWnd: HWND;
{
   返回系统托盘的句柄,适合于WinXP以上版本
}
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;

function GetToolBarButtonRect(hWnd: HWND; Title: string): TRect;
{
   返回指定工具栏对应的按钮指定文本的矩形区域
   hWnd:工具栏句柄,Title:需要返回矩形区域的按钮文字
   返回值:指定按钮的边界矩形,屏幕坐标
}
var
   C, i: integer;
   Inf _TBBUTTON;
   Item: tagTCITEM;
   Buff: PChar;
   S: array[0..1024] of char;
   PID: THandle;
   PRC: THandle;
   R: Cardinal;
begin
   FillChar(result, SizeOf(result), 0);
   if hWnd = 0 then Exit;
   GetWindowThreadProcessId(hWnd, @PID);
   PRC := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, PID);
   Buff := VirtualAllocEx(PRC, nil, 4096, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);

   if Format(‘%d.%d’, [Win32MajorVersion, Win32MinorVersion]) >= ’5.1′ then {// Is Windows XP or Higher}
   begin
     C := SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0);
     for i := 0 to C – 1 do
     begin
       FillChar(Info, SizeOf(Info), 0);
       WriteProcessMemory(PRC, Buff, @Info, SizeOf(Info), R);

       SendMessage(hWnd, TB_GETBUTTON, i, integer(Buff));
       ReadProcessMemory(PRC, Buff, @Info, SizeOf(Info), R);

       SendMessage(hWnd, TB_GETBUTTONTEXT, Info.idCommand, integer(integer(@Buff[0]) + SizeOf(Info)));
       ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOf(Info)), @S[0], SizeOf(S), R);
       if SameText(StrPas(S), Title) and not Boolean(SendMessage(hWnd, TB_ISBUTTONHIDDEN, Info.idCommand, 0)) then
       begin
         SendMessage(hWnd, TB_GETRECT, Info.idCommand, integer(integer(@Buff[0]) + SizeOf(Info)));
         ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOf(Info)), @result, SizeOf(result), R);

         Windows.ClientToScreen(hWnd, result.TopLeft);
         Windows.ClientToScreen(hWnd, result.BottomRight);

         Break;
       end;
     end;
   end
   else
   begin
     C := SendMessage(hWnd, TCM_GETITEMCOUNT, 0, 0);
     for i := 0 to C – 1 do
     begin
       with Item do
       begin
         mask := TCIF_TEXT;
         dwState := 0;
         dwStateMask := 0;
         cchTextMax := 2048;
         pszText := PChar(integer(Buff) + SizeOf(Item) * 4);
         iImage := 0;
         lParam := 0;
       end;
       WriteProcessMemory(PRC, Buff, @Item, SizeOf(Item), R);
       SendMessage(hWnd, TCM_GETITEM, i, Integer(Buff));

       ReadProcessMemory(PRC, Buff, @Item, SizeOf(Item), R);
       ReadProcessMemory(PRC, PChar(integer(Buff) + SizeOf(Item) * 4), @S[0], SizeOf(S), R);

       if SameText(S, Title) then
       begin
         SendMessage(hWnd, TCM_GETITEMRECT, i, integer(Buff));
         ReadProcessMemory(PRC, Buff, @result, SizeOf(result), R);

         Windows.ClientToScreen(hWnd, result.TopLeft);
         Windows.ClientToScreen(hWnd, result.BottomRight);
         Break;
       end;
     end;
   end;

   VirtualFreeEx(PRC, Buff, 0, MEM_RELEASE);
   CloseHandle(PRC);
end;


TCM_ADJUSTRECT        TB_ADDBITMAP             TB_SETTOOLTIPS
TCM_DELETEALLITEM     TB_ADDBUTTONS            TB_GETMAXSIZE
TCM_DELETEITEM        TB_ADDSTRING             TB_GETOBJECT
TCM_DESELECTALL       TB_AUTOSIZE              TB_GETPADDING
TCM_GETCURFOCUS       TB_BUTTONCOUNT           TB_GETRECT
TCM_GETCURSEL         TB_BUTTONSTRUCTSIZE      TB_GETROWS
TCM_GETEXTENDEDSTYLE TB_CHANGEBITMAP          TB_GETSTATE
TCM_GETIMAGELIST      TB_CHECKBUTTON           TB_GETSTYLE
TCM_GETITEM           TB_COMMANDTOINDEX        TB_GETTEXTROWS
TCM_GETITEMCOUNT      TB_CUSTOMIZE             TB_GETTOOLTIPS
TCM_GETITEMRECT       TB_DELETEBUTTON          TB_HIDEBUTTON
TCM_GETROWCOUNT       TB_ENABLEBUTTON          TB_HITTEST
TCM_GETTOOLTIPS       TB_GETANCHORHIGHLIGHT    TB_INDETERMINATE
TCM_HIGHLISHTITEM     TB_GETBITMAP             TB_INSERTBUTTON
TCM_HITTEST           TB_GETBITMAPFLAGS        TB_INSERTMARKHITTEST
TCM_INSERTITEM        TB_GETBUTTON             TB_ISBUTTONCHECKED
TCM_REMOVEIMAGE       TB_GETBUTTONINFO         TB_ISBUTTONENABLED
TCM_SETCURFOCUS       TB_GETBUTTONSIZE         TB_ISBUTTONHIDDEN
TCM_SETCURSEL         TB_GETBUTTONTEXT         TB_ISBUTTONHIGHLIGHTED
TCM_SETEXTENDEDSTYLE TB_GETDISABLEDIMAGELIST TB_ISBUTTONINDETERMINATE
TCM_SETIMAGELIST      TB_GETEXTENDEDSTYLE      TB_ISBUTTONPRESSED
TCM_SETITEM           TB_GETHOTIMAGELIST       TB_LOADIMAGES
TCM_SETITEMEXTRA      TB_GETHOTITEM            TB_MAPACCELERATOR
TCM_SETITEMSIZE       TB_GETIMAGELIST          TB_MARKBUTTON
TCM_SETMINTABWIDTH    TB_GETINSERTMARK         TB_MOVEBUTTON
TCM_SETPADDING        TB_GETINSERTMARKCOLOR    TB_PRESSBUTTON
TCM_SETTOOLTIPS       TB_GETITEMRECT           TB_REPLACEBITMAP
TB_SAVERESTORE        TB_SETANCHORHIGHLIGHT    TB_SETBITMAPSIZE
TB_SETBUTTONINFO      TB_SETBUTTONSIZE         TB_SETBUTTONWIDTH
TB_SETCMDID           TB_SETDISABLEDIMAGELIST TB_SETEXTENDEDSTYLE
TB_SETHOTIMAGELIST    TB_SETHOTITEM            TB_SETIMAGELIST
TB_SETINDENT          TB_SETINSERTMARK         TB_SETINSERTMARKCOLOR
TB_SETMAXTEXTROWS     TB_SETPADDING            TB_SETPARENT
TB_SETROWS            TB_SETSTATE              TB_SETSTYLE

uses CommCtrl;