前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >问题探讨01: 如何使用鼠标滚轮使单元格中的数值增减?

问题探讨01: 如何使用鼠标滚轮使单元格中的数值增减?

作者头像
fanjy
发布2020-04-01 17:19:57
1.8K0
发布2020-04-01 17:19:57
举报
文章被收录于专栏:完美Excel完美Excel

学习Excel技术,关注微信公众号:

excelperfect

问题:前不久,有个网友给我提了个问题要我帮助解决。这个问题是,在某单元格中有一个数字,当鼠标滚轮向上滚动时该单元格中的数字以0.01的间隔增加,向下滚动时以0.01的间隔减少?

探讨

很显然,这需要使用Windows API来捕获鼠标事件。说实话,我对Windows API研究不深,于是上网查了一下,根据查找的一些资料整理了一段代码:

代码语言:javascript
复制
Public hHook As LongPtr
 
#If VBA7 Then
    PublicDeclare PtrSafe Function SetWindowsHookEx Lib "user32" Alias"SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As LongPtr,ByVal hmod As LongPtr, ByVal dwThreadId As Long) As LongPtr
    PublicDeclare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hhkAs LongPtr) As Long
    PublicDeclare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook AsLongPtr, ByVal ncode As Long, ByVal wParam As LongPtr, lParam As Any) AsLongPtr
    PublicDeclare PtrSafe Function GetCurrentThreadId Lib "kernel32" () As Long
#End If
 
Public Const WH_MOUSE = 7
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_MOUSEWHEEL = &H20A
 
Sub BeginHK()
    '获取当前的线程ID
    i =GetCurrentThreadId
    '这里安装的是键盘钩子
    hHook =SetWindowsHookEx(WH_MOUSE, AddressOf HookProc, 0, i)
End Sub
 
'Hook程序
Public Function HookProc(ByVal code As Long, ByValwParam As Long, ByVal lParam As Long) As LongPtr
    Dimwks  As Worksheet
    Set wks =Excel.ActiveSheet
   
    '如果code参数<0,则一定要返回CallNextHookEx函数的返回值
    If code< 0 Then
       HookProc = CallNextHookEx(hHook, code, wParam, lParam)
    Else
        SelectCase wParam
            '按下鼠标右键,则退出
            Case WM_RBUTTONDOWN
               EndHK
            '使用鼠标滚轮
           Case WM_MOUSEWHEEL
               wks.Range("B2").Value = wks.Range("B2").Value + 0.01
        EndSelect
       '如果要拦截处理消息,则HookProc函数的返回值一定要是非0,不然会陷入死循环
       HookProc = 1
    End If
End Function
 
Sub EndHK()
   UnhookWindowsHookEx hHook
End Sub

但是,这段代码只能实现单元格中的数值随着滑动鼠标滚轮不断增加0.01,无论向前滚动还是向后滚动,如下图1所示。(注:可按鼠标右键退出程序)

图1

我想要的是,当鼠标滚轮向前滚动时,单元格中的数值增加0.01,向后滚动时,减少0.01。

于是,继续上网搜索资料,终于查到一段:

  • 我们知道VB应用程序响应的Windows传来的消息,需要通过VB解释。可是很不幸,虽然VB解释所有的消息,却只让用户程序在事件中处理部分消息,VB自己处理其他的消息,或者忽略这些消息。
  • 在VB5.0以前应用程序无法越过VB直接处理消息,微软从VB5.0开始提供AddressOf 运算符,该运算符可以让用户程序将函数或者过程的地址传递给一个API函数。这样我们就可以在VB应用程序中编写自己的窗口处理函数,通过AddressOf 运算符将在VB中定义的窗口地址传递给窗口处理函数,从而绕过VB的解释器,自己处理消息。事实上,该方法可用于在VB中处理任何消息。
  • 实现应用程序支持鼠标滚轮的关键是,捕获鼠标滚轮的消息 MSH_MOUSEWHEEL、WM_MOUSEWHEEL。其中MSH_MOUSEWHEEL是为95准备的,需要Intellimouse驱动程序,而WM_MOUSEWHEEL是目前各版本Windows(98/NT40/2000)内置的消息。下面是WM_MOUSEWHEEL的语法。

WM_MOUSEWHEEL

fwKeys = LOWORD(wParam); /* key flags */

zDelta = (short) HIWORD(wParam);

/* wheel rotation */

xPos = (short) LOWORD(lParam);

/* horizontal position of pointer */

yPos = (short) HIWORD(lParam);

/* vertical position of pointer */

  • 其中:fwKeys指出是否有CTRL、SHIFT、鼠标键(左、中、右、附加)按下,允许复合。zDelta传递滚轮滚动的快慢,该值小于零表示滚轮向后滚动(朝用户方向),大于零表示滚轮向前滚动(朝显示器方向)。lParam指出鼠标指针相对屏幕左上的x、y轴坐标。
  • 滚轮按钮相当于普通的三键鼠标的中键,根据滚轮按钮的动作,Windows分别发出WM_MBUTTONUP、WM_MBUTTONDOWN、WM_MBUTTONDBLCLK消息,这些消息VB已经在鼠标事件中支持。

但是,当我使用HIWORD(wParam)时,程序却崩溃了!有没有哪位朋友在这方面有研究的,可否指教一下:如何捕捉鼠标滚轮的向前或向后滚动?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 完美Excel 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档