如何得到系统盒中小图标的位置? (100分)

找见了吗
 
分少可以加
 
同意:leejames
 
不点击,就用MouseMove吧:)
 
我也很想知道,我加200分。
 
to:iamfly<br>期待你的回答
 
我也回答不出。那个VC的程序,现在不知在哪个硬盘里,我是找不到了,唉。。。<br>曾经试过用SOFTICE和W32DASM跟踪一些和SYSTRAY图标有关的程序,跟到应该是和SELECTOBJECT<br>之类的API函数有关,可是还是不知道怎么去做。。。
 
to:iamfly<br>虽然找不到了,但我还是特别感谢你!<br>谢谢!<br>TO :ALL<br>还有朋友知道吗?<br><br>
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/Shell/Functions/Shell_NotifyIcon.asp
 
var<br>&nbsp; &nbsp;nid: TNotifyIconData;<br>begin<br>&nbsp; &nbsp; &nbsp;nid.cbSize:=sizeof(TNotifyIconData);<br>&nbsp; &nbsp; &nbsp;nid.uID:=197;<br>&nbsp; &nbsp; &nbsp;nid.Wnd:=Handle;<br>&nbsp; &nbsp; &nbsp;nid.uFlags:=NIF_INFO;<br>&nbsp; &nbsp; &nbsp;nid.szInfo:='Info';<br>&nbsp; &nbsp; &nbsp;nid.szInfoTitle:='Title';<br>&nbsp; &nbsp; &nbsp;nid.uTimeout:=10;<br>&nbsp; &nbsp; &nbsp;nid.dwInfoFlags:=NIIF_INFO;<br><br>&nbsp; &nbsp; &nbsp;Shell_NotifyIconA(NIM_ADD,@nid);<br>
 
拜托,楼上的两位,你们弄清楚别人的问题再说。现在sxzqcyj不是要在SYSTRAY上加或减<br>个程序的图标,而是想弄清楚别的程序在SYSTRAY加的图标的位置。如果只是要加个图标<br>那么容易的问题,会放那么久还没人答出来?光是SEARCH一下以前的已答问题都答案一大堆<br>了。<br>TO sxzqcyj:我查看一下我的已答问题,找找当初是谁EMAIL给我的,再问问他看看吧:)
 
还没答案呢!
 
谢谢各位的热心帮助!!!!!<br>可我还没有答案呢。<br>
 
继续呀,我在等。[:)]
 
这个问题和我以前如何得到任务栏按钮的矩形一样啊~~~~~~~~~<br>一定有某个没有公开的东西可以做到,不过根据现有的资料无法用简单的方式得到的,可以采取一个笨办法来做到:<br>首先我们可以很轻松找到SysTray的句柄,用FindWindowEx就可以了,这个不用多说,找到之后,你会发现他其实是一个标准的Toolbar,这样就很简单了,我们可以用ToolbarMessage来做既可:<br>首先发送TB_BUTTONCOUNT信息得到Button Count,做一个循环:<br>for i:=0 to Count - 1 do<br>begin<br>&nbsp; 发送TB_GETBUTTON,得到第I个Button的Command ID;<br>&nbsp; 发送TB_GETBUTTONTEXT,得到第I个Button的Caption;<br>&nbsp; 判断Caption,如果是我们指定的Button则<br>&nbsp; begin<br>&nbsp; &nbsp; 发送TB_GETITEMRECT,得到第I个Button的RECT;<br>&nbsp; &nbsp; 退出;<br>&nbsp; end;<br>end;<br><br>需要注意的是,使用上面的消息,所使用的内存空间必须在Shell之内,利用ReadProcessMemoery和WriteProcessMemory既可。<br>具体的代码自己写吧,我给出我取Taskbar Button的Rect的代码供参考:<br>我修改了一下,应该可以使用:<br><br>uses CommCtrl;<br><br>function GetSysTrayWnd: HWND;<br>begin<br>&nbsp; Result := FindWindow('Shell_TrayWnd', nil);<br>&nbsp; Result := FindWindowEx(Result, 0, 'TrayNotifyWnd', nil);<br>&nbsp; Result := FindWindowEx(Result, 0, 'SysPager', nil);<br>&nbsp; Result := FindWindowEx(Result, 0, 'ToolbarWindow32', nil);<br>end;<br><br>function GetTaskBarButtonRect(Title: string): TRect;<br>{<br>&nbsp; 返回指定Title的窗口按钮在任务栏的按钮的矩形区域<br>&nbsp; 例如返回当前程序的任务栏按钮矩形:<br>&nbsp; GetTaskBarButtonRect(Application.Title);<br>}<br>var<br>&nbsp; h: HWND;<br>&nbsp; C, i: integer;<br>&nbsp; Info: _TBBUTTON;<br>&nbsp; Item: tagTCITEM;<br>&nbsp; Buff: PChar;<br>&nbsp; S: array[0..1024] of char;<br>&nbsp; PID: THandle;<br>&nbsp; PRC: THandle;<br>&nbsp; R: Cardinal;<br>begin<br>&nbsp; FillChar(Result, SizeOf(Result), 0);<br>&nbsp; H := GetSysTrayWnd;<br>&nbsp; if H = 0 then Exit;<br>&nbsp; GetWindowThreadProcessId(H, @PID);<br>&nbsp; PRC := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE, False, PID);<br>&nbsp; Buff := VirtualAllocEx(PRC, nil, 4096, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);<br><br>&nbsp; if Format('%d.%d',[Win32MajorVersion,Win32MinorVersion]) &gt;= '5.1' then // Is Windows XP or Higher<br>&nbsp; begin<br>&nbsp; &nbsp; C := SendMessage(H, TB_BUTTONCOUNT, 0, 0);<br>&nbsp; &nbsp; for i := 0 to C - 1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; FillChar(Info, SizeOf(Info), 0);<br>&nbsp; &nbsp; &nbsp; WriteProcessMemory(PRC, Buff, @Info, SizeOf(Info), R);<br><br>&nbsp; &nbsp; &nbsp; SendMessage(H, TB_GETBUTTON, i, integer(Buff));<br>&nbsp; &nbsp; &nbsp; ReadProcessMemory(PRC, Buff, @Info, SizeOf(Info), R);<br><br>&nbsp; &nbsp; &nbsp; SendMessage(H, TB_GETBUTTONTEXT, Info.idCommand, integer(integer(@Buff[0]) + SizeOf(Info)));<br>&nbsp; &nbsp; &nbsp; ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOf(Info)), @S[0], SizeOf(S), R);<br>&nbsp; &nbsp; &nbsp; Form1.Memo1.Lines.Add(StrPas(S));<br>&nbsp; &nbsp; &nbsp; if SameText(StrPas(S), Title) and not Boolean(SendMessage(H, TB_ISBUTTONHIDDEN, Info.idCommand, 0)) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; SendMessage(H, TB_GETRECT, Info.idCommand, integer(integer(@Buff[0]) + SizeOf(Info)));<br>&nbsp; &nbsp; &nbsp; &nbsp; ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOf(Info)), @Result, SizeOf(Result), R);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; Windows.ClientToScreen(H, Result.TopLeft);<br>&nbsp; &nbsp; &nbsp; &nbsp; Windows.ClientToScreen(H, Result.BottomRight);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; Break;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; end<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; C := SendMessage(H, TCM_GETITEMCOUNT, 0, 0);<br>&nbsp; &nbsp; for i := 0 to C - 1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; with Item do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; mask := TCIF_TEXT;<br>&nbsp; &nbsp; &nbsp; &nbsp; dwState := 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; dwStateMask := 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; cchTextMax := 2048;<br>&nbsp; &nbsp; &nbsp; &nbsp; pszText := PChar(integer(Buff) + SizeOf(Item) * 4);<br>&nbsp; &nbsp; &nbsp; &nbsp; iImage := 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; lParam := 0;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; WriteProcessMemory(PRC, Buff, @Item, SizeOf(Item), R);<br>&nbsp; &nbsp; &nbsp; SendMessage(H, TCM_GETITEM, i, Integer(Buff));<br><br>&nbsp; &nbsp; &nbsp; ReadProcessMemory(PRC, Buff, @Item, SizeOf(Item), R);<br>&nbsp; &nbsp; &nbsp; ReadProcessMemory(PRC, PChar(integer(Buff) + SizeOf(Item) * 4), @S[0], SizeOf(S), R);<br><br>&nbsp; &nbsp; &nbsp; if SameText(S, Title) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; SendMessage(H, TCM_GETITEMRECT, i, integer(Buff));<br>&nbsp; &nbsp; &nbsp; &nbsp; ReadProcessMemory(PRC, Buff, @Result, SizeOf(Result), R);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; Windows.ClientToScreen(H, Result.TopLeft);<br>&nbsp; &nbsp; &nbsp; &nbsp; Windows.ClientToScreen(H, Result.BottomRight);<br>&nbsp; &nbsp; &nbsp; &nbsp; Break;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; VirtualFreeEx(PRC, Buff, 0, MEM_RELEASE);<br>&nbsp; CloseHandle(PRC);<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; DrawAnimatedRects(Handle, IDANI_CAPTION, BoundsRect, GetTaskBarButtonRect('音量'));<br>end;<br><br>
 
上面的代码在Win2003 CHS下测试通过
 
谢谢Kingron。看了你的回复,<br>我现在能够在2000下显示隐藏托盘图标了。通过sendmessage TB_HIDEBUTTON。<br>现在有两个问题<br>1、98下怎么隐藏托盘图标,sendmessage什么,好像是通过SETITEM。<br>2、但是每次隐藏一个按钮图标,任务栏托盘那图标没了,但图标原来的地方空出来了,隐藏多个就空出多个。必须要应用程序窗口切换一下,任务栏才会刷新。显示图标时也一样。<br>我想应该可以通过给任务栏发消息让他刷新,但是不知怎么实现,也没找到资料。
 
1:98下,请自己调试<br>2:自己用<br>var<br>&nbsp; AID: _NOTIFYICONDATA;<br>begin<br>&nbsp; AID.cbSize := SizeOf(AID);<br>&nbsp; AID.Wnd := Handle;<br>&nbsp; AID.uID := 0;<br>&nbsp; AID.uFlags := NIF_ICON;<br>&nbsp; AID.uCallbackMessage := 0;<br>&nbsp; AID.hIcon := Icon.Handle;<br>&nbsp; AID.szTip := '';<br>&nbsp; Shell_NotifyIcon(NIM_ADD, @AID);<br>&nbsp; Shell_NotifyIcon(NIM_DELETE, @AID);<br>end;<br>即可。
 
好的,谢谢
 
顶部