VFP 的 systray 好像问题较多
我前天在家里设置单击图标,程序所有表单最小化并隐藏,再单击最大化并将最后打开的置于最顶层,到办公室发现单击不起作用,再重复折腾一遍,包括重新从VFP安装目录拷贝类,重新设计代码,可以用了,今晚回到家,把办公室复制的文件覆盖家里的,发现又不起作用了。打算用木瓜的代码了
**********************************
*VFP中系统托盘 (Vfp9)
*作者:木瓜
*VFP8中没有消息绑定,因此不能用!
*2006新年贺礼
*转载请保持原代码
**********************************
CREATEOBJECT("SysTray") &&这样用法不理解吧?我们要感谢VFP的内存垃圾回收机制带来的便利。
*!* _screen.SysTray.AddIcon("hrrl.ico","木瓜的系统托盘演示","Messagebox('你双击了',64,'信息')")
_screen.SysTray.AddIcon("hrrl.ico","木瓜的系统托盘演示","")
*_screen.Systray.DeleteIcon() &&删除图标
RETURN
*下面是定义的Windows消息,不要删除
#Define WM_MOUSEMOVE 512 &&鼠标经过
#Define WM_LBUTTONDOWN 513 &&鼠标左键按下
#Define WM_LBUTTONUP 514 &&鼠标左键弹起
#Define WM_LBUTTONDBLCLK 515 &&鼠标左键双击
#Define WM_RBUTTONDOWN 516 &&鼠标右键按下
#Define WM_RBUTTONUP 517 &&鼠标右键弹起
#Define NIM_ADD 0 &&添加
#Define NIM_MODIFY 1 &&修改
#Define NIM_DELETE 2 &&删除
#Define NIF_MESSAGE 1
#Define NIF_ICON 2 &&显示图标
#Define NIF_TIP 4 &&显示提示
*---------------------------
*类的定义
DEFINE CLASS SysTray as Custom
*--指定发生事件要执行的命令-----
*鼠标经过(一般不要在这个上面写代码)
CmdMouseMove=""
*鼠标左键按下
CmdLButtonDown=""
*鼠标左键弹起
CmdLButtonUp=""
*鼠标左键双击
CmdLButtonDBLClk="messagebox('The Mouse DBClicked!')"
*鼠标右键按下
CmdRButtonUP=""
*鼠标右键弹起
CmdRButtonDown=""
*字符串
IconData="" &&一个结构
*------------------------------------------------------
PROCEDURE CallBackWndProc() &&消息回调函数,如果不明白,不要修改此函数
LPARAMETERS hWnd, nMsg,nParam,nMsg
*TO DO 处理消息
DO CASE
CASE nMsg=WM_MOUSEMOVE &&鼠标经过
EXECSCRIPT(this.CmdMouseMove)
CASE nMsg=WM_LBUTTONDOWN &&鼠标左键按下
EXECSCRIPT(this.CmdLButtonDown)
CASE nMsg=WM_LBUTTONUP &&鼠标左键弹起
EXECSCRIPT(this.CmdLButtonUp)
CASE nMsg=WM_LBUTTONDBLCLK &&鼠标左键双击
EXECSCRIPT(this.CmdLButtonDBLClk)
CASE nMsg=WM_RBUTTONDOWN &&鼠标右键按下
EXECSCRIPT(this.CmdRButtonDown)
CASE nMsg=WM_RBUTTONUP &&鼠标右键弹起
EXECSCRIPT(this.CmdRButtonUp)
ENDCASE
ENDPROC
*------------------------------------------------------
PROCEDURE AddIcon
LPARAMETERS cIcon,cTitle,cmdDbClick
cbSize = 88 &&结构的大小
uID = 1 &&指定与图标关联的ID。它不是很重要,除非你需要显示并跟踪几个图标(VC中原话这么说的)。
uFlags = NIF_MESSAGE + NIF_ICON + NIF_TIP &&告诉Windows应该读取哪个成员。当添加一个图标时,应该包含这个结构的大多数成员。
&&当更新图标时,如只是需要改变图标时,你只要设置相应的标志就可以了
uCallbackMessage = WM_LBUTTONDBLCLK &&从VC中资料得出,此值应该是一个Windows消息,但在VFP里好像没什么用,因为在回调函数中
&&只能看到是由托盘图标传递的,而具体事件要在回调函数中检查。
hicon = LoadImage(0, cIcon, 1, 16, 16, 16) && 可以替换图标文件
*hicon = ExtractIcon(1, "Explorer.exe", 0) && 可以从你自己的exe文件中提取图标
szTip = PADR(cTitle,64,chr(0)) && 提示信息,控制在 64 个字符内
hWnd=_vfp.HWnd && 句柄
cData = this.NumToDWORD(cbSize);
+ this.NumToDWORD(hWnd) ;
+ chr(uID) + Chr(0) + Chr(0) + Chr(0) ;
+ this.NumToDWORD(uFlags) ;
+ this.NumToDWORD(uCallbackMessage) ;
+ this.NumToDWORD(hIcon) ;
+ szTip
this.IconData=cData &&记录下来数据
Shell_NotifyIcon(NIM_ADD, @cData) &&正式加入
BINDEVENT(Hwnd,uCallbackMessage,_screen.SysTray,"CallBackWndProc")
IF VARTYPE(cmdDbClick)="C"
this.CmdLButtonDBLClk=cmdDbClick &&记录事件
ENDIF
*这里只显示了双击的事件,其他事件可以直接修改相关属性。
ENDPROC
*------------------------------------------------------
PROCEDURE DeleteIcon
LOCAL cData
cData=this.IconData &&读取结构
Shell_NotifyIcon(NIM_DELETE, @cData) &&移除图标
ENDPROC
*------------------------------------------------------
PROCEDURE init() &&加载
Declare integer GetActiveWindow in user32
Declare integer LoadImage in user32 integer, String, integer, integer, integer, integer
Declare integer ExtractIcon in shell32 integer, String, integer
Declare integer Shell_NotifyIcon in shell32 integer, String @
Declare integer RtlMoveMemory in WIN32API as RtlCopyLong string @pDestString, ;
integer @pVoidSource, integer nLength
IF VARTYPE(_screen.SysTray)<>"O" &&自己要使用这个对像
_screen.AddProperty("SysTray")
ENDIF
_screen.SysTray=this &&连接自己
ENDPROC
*------------------------------------------------------
PROCEDURE Destroy
this.DeleteIcon() &&退出时删除图标
ENDPROC
*------------------------------------------------------
PROCEDURE NumToDWORD &&数字转换双字(4字节)
LPARAMETERS nNum
LOCAL cLong
cLong = SPACE(4)
RtlCopyLong(@cLong, BITOR(nNum,0), 4)
RETURN cLong
ENDPROC
ENDDEFINE