一个系统托盘的问题
我用TrayIcon来在系统托盘上加了一个图标,可是当我结束Explorer进程后再重新新建Explorer进程后,图标不见了!怎么解决?我想要BCB的TrayIcon的相关解决代码,请不要给我VC的或者Windows API的代码。谢谢。 问题点数:0、回复次数:19Top
1 楼zywx(Waterun)回复于 2003-06-04 00:04:59 得分 0
TrayIcon的源代码在example里面有,example\controls\source\bcbsmp.bpkTop
2 楼aniven(Compile Failed)回复于 2003-06-04 00:17:30 得分 0
这很正常啊,大多数程序的托盘图标,在EXPLORER进程中断又重建后都会没有.没有必要把时间花在这上面,毕竟谁也不会随便中断EXPLORER玩Top
3 楼warton(创业群13734424 http://www.anywhy.cn)回复于 2003-06-04 00:18:58 得分 0
CBuilder6\Examples\Controls\Traydemo
中有示例!!!Top
4 楼Lersh(暑片)回复于 2003-06-04 00:24:16 得分 0
拜托zywx(Waterun),warton(转型中...) 看清我的问题再发言!!!!!Top
5 楼Lersh(暑片)回复于 2003-06-04 00:26:25 得分 0
To aniven(風月無邊),虽然没人会随便中断Explorer进程,但一旦出现了呢,我就碰到过,Explorer进程死掉了,不得已重启Explorer,然后发现我的程序找不到了,虽然进程管理器里有,但我没法操作它了……很郁闷的!Top
6 楼kevincsdn(找不到好的用户名)回复于 2003-06-04 00:45:38 得分 0
对,原来一个版本的FlashFXP就是,有时最小化了,TrayIcon就不见了,无法操作了。只能强行关闭它的进程。Top
7 楼ybluo()回复于 2003-06-04 08:54:53 得分 0
在Explorer进程重启后,在添加托盘图标,
怎样才知道Explorer进程重启呢?用Timer查找好像比较笨,
不知道有没有什么消息?
Top
8 楼flyfeel(图灵)回复于 2003-06-04 09:06:11 得分 0
有意思,关注。。。。Top
9 楼MikeWKL(星星之盾)回复于 2003-06-04 09:51:44 得分 0
GZTop
10 楼yingyys(鹰)回复于 2003-06-04 10:02:29 得分 0
不知道,不过有很多程序都是这样的Top
11 楼hunyahun(露头一铁锹)回复于 2003-06-04 10:53:17 得分 0
教你一个办法,用一个计时器不断查找Explorer.exe,查找用FindWindow("Progman",0),Progman是Explorer.exe的类名。
void __fastcall TForm1:Timer1Timer(TObject *Sender)
{
if(FindWindow("Progman",0))
{
//检查TrayIcon是否存在
...
new TrayIcon;
...
}
}
如果你不想用计时器,你就可以查一查Explorer启动时广播的消息是什么,然后来相应这个消息。Top
12 楼boris(开心大使)回复于 2003-06-04 10:58:57 得分 0
case WM_CREATE:
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
break;
//处理TrayIcon菜单消息
default:
if(message == s_uTaskbarRestart)
AddTrayIcon();
break;
Top
13 楼Lersh(暑片)回复于 2003-06-04 11:10:37 得分 0
To hunyahun(哈哈哈),绝对不考虑用Timer
To boris(开心大使),抄资料前先验证一下,你抄的代码没用的。另外看清我的要求,要TrayIcon的解决方法,AddTrayIcon函数连定义都没有。Top
14 楼Lersh(暑片)回复于 2003-06-04 12:47:52 得分 0
OK,现在检测任务栏重启的代码搞定了,但是不知道怎么重绘TrayIcon,谁给个代码?100分送上Top
15 楼Lersh(暑片)回复于 2003-06-04 12:48:13 得分 0
重载WndProc…………Top
16 楼ybluo()回复于 2003-06-04 16:33:09 得分 0
请教你是怎样检测任务栏重启的?Top
17 楼Lersh(暑片)回复于 2003-06-04 18:20:54 得分 0
嗯,我说了啊,重载WndProc,检测TaskbarCreated消息Top
18 楼Lersh(暑片)回复于 2003-06-06 17:46:14 得分 0
upTop
19 楼blow_jj(阿俊)回复于 2003-07-04 14:42:13 得分 0
Tray(托盘)是Windows9x任务条上的一个特殊区域,它的技术名称为"任务栏布告区",一些软件(如金山词霸Ⅲ)运行时会在托盘上放置一个图标,使用户一眼就能知道这个程序正在后台运行,要想激活它也很容易,通常只需单击一下这个图标即可,非常方便。Tray的编程比较特殊,但并不难,主要包括图标、工具提示和消息等三个方面,它是Shell编程的一部分。ShellAPI提供了Shell_NotifyIcon函数,用它可以增加、删除或者修改托盘中的图标,在托盘上放置图标后,Windows Shell会负责把发生在图标上的鼠标事件通知应用程序。Shell_NotifyIcon函数定义如下:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage,PNOTIFYICONDATA pnid);
dwMessage表示要完成的操作:NIM_ADD(增加图标)、NIM_DELETE(删除图标)、NIM_MODIFY(修改图标或提示文本),pnid是一个指向NOTIFYICONDATA结构的指针,结构的定义如下:
typedef struct _NOTIFYICONDATA{
DWORD cbSize;//结构所占的字节数,必须用结构的大小来初始化。
HWND hWnd;//接受Tray图标消息的窗口句柄
UINT uID;//由应用程序定义的图标ID
UINT uFlags;//用来鉴别那些需要改变其值的域,NIF_ICON表示hIcon有效,可用来修改图标,NIF_MESSAGE表示uCallbackMessage有效,用来定义消息,NIF_TIP表示szTip参数有效,可修改工具提示。
UINT uCallbackMessage;//应用程序定义的消息
HICON hIcon;//Tray图标的句柄
char szTip[64];//工具提示的文本
}NOTIFYICONDATA;
下面我们就通过一个具体例子来说明实现方法,程序运行时不会显示主窗体,只在托盘上增加一个图标,双击图标可关闭程序。
程序运行时托盘区显示如下:
新建一个工程,放置一个Timer控件到窗体上。打开unit1.h文件,增加头文件说明#include <shellapi.h>,在TForm1定义的private段增加一些数据成员和方法的声明:
unsigned int iconmessage;//定义的消息
void AddTrayIcon();//在托盘上增加图标
void RemoveTrayIcon();//从托盘中删除图标
由于要增加对自定义消息的处理,所以必须重载窗口过程函数WndProc,在TForm1的定义中增加protected段:virtual void __fastcall WndProc(Messages::Tmessage& Message);
在unit1.cpp中定义相应的成员函数:
void TForm1::AddTrayIcon()
{NOTIFYICONDATA icondata;
memset(&icondata,0,sizeof(icondata));
//将结构icondata的各域初始化为0
icondata.cbSize=sizeof(icondata);
icondata.hWnd=Form1->Handle;
strncpy(icondata.szTip,"未知状态",sizeof(icondata.szTip));
icondata.hIcon=Application->Icon->Handle;
icondata.uCallbackMessage=iconmessage;
icondata.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
Shell_NotifyIcon(NIM_ADD,&icondata);
}
void TForm1::RemoveTrayIcon()
{NOTIFYICONDATA icondata;
memset(&icondata,0,sizeof(icondata));
icondata.cbSize=sizeof(icondata);
icondata.hWnd=Form1->Handle;
Shell_NotifyIcon(NIM_DELETE,&icondata);
}
//重载TForm1的WndProc函数,加入对自定义消息的处理代码,这其实相当于创建了TForm类的子类。
void __fastcall TForm1::WndProc(Messages::TMessage& Message)
{
NOTIFYICONDATA icondata;
if(Message.Msg==iconmessage)
{
if(Message.LParam==WM_RBUTTONDOWN)
{
//Form1->PopupMenu1->Popup((icondata.uID->Left),(icondata.uID->Top));
//Application->Terminate();
//如果双击图标,则关闭应用程序
// Form1->Show(); //改动后是显示Form1,去掉托盘
// RemoveTrayIcon();
}
if(Message.LParam==WM_LBUTTONDOWN)
{
//Application->Terminate();
//如果单击图标,则关闭应用程序
Form1->Show(); //改动后是显示Form1,去掉托盘
RemoveTrayIcon();
}
return;
}
TForm::WndProc(Message);
}
//创建窗体的OnCreate事件句柄:
//这里通过调用RegisterWindowMessage函数来定义一个用户消息,也可以通过WM_USER+n来获得一个系统没有使用的消息编号。
//编写Timer1的Timer事件代码,当用户将鼠标停留在图标上时,显示提示文本:
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//iconmessage=RegisterWindowMessage("IconNotify");
//AddTrayIcon();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
RemoveTrayIcon();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{NOTIFYICONDATA icondata;
memset (&icondata, 0, sizeof (icondata));
icondata.cbSize = sizeof (icondata);
icondata.hWnd = Form1->Handle;
String s="编程文档手册";//定义提示文本
strncpy (icondata.szTip, s.c_str(), sizeof (icondata.szTip));
icondata.uFlags = NIF_TIP ;
Shell_NotifyIcon (NIM_MODIFY,&icondata);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormHide(TObject *Sender)
{
iconmessage=RegisterWindowMessage("IconNotify");
AddTrayIcon();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form1->Hide();
}
/*--------------------------------------
在Sample的面板上有TrayIcon控件。*/Top



