簡體   English   中英

是否可以通過 C# 在 Powerpoint Addin 中檢測撤消/重做?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM