刷新托盘区域

gctren 2009-01-12 07:59:26
我用杀进程的方式,关闭掉一个程序后,其托盘图标还在托盘区,没有给消失,需要鼠标移动上去后,才会消失,如何用程序来实现刷新托盘区域呢? 也可以在我程序杀掉进程前,删除/隐藏该托盘图标。

我找到了DEPHI的:
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;

procedure FreeIcon;
var
ShellHandle: THandle;
PID: THandle;
PRC: THandle;
Buff: pchar;
i,Count: integer;
Info: _TBBUTTON;
R: Cardinal;
S: array[0..1024] of char;
begin
ShellHandle := GetSysTrayWnd; //得到托盘处句炳
GetWindowThreadProcessId(ShellHandle, @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);
Count := SendMessage(ShellHandle, TB_BUTTONCOUNT, 0, 0);
for i := 0 to Count - 1 do
begin
FillChar(Info, SizeOf(Info), 0);
WriteProcessMemory(PRC, Buff, @Info, SizeOf(Info), R);
SendMessage(ShellHandle, TB_GETBUTTON, i,integer(Buff));
ReadProcessMemory(PRC, Buff, @Info, SizeOf(Info), R);
SendMessage(ShellHandle, TB_GETBUTTONTEXT, Info.idCommand, integer(integer(@Buff[0]) + SizeOf(Info)));
ReadProcessMemory(PRC, Pointer(integer(@Buff[0]) + SizeOf(Info)), @S[0], SizeOf(S), R);
SendMessage(ShellHandle,TB_HIDEBUTTON,i,1);
SendMessage(ShellHandle, TB_AUTOSIZE, 0, 0)
end;
VirtualFreeEx(PRC, Buff, 0, MEM_RELEASE);
CloseHandle(PRC);
end;

但其实的FILLCHAR 在C# 中没有,并且这段代码不全。 不知道如何修改,

那位大哥,高人帮忙解决解决, 谢谢。 在线。
...全文
544 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
风龙-3 2009-01-13
  • 打赏
  • 举报
回复
程序退出后,用另外的进程获取托盘区中对应的各TBBUTTON信息对应的进程为空,则删除该图标
gctren 2009-01-13
  • 打赏
  • 举报
回复
再顶下。
gctren 2009-01-13
  • 打赏
  • 举报
回复
顶下。
gctren 2009-01-13
  • 打赏
  • 举报
回复
但首先要能得到 TBBUTTON信息才行。 现在的问题是我得不到这个信息,不知道那边写的有问题。
gctren 2009-01-12
  • 打赏
  • 举报
回复
好象还没有读进 TBBUTTON中去。 哎。不知道,还有那边没写好。
ICanUseThisID 2009-01-12
  • 打赏
  • 举报
回复
to 12F:

//试试这个?
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
out TBBUTTON lpBuffer,
uint nSize,
out uint lpNumberOfBytesRead
);

public struct TBBUTTON
{
public int iBitmap;
public int idCommand;
public byte fsState;
public byte fsStyle;
public byte bReserved1;
public byte bReserved2;
public int dwData;
public int iString;
}
gctren 2009-01-12
  • 打赏
  • 举报
回复
没能实现, 你在杀掉QQ进程的时候,用这个方法,可以看到托盘区域QQ图标消失吗? 我没有实现
GTX280 2009-01-12
  • 打赏
  • 举报
回复
p.CloseMainWindow();
p.Close();
我试过可以消除托盘图标
gctren 2009-01-12
  • 打赏
  • 举报
回复
Public Declare Function ReadProcessMemory Lib "kernel32.dll" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

Public Type TBBUTTON
iBitmap As Long
idCommand As Long
fsState As Byte
fsStyle As Byte
bReserved1 As Byte
bReserved2 As Byte
dwData As Long
iString As Long
End Type

Dim udtTb As TBBUTTON
lret = ReadProcessMemory(hProcess, ByVal lAddress, ByVal VarPtr(udtTb), ByVal Len(udtTb), ByVal 0&)

这段代码如何转成C# , 这个转成的话, 我的这个问题,差不多可以解决了。
gctren 2009-01-12
  • 打赏
  • 举报
回复
这个是模拟了鼠标在托盘区移动,
但和我的想法与要求还是有点区别, 我是要在让客户没感知的情况下刷新掉托盘区。而是模拟一个鼠标在那移动。

不过还是很感觉 wangpint_li 呵呵 。
wangping_li 2009-01-12
  • 打赏
  • 举报
回复
这东西不好搞啊,我搞到一个VC版的,希望能对你有帮助:

http://www.diybl.com/course/4_webprogram/asp.net/netjs/2007116/84757.html
gctren 2009-01-12
  • 打赏
  • 举报
回复
如果能够得到这个图标的话,也不用这么麻烦了。 呵呵 。

我是这样情况,如: 在我的程序中杀死QQ程序,同时要将QQ的托盘图标给删除/隐藏掉。
tonyli2019 2009-01-12
  • 打赏
  • 举报
回复
同意7楼的,
用this.notifyIcon1.Dispose()是正道
GTX280 2009-01-12
  • 打赏
  • 举报
回复
this.notifyIcon1.Dispose();//直接释放托盘图标资源,这个比较彻底
GTX280 2009-01-12
  • 打赏
  • 举报
回复
this.notifyIcon1.Visible = false;//隐藏托盘图标,在杀进程前调用
消失的尘芥 2009-01-12
  • 打赏
  • 举报
回复
楼主的代码我看了一下,我还是没明白!up了!
友情提醒:你的思路确定是对吗?
gctren 2009-01-12
  • 打赏
  • 举报
回复
哎, 不要只是MARK啊。 要顶。 呵呵
black__art 2009-01-12
  • 打赏
  • 举报
回复
接分
饺子87 2009-01-12
  • 打赏
  • 举报
回复
MARK
再见品月 2009-01-12
  • 打赏
  • 举报
回复
有点意思。。。Mark。。偶也不会。。等待高人。

110,526

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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