把最小化图标放到任务栏右下角

唐北漂

唐北漂

2016-02-19 18:26

下面是个超简单的把最小化图标放到任务栏右下角教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~
----目前有不少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来实现这一功能(具体请参照程序代码)。
  
  三、程序实例
  ----下面,我们通过一个简单的实例来实现上述方法:
  ----1、窗体布局
  
  ----新建一个工程IconTest,新建一个标准窗体frmIconTest,在窗体上放置三个命令按钮,名称(Name)分别为cmdCreateIcon、cmdNormalMin和cmdExit,标题(Caption)分别为“最小化到右下角”、“普通最小化”和“退出”。
  
  ----2、代码
  
  ----添加一个模块modIconTest,在其中编写如下的代码:
  
  OptionExplicit
  '定义常量
  PublicConstGWL_WNDPROC=(-4)
  PublicConstWM_LBUTTONDOWN=&H201
  PublicConstNIM_ADD=0
  PublicConstNIM_DELETE=2
  PublicConstNIF_MESSAGE=1
  PublicConstNIF_ICON=2
  PublicConstNIF_TIP=4
  '定义全局变量
  PublicIconMsgAsLong'消息编号
  PublicOldWinProcAsLong'原消息处理程序的地址
  '定义自定义数据类型
  PublicTypeNOTIFYICONDATA
  cbSizeAsLong
  hWndAsLong
  uIDAsLong
  uFlagsAsLong
  uCallbackMessageAsLong
  hIconAsLong
  szTipAsString*64
  EndType
  'WindowsAPI函数声明
  DeclareFunctionCallWindowProcLib"user32"Alias
  "CallWindowProcA"(ByVallpPrevWndFuncAsLong,
  ByValhWndAsLong,ByValMsgAsLong,ByVal
  wParamAsLong,ByVallParamAsLong)AsLong
  DeclareFunctionGetWindowLongLib"user32"
  Alias"GetWindowLongA"(ByValhWndAsLong,
  ByValnIndexAsLong)AsLong
  DeclareFunctionSetWindowLongLib"user32"Alias
  "SetWindowLongA"(ByValhWndAsLong,ByValnIndex
  AsLong,ByValdwNewLongAsLong)AsLong
  DeclareFunctionShell_NotifyIconALib"SHELL32"(ByVal
  dwMessageAsLong,lpDataAsNOTIFYICONDATA)AsInteger
  '自定义消息处理程序
  SubMyProc(ByValhWndAsLong,ByValMsgAsLong,
  ByValwParamAsLong,ByVallParamAsLong)
  '根据Msg判断,消息是否是图标发出的,
  如果是,再进行处理
  IfMsg=IconMsgThen
  IflParam=WM_LBUTTONDOWNThen
  frmIconTest.Show'如果在图标上按
  下了左键则显示窗体
  EndIf
  EndIf
  '执行全程变量OldWinProc记录的原
  消息处理程序的地址中的消息处理程序
  CallWindowProcOldWinProc,hWnd,Msg,wParam,lParam
  EndSub
  在frmIconTest的窗体模块中编写如下代码:
  OptionExplicit
  DimHadAddAsBoolean
  DimnidAsNOTIFYICONDATA
  PrivateSubcmdEnd_Click()
  IfHadAddThen
  '如果曾向右下角添加过小图标
  '则根据事先记录的OldWinProc
  恢复原来的消息处理程序,并删除图标
  SetWindowLongfrmIconTest.hWnd,
  GWL_WNDPROC,OldWinProc
  CallShell_NotifyIconA(NIM_DELETE,nid)
  '删除图标
  EndIf
  UnloadMe'卸载窗体
  EndSub
  PrivateSubcmdCreateIcon_Click()
  IfNotHadAddThen
  '如果没有产生过图标,则添加图标到右下角
  Withnid
  '以下填写nid变量的所有成员
  .cbSize=Len(nid)'填写自定义数据类型的长度
  .hWnd=frmIconTest.hWnd'填写窗体的句柄
  .uID=9999'图标的Id,可随意
  '允许显示图标、提示并产生消息
  .uFlags=NIF_ICON NIF_TIP NIF_MESSAGE
  .hIcon=frmIconTest.Icon.Handle'图标句柄
  .szTip="单击鼠标左键恢复窗体!"'提示信息
  .uCallbackMessage=2'图标的消息号
  EndWith
  Shell_NotifyIconANIM_ADD,nid'添加图标
  IconMsg=nid.uCallbackMessage
  '用全局变量记录消息号,
  '读取frmIconTest正常的消息处理程序
  的地址保存在全程变量OldWinProc中
  OldWinProc=GetWindowLong(frmIconTest.hWnd,
  GWL_WNDPROC)
  '用自定义过程MyProc的地址
  代替正常消息处理程序的地址
  SetWindowLongfrmIconTest.hWnd,
  GWL_WNDPROC,AddressOfMyProc
  frmIconTest.Hide'隐藏窗体
  HadAdd=True'置“已经添加图标”标志
  Else
  frmIconTest.Hide'如果已经有小图标了,
  则直接隐藏窗体
  EndIf
  EndSub
  PrivateSubcmdNormalMin_Click()
  frmIconTest.WindowState=1'普通最小化窗体
  EndSub
  PrivateSubForm_Load()
  HadAdd=False'将“是否添加了图标的标志”置为False
  '下面为窗体装载图标,读者应当根据自己的VB目录而定
  frmIconTest.Icon=oadPicture("c:MyIconfiles10.ico")
  EndSub
  
  ----按下F5,执行本程序,单击“最小化到右下角”按钮,窗体将消失,同时任务栏的右边出现代表窗体的图标(如图2),在该图标上单击鼠标左键,窗体恢复正常。再单击“普通最小化图标”按钮,你会看到窗体虽然也消失了,但最小化图标在任务栏的中间,即普通位置(如图3)。
  
  ----本程序用VB5编制,在Pwin95下调试正常。->

展开更多 50%)
分享

猜你喜欢

把最小化图标放到任务栏右下角

编程语言 网络编程
把最小化图标放到任务栏右下角

MSN怎么最小化到右下角?

电脑网络
MSN怎么最小化到右下角?

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Win10任务栏右下角时钟图标消失不见的解决方法

电脑入门
Win10任务栏右下角时钟图标消失不见的解决方法

Win10任务栏右下角不显示QQ图标的解决方法

电脑入门
Win10任务栏右下角不显示QQ图标的解决方法

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

xp隐藏右下角图标设置

电脑入门
xp隐藏右下角图标设置

用VB实现窗口图标最小化到通知栏

vb
用VB实现窗口图标最小化到通知栏

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

比较VC和Delphi的WinTest工程

比较VC和Delphi的WinTest工程

AJAX与数据岛实现无刷新绑定

AJAX与数据岛实现无刷新绑定
下拉加载更多内容 ↓