谁有空将这段代码做成标准的DLL,我给500分他(她).如果代码作者在,也给500分.
fontz 2005-11-07 09:00:31 如果你用SPY++查看那个地方,你会发现那里其实是一个Toolbar控件,类名是"ToolbarWindow32"。所以要删除某一个图标,只要删除该图标对应的按钮即可,如何知道某个图标对应哪个按钮呢?OK,每一个图标都有一个Hint值,只要查询该图标的Hint值是否是你要删除的图标的Hint值,如果是,就直接删除那个图标。
技术难点:查询图标的Hint值是通过发送消息TB_GETBUTTONINFO来完成的,这个消息需要一个TBBUTTONINFO结构变量地址,如果直接采用如下方法:
TBBUTTONINFO tbi;
SendMessage(hTrayWnd,WM_GETBUTTONINFO,Index,&tbi);
你的Explorer.exe马上就死(刚开始我的Explorer.exe就死了好几次,还好我用的是Win2000,没事^_^), 因为tbi的地址只在你的进程里边有效,在Explorer.exe进程里边都不知道指向何方。所以解决方法就自然地转到如何让Explorer.exe进程能找到那个地址,唯一的办法就是把变量放到Explorer.exe进程里边,如果你对API比较熟悉,就回想到VirtualAllocEx函数,没错,就是它!!!!!!!!
下面是详细代码,已经测试过了,放心用吧*_^
--------------------------------------------
--------------------------------------------
--------------------------------------------
//删除scktsrvr.exe对应的托盘图标
HideSysTrayIcon("Borland Socket Server");
// HideSysTrayIcon("金山词霸");
// HideSysTrayIcon("天网防火墙");
--------------------------------------------
//参数是图标的Hint值的一部分,而不是程序的名称。比如你想隐藏的那个图标Hint值为
//"Borland Socket Server",金山词霸则可以输入"金山词霸",不能使用"金山词霸|(暂停)"。
void __fastcall TForm1::HideSysTrayIcon(AnsiString ATrayHint)
{
HWND hTrayWnd;
DWORD dwProcessID;
HANDLE hSourceHandle;
HANDLE hTargetHandle;
LPVOID pStart;
LPVOID pBufStart;
int Result;
DWORD dwAllocSize;
const int TextBufSize = 128;
///////////////////
hTrayWnd = FindWindow("Shell_TrayWnd",NULL);
hTrayWnd = FindWindowEx(hTrayWnd,0,"TrayNotifyWnd",NULL);
hTrayWnd = FindWindowEx(hTrayWnd,0,"ToolbarWindow32",NULL);
GetWindowThreadProcessId(hTrayWnd,&dwProcessID);
hSourceHandle = OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessID);
if(hSourceHandle == NULL)
{
Memo1->Lines->Add("Error Open Process. Err=" + SysErrorMessage(GetLastError()));
return;
}
Result = DuplicateHandle(GetCurrentProcess(),hSourceHandle,GetCurrentProcess(),
&hTargetHandle,PROCESS_ALL_ACCESS,false,0);
if(Result == 0)
{
Memo1->Lines->Add("Error Duplicate Process Handle. Err=" + SysErrorMessage(GetLastError()));
return;
}
dwAllocSize = sizeof(TBBUTTONINFO);
pStart = VirtualAllocEx(hTargetHandle,NULL,dwAllocSize,MEM_COMMIT,PAGE_READWRITE);
pBufStart = VirtualAllocEx(hTargetHandle,NULL,TextBufSize,MEM_COMMIT,PAGE_READWRITE);
if(pStart == NULL || pBufStart == NULL)
{
Memo1->Lines->Add("Error Allocate Memory. Err=" + SysErrorMessage(GetLastError()));
return;
}
int ButtonCount;
// TBBUTTONINFO *Button;
// byte *TempData;
TBBUTTONINFO tbi;
byte *TempBuf;
DWORD dwWrite,dwRead;
ButtonCount = SendMessage(hTrayWnd,TB_BUTTONCOUNT,0,0) + 30;//随便多加几个数
Memo1->Lines->Add("Count = " + IntToStr(ButtonCount));
for(int i=0; i < ButtonCount; i++)
{
tbi.cbSize = dwAllocSize;
tbi.dwMask = TBIF_TEXT;
tbi.pszText = (LPTSTR)pBufStart;
WriteProcessMemory(hTargetHandle,pStart,(LPVOID)&tbi,dwAllocSize,&dwWrite);
TempBuf = new byte[TextBufSize];
ZeroMemory(TempBuf,TextBufSize);
WriteProcessMemory(hTargetHandle,pBufStart,(LPVOID)TempBuf,TextBufSize,&dwWrite);
/////////////
SendMessage(hTrayWnd,TB_GETBUTTONINFO,i,(LPARAM)((TBBUTTONINFO*)pStart));// Button);
/////////////
// TempData = new byte[dwAllocSize];
// ReadProcessMemory(hTargetHandle,(LPCVOID)pStart,TempData,dwAllocSize,&dwRead);
// Button = (TBBUTTONINFO*)TempData;
// ....
// delete[] TempData;
ReadProcessMemory(hTargetHandle,(LPCVOID)pBufStart,(LPVOID)TempBuf,TextBufSize,&dwRead);
// Memo1->Lines->Add("ButtonText = " + AnsiString((char*)TempBuf) + " Hint= " + AnsiString(ATrayHint));
//采用模式查找,而不是等值查找,以提高灵活性
if(AnsiString((char*)TempBuf).LowerCase().Pos(ATrayHint.LowerCase()) > 0)
{
// Memo1->Lines->Add("Delete now");
//删除(图标)按钮
Result = SendMessage(hTrayWnd,TB_DELETEBUTTON,i,0);
if(Result)
Memo1->Lines->Add("Succeed in deleting Icon");
else
Memo1->Lines->Add("Fail to deleting Icon");
delete[] TempBuf;
break;
}
delete[] TempBuf;
}
VirtualFreeEx(hTargetHandle,pStart,dwAllocSize,MEM_DECOMMIT);
VirtualFreeEx(hTargetHandle,pBufStart,TextBufSize,MEM_DECOMMIT);
CloseHandle(hTargetHandle);
CloseHandle(hSourceHandle);
}
//---------------------------------------------------------------------------
//原贴:
http://search.csdn.net/Expert/topic/929/929648.xml?temp=.3012354