Есть ли способ переопределить поведение курсора через winapi в VBA? - PullRequest
0 голосов
/ 25 марта 2019

Я хотел бы изменить изображение курсора во время работы моего макроса Excel. Мне удалось изменить курсор с помощью этих функций winapi: SetCursor и LoadCursorFromFileA .

Вот пример:

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

Однако курсор вернется к значению по умолчанию, если есть событие (например, диалоговое окно) или если курсор перемещен.

По этой ссылке кажется, что Excel обновляет курсор при наведении на элементы.

Я нашел решение , но он не позволяет моему макросу работать, потому что он использует бесконечный цикл.

Есть ли способ переопределить взаимодействие Excel с курсором?

1 Ответ

1 голос
/ 26 марта 2019

Это пример кода подкласса. В Excel Application.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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...