[英]Is is possible to detect Undo/Redo in a Powerpoint Addin via C#?
是否可以通過 C# 檢測 Powerpoint 插件中的撤消/重做事件? 或者是否可以訪問發生的事情或操作撤消/重做列表?
我問是因為我沒有看到任何允許這樣做的東西,這讓我感到驚訝,我期待它成為可能,所以我問的主要是希望我錯過了一些東西。
任何幫助將非常感激!
不幸的是,PPT沒有公開撤銷列表,並且沒有任何事件可以讓你知道撤消/重做何時發生。
我想有可能實現你自己的撤銷堆棧,但這似乎是斯蒂芬金將寫小說的東西。 ;-)
我也在尋找 Ctrl+Z/Undo 的事件。 Undo 功能的 idMso 控件是一個畫廊,因此在通過 customUI 中的 a 重新調整用途方面這是一個死胡同。 沒有內置的 Application.OnUndo 事件,我能想到的唯一其他事情是使用 WinAPI 掛鈎到 PowerPoint 的 WindowProc 過程以檢測 Ctrl+Z。 我簡單地嘗試了一下,可以檢測到那個組合鍵,但我鄙視這種事情導致的不穩定,導致 PowerPoint 在某些系統上可能崩潰,而且它沒有解決 macOS。 如果有人想要改進它,這是該技術的基礎:
Option Explicit
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As LongPtr
Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Function RegisterHotKey Lib "user32" (ByVal hwnd As LongPtr, ByVal ID As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Private Declare PtrSafe Function UnregisterHotKey Lib "user32" (ByVal hwnd As LongPtr, ByVal ID As Long) As Long
Private Declare PtrSafe Function CallWindowProc Lib "user32" Alias "CallWindowProcA" ( _
ByVal lpPrevWndFunc As LongPtr, _
ByVal hwnd As LongPtr, _
ByVal MSG As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr
Public hWndPPT As LongPtr
Public Type POINTAPI
x As Long
y As Long
End Type
Public Type MSG
hwnd As LongPtr
Message As Long
wParam As LongPtr
lParam As LongPtr
time As Long
PT As POINTAPI
End Type
#If Win64 Then
Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
Private Const GWL_WNDPROC As Long = -4& ' Sets a new address for the window procedure
Private PrevWndFunc As LongPtr ' Pointer to the initial window proc
Private Const WM_HOTKEY = &H312& ' HotKey message
Private Const MOD_Control = 2 ' Either CTRL key
Public Sub RegisterCtrlZ()
Dim returnedVal
hWndPPT = GetPPThWnd
returnedVal = RegisterHotKey(hwnd:=hWndPPT, ID:=1, fsModifiers:=MOD_Control, vk:=vbKeyZ)
Debug.Print "RegisterHotKey returned " & returnedVal
' Set the window callback procedure
PrevWndFunc = SetWindowLongPtr(hWndPPT, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub UnregisterCtrlZ()
Dim returnedVal
hWndPPT = GetPPThWnd
returnedVal = UnregisterHotKey(hwnd:=hWndPPT, ID:=1)
Debug.Print "UnregisterHotKey returned " & returnedVal
PrevWndFunc = SetWindowLongPtr(hWndPPT, GWL_WNDPROC, PrevWndFunc)
End Sub
Public Function WindowProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
' Check if a hotkey and the main PPT window is the active window
If uMsg = WM_HOTKEY And GetActiveWindow = hWndPPT Then
Debug.Print "Hotkey " & wParam & " event (Ctrl+Z)"
End If
' Call the next window proc
WindowProc = CallWindowProc(PrevWndFunc, hwnd, uMsg, wParam, lParam)
End Function
' Get the handle for the PowerPoint window
Public Function GetPPThWnd() As LongPtr
Select Case Val(Application.Version)
Case 8
GetPPThWnd = FindWindow("PP97FrameClass", 0&)
Case 9 To 12
GetPPThWnd = FindWindow("PP" & Val(Application.Version) & "FrameClass", 0&)
Case Else
GetPPThWnd = FindWindow("PPTFrameClass", vbNullString)
End Select
End Function
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.