把最小化图标放到任务栏右下角
----目前有不少Win95应用程序在最小化后,代表该程序的小图标就会隐藏在屏幕的右下角(即任务栏的右边),如“金山词霸”、“东方快车”等,而我们用VisualBasic编制的程序在最小化后,图标却总是出现在任务栏的中央,并且占据较大的空间。如何让我们自己的程序也能将最小化图标放在任务栏的右边呢?我们可以通过WindowsAPI函数调用来实现该功能。
一、如何添加和隐藏图标 ----在Windows的动态连接库Shell32.dll中有一个名为Shell_NotifyIconA的WindowsAPI函数,其功能是对任务栏的右下角图标进行操作,包括添加、删除和修改。Shell_NotifyIconA函数的VB声明格式如下: ----DeclareFunctionShell_NotifyIconALib"SHELL32"(ByValdwMessageAsLong,lpDataAsNOTIFYICONDATA)AsIntegerShell_NotifyIconA有两个参数DwMessage和lpData。DwMessage为操作图标的方式,可能的取值和含义如下: ----0(向任务栏添加图标) ----1(修改任务栏中的图标) ----2(删除任务栏中的图标) ----lpData是自定义数据类型NOTIFYICONDATA的数据,该自定义数据结构由以下成员构成: ----1.cbSize:需填写NOTIFYICONDATA数据结构的长度,在使用时可通过VB的标准函数Len来计算,如nid为NOTIFYICONDATA类型的变量,则cbSize为Len(nid)。 ----2.hWnd:最小化窗体的句柄。 ----3.uID:使用者为图标所设定的ID,可自定。 ----4.uFlags:用来设定后面三个成员(uCallbackMessage、hIcon、szTip)是否有效,等于1时为uCallbackMessage有效,将来使用者在图标上按下鼠标键时,Windows会发出消息给窗体程序;等于2时为hIcon有效,表示要显示图标(如果不显示图标,用户只是无法看见图标,但仍然可在任务栏的图标应该出现的位置上操作);等于4时为szTip有效,当用户将鼠标指针放在图标上时,要显示提示信息,否则不显示。通常将uFlags设定成7(即1+2+4),表示全部有效。 ----5.uCallbackMessage:当用户在图标上按下鼠标按键时,Windows发给应用程序的消息编号。 ----6.hIcon:图标句柄。 ----7.szTip:当用户将鼠标指针放在图标上时显示的提示信息。 ----在调用Shell_NotifyIconA函数之前,必须将NOTIFYICONDATA类型变量的以上各成员填写正确的内容。 ----该函数如果调用成功则返回1,否则返回0。 ----了解了Shell_NotifyIconA函数的功能和用法后,我们可以很容易地将图标添加在任务栏的右边,或者从任务栏上将图标删除。 ----如:假设我们事先声明了一个NOTIFYICONDATA型的变量nid,且已经给它的所有成员赋予了合适的值,那么,下面的两条语句分别可完成添加和删除图标的任务: Shell_NotifyIconA(0,nid) '添加图标 Shell_NotifyIconA(2,nid)'删除图标 二、如何响应鼠标按键 ----按照上面的方法,我们可以将最小化后的图标放在任务栏的右边,那么当我们在该图标上按下鼠标按键时会发生什么事情呢?很遗憾,什么也没有发生,最小化的窗体不会象我们希望的那样恢复正常显示状态。 ----这时怎么回事呢?很简单,前面我们只是将图标添加到了任务栏上,而并没有对鼠标事件做任何的工作,为了对鼠标按键作出响应,我们还有一些事情要做。 ----前面已经说过,如果将将NOTIFYICONDATA类型变量的成员uFlags设定为1,则当用户在图标上按下鼠标按键时,Windows会将编号为uCallbackMessage的消息发送到应用程序,因此,为了能响应鼠标事件,我们必须在程序中对该消息进行处理。 ----需要注意的是,由于Windows自身的消息处理机制的限制,我们无法直接干预Windows的自身消息处理过程,所以只有采用一种类似于从前DOS环境下截获中断的“曲线救国“的方法来处理消息,过程是: ----在窗体最小化后,立即读取该窗体原消息处理过程的地址并记录在一个全局变量中,方法是调用WindowsAPI函数GetWindowLong,其声明如下: ----DeclareFunctionGetWindowLongLib"user32"Alias"GetWindowLongA"(ByValhWndAsLong,ByValnIndexAsLong)AsLong其中hWnd为窗体句柄,nIndex为过程类型,这里为-4(Windows默认过程)。 ----(2)编写自己的消息处理过程,注意参数的数量和类型必须按照下面的格式(过程名可随意): ----SubWndProcForIcon(ByValhWndAsLong,ByValMsgAsLong,ByValwParamAsLong,ByVallParamAsLong) ----(3)将自己的消息处理过程设置为默认的消息处理程序,方法是调用WindowsAPI函数SetWindowLong,其声明如下: ----DeclareFunctionSetWindowLongLib"user32"Alias"SetWindowLongA"(ByValhWndAsLong,ByValnIndexAsLong,ByValdwNewLongAsLong)AsLong ----其中hWnd与nIndex含义同上,dwNewLong为自定义过程的地址,可使用VB的求地址运算符AddressOf得到,如AddressOfWndProcForIcon可得到自定义过程WndProcForIcon的地址。 ----(4)当鼠标事件发生后,自己的消息处理过程(现在已成为默认的消息处理过程)首先进行处理,一般是根据按键将窗体恢复或弹出一个PopUp菜单供用户选择。 ----(5)让Windows去执行原消息处理过程(该过程的地址由全局变量保存),方法是调用WindowsAPI函数CallWindowProc,其声明如下: ----DeclareFunctionCallWindowProcLib"user32"Alias"CallWindowProcA"(ByVallpPrevWndFuncAsLong,ByValhWndAsLong,ByValMsgAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLong ----其中lpPrevWndFunc为原消息处理程序的地址,其它参数与自定义消息处理过程中的参数相对应。 ----细心的读者一定会发现,如果在上述第3步完成后,没有进行第5步,即:使用setWindowLong改变了原先消息处理程序的地址,却没有在程序结束前将地址设定回来,那程序将不会正常结束,往往会造成死机,因此,程序中一定要小心处理这个问题。 ----另外,为了正确的处理消息,还有一个问题需要解决,就是如何识别消息是否是由图标发出的?这一点可以这样解决:利用一个全局变量记录下NOTIFYICONDATA型变量的成员uCallbackMessage(消息号)的值,然后在消息处理程序中检查Windows传回的消息号(MsgNo)是否与其一致,如果一致,则说明消息的确是由图标发出的,应该进行处理,否则即可忽略。如本文后面的程序实例就用全局变量IconMsg来实现这一功能(具体请参照程序代码)。 上一篇:VB调用API函数使窗口保持在最上层 下一篇:如何用VB在桌面建立快捷方式 更多相关文章
|
推荐文章
精彩文章
|