有没有一种方法可以通过VBA中的winapi覆盖游标行为?

时间:2019-03-25 17:52:04

标签: excel vba winapi

我想在我的excel宏运行时更改光标图像。我设法通过以下winapi函数来更改光标:SetCursorLoadCursorFromFileA

这里是一个例子:

Option Explicit

Declare Function LoadCursorFromFileA Lib "user32" (ByVal lpFileName As String) As Long
Declare Function SetCursor Lib "user32" (ByVal hCursor As Long) As Long

Sub TestCursor()
     Call SetCursor(LoadCursorFromFileA("C:\Temp\cursor2.cur"))
    ' Waits 5 seconds, any movement of the mouse will revert the cursor back to default
    Application.Wait Now + TimeValue("00:00:05")
    ' Cursor is back to default at the end of the sub
End Sub

但是,如果发生事件(如对话框窗口)或移动了光标,则光标会变回默认值。

this link看来,Excel悬停在元素上时会更新光标。

我发现了一个solution,但由于它使用了无限循环,因此阻止了我的宏运行。

有没有一种方法可以替代Excel与光标的交互方式?

1 个答案:

答案 0 :(得分:1)

这是一些示例子类化代码。在Excel Application.hWnd中具有您想要的hWnd。

Public Const WM_SETCURSOR = &H20

收到上述消息后,返回True(-1)以停止光标的进一步更改。

gWindowProc = true

Public Sub Hook()
   lpPrevWndProc = SetWindowLong(EditNote.gRtfHwnd, GWL_WNDPROC, _
   AddressOf gWindowProc)
End Sub

Public Sub Unhook()
   Dim temp As Long
   temp = SetWindowLong(EditNote.gRtfHwnd, GWL_WNDPROC, lpPrevWndProc)
End Sub

Public Function gWindowProc(ByVal hwnd As Long, ByVal Msg As Long, _
                 ByVal wParam As Long, ByVal lParam As Long) As Long
   If Msg = WM_CONTEXTMENU Then
        If EditNote.mnuViewEditContextMenu.Checked Then EditNote.PopupMenu EditNote.mnuEdit
'        gWindowProc = CallWindowProc(lpPrevWndProc, hWnd, Msg, wParam, _
         lParam)
   Else ' Send all other messages to the default message handler
      gWindowProc = CallWindowProc(lpPrevWndProc, hwnd, Msg, wParam, _
         lParam)
   End If
End Function
  

备注

     

当窗口进入菜单模式时,lParam的高位字为零。   DefWindowProc函数将WM_SETCURSOR消息传递给父级   窗口处理之前。如果父窗口返回TRUE,则进一步   处理被暂停。将消息传递到窗口的父窗口   使父窗口可以控制子窗口中光标的设置   窗口。 DefWindowProc函数还使用此消息来设置   如果它不在客户区中,则将光标移至箭头,或者将光标移至   注册的类光标(如果它在客户区域中)。如果低阶   lParam参数的单词为HTERROR,而高阶单词为   lParam指定按下鼠标键之一,   DefWindowProc调用MessageBeep函数。

MSDN 2001