首页
社区
课程
招聘
VB托盘程序
发表于: 2007-1-13 17:52 5628

VB托盘程序

2007-1-13 17:52
5628
Option Explicit
Private Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
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 Type
Private Const NIF_ICON = &H2
Private Const NIF_MESSAGE = &H1
Private Const NIF_TIP = &H4
Private Const NIM_ADD = &H0
Private Const NIM_DELETE = &H2
Private Const NIM_MODIFY = &H1

Private Const WM_MOUSEMOVE = &H200

Dim MyIcon As NOTIFYICONDATA

Private Sub Form_Load()
  Me.ScaleMode = vbPixels
  With MyIcon
    .cbSize = Len(MyIcon)
    .hIcon = Me.Icon
    .hwnd = Me.hwnd
    .szTip = "test" & Chr(0)
    .uCallbackMessage = WM_MOUSEMOVE
    .uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
  End With
  Shell_NotifyIcon NIM_ADD, MyIcon
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  'Debug.Print Button, Shift, X, Y
  If X = 513 Then Debug.Print "鼠标左键被按下"
  If X = 514 Then Debug.Print "鼠标左键被抬起"
  If X = 516 Then Debug.Print "鼠标右键被按下"
  If X = 517 Then Debug.Print "鼠标右键被抬起"
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Shell_NotifyIcon NIM_DELETE, MyIcon
End Sub
其中的这段代码
If X = 513 Then Debug.Print "鼠标左键被按下"
If X = 514 Then Debug.Print "鼠标左键被抬起"
If X = 516 Then Debug.Print "鼠标右键被按下"
  If X = 517 Then Debug.Print "鼠标右键被抬起"
为什么只要消息已经挂接到这个过程,x就会等于513、514、516、517呢,挂接是怎么回事??为什么挂接不是到参数y呢?而是参数x呢???

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 26
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
而这里513、514、516、517却是和lParam参数进行赋值?这是怎么回事?
Function Windproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

   Select Case Msg
     Case 9999
       Debug.Print Msg, wParam, lParam, hwnd
       If lParam = 513 Then Debug.Print "left down"
       If lParam = 514 Then Debug.Print "left up"
       If lParam = 516 Then Debug.Print "right down"
       If lParam = 517 Then Debug.Print "right up"
   End Select
   
    Windproc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End Function
2007-1-13 18:02
0
雪    币: 26
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
'form1
Option Explicit
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

Private Const SPI_GETWORKAREA        As Long = 48

Private Const NIF_ICON = &H2
Private Const NIF_MESSAGE = &H1
Private Const NIF_TIP = &H4
Private Const NIM_ADD = &H0
Private Const NIM_DELETE = &H2
Private Const NIM_MODIFY = &H1

Private Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type

Private Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long

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 Type

Dim dddd As NOTIFYICONDATA

Private Sub Form_Load()
  Dim ret As Long
  prevWndProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
  ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf Windproc)
  With dddd
    .cbSize = Len(dddd)
    .hIcon = Me.Icon
    .hwnd = Me.hwnd
    .szTip = "asdf" & Chr(0)
    .uID = 1
    .uCallbackMessage = 9999
    .uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
  End With
  Shell_NotifyIcon NIM_ADD, dddd
End Sub

Private Sub Form_Unload(Cancel As Integer)
  Dim ret As Long
  ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, prevWndProc)
  Shell_NotifyIcon NIM_DELETE, dddd
End Sub

'module1
Option Explicit

Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public 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

  Public Const GWL_WNDPROC = (-4)
Public prevWndProc As Long

Function Windproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

   Select Case Msg
     Case 9999
       Debug.Print Msg, wParam, lParam, hwnd
       If lParam = 513 Then Debug.Print "left down"
       If lParam = 514 Then Debug.Print "left up"
       If lParam = 516 Then Debug.Print "right down"
       If lParam = 517 Then Debug.Print "right up"
   End Select
   
    Windproc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End Function

这是二楼的完整代码
2007-1-13 18:05
0
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
为什么只要消息已经挂接到这个过程,x就会等于513、514、516、517呢,挂接是怎么回事??为什么挂接不是到参数y呢?而是参数x呢???

而这里513、514、516、517却是和lParam参数进行赋值?这是怎么回事?     

===================
首先, 这个值是windows定义的常量对应
WM_LBUTTONDOWN, WM_LBUTTONUP,  WM_RBUTTONDOWN,...
至于为什么要放到lparam, msdn解释
Note The messages discussed above are not conventional Windows messages. They are sent as the lParam value of the application-defined message that is specified when the icon is added with NIM_ADD.
人家就这么放的, 可能wparam做别的用去了吧, 不要问为什么.

好了, 首先, 通过Shell_NotifyIcon的NIM_ADD操作,增加一个托盘
图标, 这个图标的属性为, callback为99999,  那么
一旦用户到这个托盘图标操作了, windows就会自动给图标
属性对应的handle发送99999号消息, lparam为消息产生的原因.
如513=WM_LBUTTONDOWN.

vb不方便处理自定义消息. 如果需要, 则必须
用SetWindowLong来重新设置消息回掉过程, 比较麻烦.
这个技术在vb中叫做subclass.  但是, vb对一些常用的
消息进行了封状, 比如, 窗体这个类ThunderFormDC,
如果发现windows发送了WM_MOUSEMOVE消息, 并且你的程序代码写了
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

End Sub
这个函数, 那么就会去调用他. 其实, WM_MOUSEMOVE的消息原形是
LRESULT CALLBACK WindowProc(
  HWND hwnd,       // handle to window
  UINT uMsg,       // WM_MOUSEMOVE
  WPARAM wParam,   // key indicators
  LPARAM lParam    // horizontal and vertical position
);
可以知道, 对应shell_notifyicon发送过来的lParam, 实际上是放到
了水平垂直位置上, 其中, 由于刚说的数字比较小如513,  小于65535, 那么是放到lParam的第16位中,  再次参考msdn. 可知
lParam
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
低16位为x坐标,  那么shell_notifyiocn让系统发送的lparam
就存在了WM_MOUSEMOVE的x坐标中, 于是vb把他转换成single类型,
给我们放到了那个Form_MouseMove中的x里面了.
2007-1-14 17:30
0
雪    币: 26
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
Function Windproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

   Select Case Msg
     Case 9999
       Debug.Print Msg, wParam, lParam, hwnd
       If lParam = 513 Then Debug.Print "left down"
       If lParam = 514 Then Debug.Print "left up"
       If lParam = 516 Then Debug.Print "right down"
       If lParam = 517 Then Debug.Print "right up"
   End Select
   
    Windproc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End Function
谁能告诉我wParam参数是做什么用的呢?怎么用的呢?
2007-1-14 18:39
0
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
看来你什么都不懂。
建议看看《windows程序设计》
2007-1-15 17:54
0
雪    币: 26
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
请问:怎么使右击托盘图标弹出的菜单上有图标呢???
2007-1-17 20:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习+支持!  :)
2007-1-17 21:14
0
游客
登录 | 注册 方可回帖
返回
//