Shell_NotifyIcon
按Alt:
keybd_event按F1
SendMessage(QQhWnd,WM_CHAR,VK_F1,0);I'm not positive to these answer,but it the general solution,try it out.

解决方案 »

  1.   


        托盘程序详解(一) 
         很多软件运行时会在系统托盘区(就是桌面右下角显示时间的区域)出现一个小图标,它作为程序运行的一个标志,我们可以通过使用小图标所弹出的菜单来控制应用程序的状态。本例就给出了一个功能比较完整的托盘程序,我们可以看到怎样用API函数Shell_NotifyIcon来添加、删除、更改托盘图标;而且例中还演示了为托盘图标添加右键菜单和浮动提示的方法。    程序中用到了Shell_NotifyIcon、SendMessage、CallWindowProc、SetWindowLong等API函数,其中Shell_NotifyIcon是主要的函数,它用来添加、删除、更改系统托盘区(taskbar status area)的图标,所以我们先来看看这个函数的声明和参数:  使用API函数之前必须先在程序中声明如下:
      Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long  其中各参数的意义如下表:参数: 意义 
    dwMessage 为消息设置值,它可以是以下的几个常数值:0、1、2
    NIM_ADD = 0     加入图标到系统状态栏中
    NIM_MODIFY = 1    修改系统状态栏中的图标
    NIM_DELETE = 2    删除系统状态栏中的图标LpData 用以传入NOTIFYICONDATA数据结构变量,其结构如下所示:
    Type NOTIFYICONDATA
      cbSize As Long        需填入NOTIFYICONDATA数据结构的长度
      HWnd As Long         设置成窗口的句柄
      Uid As Long         为图标所设置的ID值
      UFlags As Long        设置uCallbackMessage,hIcon,szTip是否有效
      UCallbackMessage As Long   消息编号
      HIcon As Long         显示在状态栏上的图标
      SzTip As String * 64     提示信息
    End Type返回值 Long,非零表示成功,零表示失败   在使用这个API函数之前我们应该先定义结构类型NOTIFYICONDATA:
       Public Type NOTIFYICONDATA
         cbSize As Long HWnd As Long
         Uid As Long UFlags As Long
         UCallbackMessage As Long
         HIcon As Long
         SzTip As String * 64
       End Type
      然后定义一个NOTIFYICONDATA的变量TheData来记录设置托盘图标的数据
       Private TheData As NOTIFYICONDATA  这时我们就可以使用这个函数来设置系统托盘图标了,具体方法如下:
       1、添加图标
       With TheData
        .Uid = 0
        .HWnd = frm.HWnd           'frm.HWnd是程序主窗体的句柄
        .cbSize = Len(TheData)
        .HIcon = frm.Icon.Handle       'frm.Icon.Handle指向主窗体的图标
        .UFlags = NIF_ICON
        .UCallbackMessage = TRAY_CALLBACK '作用是允许返回消息,在下一节中会有详细解释。
        .UFlags = .UFlags Or NIF_MESSAGE
        .cbSize = Len(TheData)
       End With
       Shell_NotifyIcon NIM_ADD, TheData    '根据前面定义NIM_ADD,设置为“添加模式”,然后添加   2、删去图标
       With TheData
        .UFlags = 0
       End With
       Shell_NotifyIcon NIM_DELETE, TheData  '根据前面定义NIM_DELETE,设置为“删除模式”   3、更改图标
       With TheData
        .HIcon = pic.Handle          'pic是图片狂PictureBox,存放图标文件
        .UFlags = NIF_ICON
       End With
       Shell_NotifyIcon NIM_MODIFY, TheData  '根据前面定义NIM_MODIFY,设置为“更改模式”   4、为图标添加浮动提示信息
       With TheData
        .SzTip = tip & vbNullChar       'tip是字符串string,存储提示信息
        .UFlags = NIF_TIP           '指明要对浮动提示进行设置
       End With
       Shell_NotifyIcon NIM_MODIFY, TheData  '根据前面定义NIM_MODIFY,设置为“修改模式”  通过以上几段代码我们就能根据自己需要添加、删除、更改系统托盘图标,并能添加系统图标上的浮动提示信息。但这时的托盘图标是孤立的,我们并不能利用它来控制应用程序的行为,怎么办呢?别急,接着下节的内容会继续这个例子的介绍,并给你答案的。 
     
       
     
      
     
      

  2.   


        托盘程序详解(二) 
     
       
    如果你下载(源程序下载)并运行这个例程序,你会发现如果我们在托盘图标上点击鼠标右键,则会弹出一个右键菜单(如右图)。如果点击相应的菜单项,程序主窗体会随之变化,这样就可以控制程序的行为。而如果当主窗体处于最小化状态时,我们在托盘图标上点击左键,窗体会恢复到原来的大小。其实实现上述的功能都要依赖于WINDOWS操作系统的消息机制,要完全弄懂这个机制挺不容易的,但是我们可以按下述文字来理解它。  把WINDOWS操作系统看作人的大脑,它接收、处理、并发送各种各样的信息给我们的各个器官(当然是比喻各个应用程序了),也就是说它是消息的中枢。而每个应用程序(甚至每一个按钮、标签、窗体等等统称为窗口)在运行时都会被分配一个窗口过程WINDOWPROC,由这个窗口过程来接收和处理操作系统发来的消息(实际上存在一个消息队列),通常情况下这个窗口过程是由操作系统指定的,它会自动的响应并处理一些WINDOWS消息(如窗体移动、最大化、最小化、错误信息等)。好,到这我们先停一下,提出一个疑问,这些消息能否由我们自己写程序来处理呢?答案是肯定的,不过还得借助API函数的威力了,怎么用?我们还是先看看这些API函数的定义和参数吧。  程序中用到了SendMessage、CallWindowProc、SetWindowLong等API函数,其中SendMessage函数的作用是将一条消息发给某个窗口;CallWindowProc函数用来发送消息到一个窗口过程;而使用SetWindowLong函数来为窗口结构中为指定的窗口设置属性。使用API函数之前必须先在程序中声明如下:
       Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
       Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal HWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
       Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal HWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long  其中各参数的意义如下表:CallWindowProc函数
    参数: 意义 
    lpPrevWndFunc Long,原来的窗口过程地址HWnd Long,窗口句柄Msg Long,发送的消息 
    wParam Long,消息类型,参考wParam参数表 
    lParam Long,依据wParam参数的不同而不同 
    返回值 Long,依据发送的消息不同而变化 
    SetWindowLong函数 参数: 意义 
    hwnd Long,欲为其取得信息的窗口的句柄nIndex Long,请参考GetWindowLong函数的nIndex参数的说明dwNewLong Long,由nIndex指定的窗口信息的新值 
    返回值 Long,指定数据的前一个值 
    SendMessage函数 参数: 意义 
    hwnd Long,要接收消息的那个窗口的句柄wMsg Long,消息的标识符wParam Long,具体取决于消息 
    lParam Any,具体取决于消息 
    返回值 Long,由具体的消息决定   我们要自己写程序来处理消息,必须先更改窗口的属性,从原来由默认的窗口过程来处理消息变成由我们自己写的消息处理过程来处理消息。方法是使用SetWindowLong函数来取得默认窗口过程的地址,然后转向为我们自己写的窗口过程的地址,具体的实现方法如下代码:
       'GWL_WNDPROC获得该窗口的窗口过程的地址,AddressOf是取址函数,NewWindowProc是我们写的过程
       OldWindowProc = SetWindowLong(frm.HWnd, GWL_WNDPROC, AddressOf NewWindowProc)  然后在NewWindowProc函数中写入如下代码,需要注意的是下面代码中红色的TRAY_CALLBACK是由托盘区图标传来的消息,要让托盘图标传回消息,必须在添加托盘图标时指定(参见上节内容):
       Public Function NewWindowProc(ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
       '如果用户点击了托盘中的图标,则进行判断是点击了左键还是右键
       If Msg = TRAY_CALLBACK Then
         '如果点击了左键
         If lParam = WM_LBUTTONUP Then
           '而这时窗体的状态是最小化时
           If TheForm.WindowState = vbMinimized Then _
            '恢复到最小化前的窗体状态
              TheForm.WindowState = TheForm.LastState
              TheForm.SetFocus
              Exit Function
           End If
         End If
         '如果点击了右键
         If lParam = WM_RBUTTONUP Then
           '则弹出右键菜单
           TheForm.PopupMenu TheMenu
           Exit Function
         End If
       End If
       '如果是其他类型的消息则传递给原有默认的窗口函数
       NewWindowProc = CallWindowProc(OldWindowProc, HWnd, Msg, wParam, lParam)
       End Function  这样我们就取得并处理了来自托盘图标的消息,现在的问题是在鼠标右键菜单弹出后,怎么控制程序主窗体的状态,这时我们需要用到SendMessage函数来向主窗体发送最大化、最小化、关闭、移动等消息,具体的代码实现如下,其中HWnd是主窗体的句柄,WM_SYSCOMMAND表示发送的是系统控制类的消息,SC_MOVE、SC_SIZE、SC_RESTORE便是要发送的消息了:
       '托盘图标右键菜单上的“移动”项被点击时
       Private Sub mnuTrayMove_Click()
         SendMessage HWnd, WM_SYSCOMMAND, SC_MOVE, 0&
       End Sub
       '托盘图标右键菜单上的“恢复”项被点击时
       Private Sub mnuTrayRestore_Click()
         SendMessage HWnd, WM_SYSCOMMAND, SC_RESTORE, 0&
       End Sub
       '托盘图标右键菜单上的“退出”项被点击时
       Private Sub mnuTraySize_Click()
         SendMessage HWnd, WM_SYSCOMMAND, SC_SIZE, 0&
       End Sub  最后要提醒你,在程序退出时一定要把窗口过程的地址恢复为默认值,同时把托盘图标移去哦。  
     
       
     
      
     
      

  3.   

    HOOKS 说明书hook是WINDOWS提供的一种消息处理机制,它使得程序员可以使用子过程来监视系统消息,并在消息到达目标过程前得到处理。 
    下面将介绍WINNDOWS HOOKS并且说明如何在WINDOWS 程序中使用它。 关于HOOKS 
    使用HOOK 将会降低系统效率,因为它增加了系统处量消息的工作量。建议在必要时才使用HOOK,并在消息处理完成后立即移去该HOOK。 
    HOOK链 
    WINDOWS提供了几种不同类型的HOOKS;不同的HOOK可以处理不同的消息。例如,WH_MOUSE HOOK用来监视鼠标消息。 
    WINDOWS为这几种HOOKS维护着各自的HOOK链。HOOK链是一个由应用程序定义的回调函数队列,当某种类型的消息发生时,WINDOWS向此种类型的HOOK链的第一个函数发送该消息,在第一函数处理完该消息后由该函数向链表中的下一个函数传递消息,依次向下。如果链中某个函数没有向下传送该消息,那么链表中后面的函数将得不到此消息。(对于某些类型的HOOK,不管HOOK链中的函数是否向下传递消息,与此类型HOOK联系的所有HOOK函数都会收到系统发送的消息) 
    HOOK过程 
    为了拦截特定的消息,你可以使用SetWindowsHookEx函数在该类型的HOOK链中安装你自己的HOOK函数。该函数语法如下: 
    public function MyHook(nCode,wParam,iParam) as long 
    ‘加入代码 
    end function 
    其中MyHook可以随便命名,其它不能变。该函数必须放在模块段。nCode指定HOOK类型。wParam,iParam的取值随nCode不同而不同,它代表了某种类型的HOOK的某个特定的动作。 
    SetWindowsHookEx总是将你的HOOK函数放置在HOOK链的顶端。你可以使用CallNextHookEx函数将系统消息传递给HOOK链中的下一个函数。 
    [注释]对于某些类型的HOOK,系统将向该类的所有HOOK函数发送消息,这时,HOOK函数中的CallNextHookEx语句将被忽略。 
    全局HOOK函数可以拦截系统中所有线程的某个特定的消息(此时该HOOK函数必须放置在DLL中),局部HOOK函数可以拦截指定线程的某特定消息(此时该HOOK函数可以放置在DLL中,也可以放置在应用程序的模块段)。 
    [注释] 建议只在调试时使用全局HOOK函数。全局HOOK函数将降低系统效率,并且会同其它使用该类HOOK的应用程序产生冲突。 HOOK类型 
    WH_CALLWNDPROC 和 WH_CALLWNDPROCRET HOOK 
    WH_C ALLWNDPROC 和WH_CALLWNDPROCRET HOOK可以监视SendMessage发送的消息。系统在向窗体过程发送消息前,将调用WH_CALLWNDPROC;在窗体过程处理完该消息后系统将调用WH_CALLWNDPROCRET。 
    WH_CALLWNDPROCRET HOOK会向HOOK过程传送一个CWPRETSTRUCT结构的地址。该结构包含了窗体过程处理系统消息后的一些信息。 
    WH_CBT Hook 
    系统在激活,创建,消毁,最小化,最大化,移动,改变窗体前;在完成一条系统命令前;在从系统消息队列中移去鼠标或键盘事件前;在设置输入焦点前,或同步系统消息队列前,将调用WH_CBT HOOK。你可以在你的HOOK 过程拦截该类HOOK,并返回一个值,告诉系统,是否继续执行上面的操作。 
    WH_DEBUG HOOK 
    系统在调用与某种HOOK类型联系的HOOK过程前,将调用WH_DEBUG ,应用程序可以使用该HOOK决定是否让系统执行某种类型的HOOK。 
    WH_FOREGROUNDIDLE Hook 
    系统在空闲时调用该HOOK,在后台执行优先权较低的应用程序。 
    WH_GETMESSAGE Hook 
    WH_GETMESSAGE Hook使应用程序可以拦截GetMessage 或 PeekMessage的消息。应用程序使用WH_GETMESSAGE HOOK监视鼠标、键盘输入和发送到队列中的其它消息。 
    WH_JOURNALRECORD Hook 
    WH_JOURNALRECORD Hook使应用程序可以监视输入事件。典型地,应用程序使用该HOOK记录鼠标、键盘输入事件以供以后回放。该HOOK是全局HOOK,并且不能在指定线程中使用。 
    WH_JOURNALPLAYBACK Hook 
    ` WH_JOURNALPLAYBACK Hook使应用程序可以向系统消息队列中插入消息。该HOOK可以回放以前由WH_JOURNALRECORD HOOK录制的鼠标、键盘输入事件。在WH_JOURNALPLAYBACK Hook安装到系统时,鼠标、键盘输入事件将被屏蔽。该HOOK同样是一个全局HOOK,不能在指定线程中使用。 
    WH_JOURNALPLAYBACK Hook返回一个时间暂停值,它告诉系统,在处理当前回放的消息时,系统等待百分之几秒。这使得此HOOK可以控制在回放时的时间事件。 
    WH_KEYBOARD Hook 
    WH_KEYBOARD Hook使应用程序可以监视由GetMessage和PeekMessage返回的WM_KEYDOWN 及WM_KEYUP消息。应用程序使用该HOOK监视发送到消息队列中的键盘输入。 
    WH_MOUSE Hook 
    WH_MOUSE Hook 使应用程序可以监视由GetMessage和PeekMessage返回的消息。应用程序使用该HOOK监视发送到消息队列中的鼠标输入。 
    WH_MSGFILTER and WH_SYSMSGFILTER Hooks 
    WH_MSGFILTER 和WH_SYSMSGFILTER Hooks使应用程序可以监视菜单、滚动条、消息框、对话框,当用户使用ALT+TAB或ALT+ESC来切换窗体时,该HOOK也可以拦截到消息。WH_MSGFILTER仅在应用程序内部监视菜单、滚动条、消息框、对话框,而WH_SYSMSGFILTER则可以在系统内监视所有应用程序的这些事件。 
    WH_SHELL Hook 
    一个SHELL程序可以使用WH_SHELL Hook来接收重要的信息。当一个SHELL程序被激活前或当前窗体被创建、消毁时,系统会调用WH_SHELL Hook过程。 
    使用HOOK 
    安装、消毁HOOK过程 
    监视系统事件 安装、消毁HOOK过程 
    使用SetWindowsHookEx函数,指定一个HOOK类型,自己的HOOK过程是全局还是局部HOOK,同时给出HOOK过程的进入点,就可以轻松的安装你自己的HOOK过程。 
    为了安装一个全局HOOK过程,必须在应用程序外建立一个DLL,并将该HOOK函数封装到其中,应用程序在安装全局HOOK过程时必须先得到该DLL模块的句柄。将DLL名传递给LoadLibrary 函数,就会得到该DLL模块的句柄;得到该句柄 后,使用GetProcAddress函数可以得到HOOK过程的地址。最后,使用SetWindowsHookEx将HOOK过程的首址嵌入相应的HOOK链中,SetWindowsHookEx传递一个模块句柄,它为HOOK过程的进入点,线程标识符置为0,指出:该HOOK过程同系统中的所有线程关联。 
    以下是C写的例程,大家可以方便的转换为VB程序。 
    HOOKPROC hkprcSysMsg; 
    static HINSTANCE hinstDLL; 
    static HHOOK hhookSysMsg; 


    . hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll"); 
    hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); 
    hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER, 
    hkprcSysMsg, hinstDLL, 0);
      

  4.   

    'Download the full source+pictures+... at http://kpdteam.hypermart.net/download/tray.zip
    Private Type NOTIFYICONDATA
        cbSize As Long
        hWnd As Long
        uId As Long
        uFlags As Long
        ucallbackMessage As Long
        hIcon As Long
        szTip As String * 64
    End TypePrivate Const NIM_ADD = &H0
    Private Const NIM_MODIFY = &H1
    Private Const NIM_DELETE = &H2
    Private Const NIF_MESSAGE = &H1
    Private Const NIF_ICON = &H2
    Private Const NIF_TIP = &H4Private Const WM_LBUTTONDBLCLK = &H203
    Private Const WM_LBUTTONDOWN = &H201
    Private Const WM_RBUTTONUP = &H205Private Declare Function Shell_NotifyIcon Lib "shell32" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
    Dim TrayI As NOTIFYICONDATA
    Private Sub Form_Load()
        TrayI.cbSize = Len(TrayI)
        'Set the window's handle (this will be used to hook the specified window)
        TrayI.hWnd = pichook.hWnd
        'Application-defined identifier of the taskbar icon
        TrayI.uId = 1&
        'Set the flags
        TrayI.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
        'Set the callback message
        TrayI.ucallbackMessage = WM_LBUTTONDOWN
        'Set the picture (must be an icon!)
        TrayI.hIcon = imgIcon(2).Picture
        'Set the tooltiptext
        TrayI.szTip = "Recent" & Chr$(0)
        'Create the icon
        Shell_NotifyIcon NIM_ADD, TrayI    Me.Hide
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
        'remove the icon
        TrayI.cbSize = Len(TrayI)
        TrayI.hWnd = pichook.hWnd
        TrayI.uId = 1&
        Shell_NotifyIcon NIM_DELETE, TrayI
        End
    End Sub
    Private Sub mnuPop_Click(Index As Integer)
        Select Case Index
            Case 0
                MsgBox "KPD-Team 1998" + Chr$(13) + "URL: http://www.allapi.net/" + Chr$(13) + "E-Mail: [email protected]", vbInformation + vbOKOnly
            Case 2
                Unload Me
        End Select
    End Sub
    Private Sub pichook_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
        Msg = X / Screen.TwipsPerPixelX
        If Msg = WM_LBUTTONDBLCLK Then
            'Left button double click
            mnuPop_Click 0
        ElseIf Msg = WM_RBUTTONUP Then
            'Right button click
            Me.PopupMenu mnuPopUp
        End If
    End Sub
    Private Sub Timer1_Timer()
        Static Tek As Integer
        'Animate the icon
        Me.Icon = imgIcon(Tek).Picture
        TrayI.hIcon = imgIcon(Tek).Picture
        Tek = Tek + 1
        If Tek = 3 Then Tek = 0
        Shell_NotifyIcon NIM_MODIFY, TrayI
    End Sub
      

  5.   

    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
    Private Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Const WM_SETHOTKEY = &H32
    Const WM_SHOWWINDOW = &H18
    Const HK_SHIFTA = &H141 'Shift + A
    Const HK_SHIFTB = &H142 'Shift + B
    Const HK_CONTROLA = &H241 'Control + A
    Const HK_ALTZ = &H45A
    'The value of the key-combination has to
    'declared in lowbyte/highbyte-format
    'That means as a hex-number: the last two
    'characters specify the lowbyte (e.g.: 41 = a),
    'the first the highbyte (e.g.: 01 = 1 = Shift)
    Private Sub Form_Load()
        'KPD-Team 1999
        'URL: http://www.allapi.net/
        'E-Mail: [email protected]
        Me.WindowState = vbMinimized
        'Let windows know what hotkey you want for
        'your app, setting of lParam has no effect
        erg& = SendMessage(Me.hwnd, WM_SETHOTKEY, HK_ALTZ, 0)
        'Check if succesfull
        If erg& <> 1 Then
        MsgBox "You need another hotkey", vbOKOnly, "Error"
        End If
        'Tell windows what it should do, when the hotkey
        'is pressed -> show the window!
        'The setting of wParam and lParam has no effect
        erg& = DefWindowProc(Me.hwnd, WM_SHOWWINDOW, 0, 0)
    End Sub
      

  6.   

    tianxiaolei(辛武) ,你贴的托盘程序详解1,2是再哪个网站看的?
    能不能把网址给我说下?
    谢谢
      

  7.   

    www.21code.com
    这种代码满地都是~~~~~~~~