Option Explicit
#If Win64 Then
Private Const NULL_PTR = 0^
#Else
Private Const NULL_PTR = 0&
#End If
#If VBA7 Then
Private Declare PtrSafe Function SendInput Lib "USER32.DLL" (ByVal cInputs As Long, pInputs As Any, ByVal cbSize As Integer) As Long
Private Declare PtrSafe Function SetWinEventHook Lib "USER32.DLL" (ByVal eventMin As Long, ByVal eventMax As Long, ByVal hmodWinEventProc As Long, ByVal pfnWinEventProc As LongPtr, ByVal idProcess As Long, ByVal idThread As Long, ByVal dwFlags As Long) As LongPtr
Private Declare PtrSafe Function UnhookWinEvent Lib "USER32.DLL" (ByVal hWinEventHook As LongPtr) As Long
Private Declare PtrSafe Function AccessibleObjectFromEvent Lib "oleacc.dll" (ByVal hwnd As LongPtr, ByVal dwObjectId As Long, ByVal dwChildID As Long, ppacc As IAccessible, pVarChild As Variant) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hUF As LongPtr) As Long
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare PtrSafe Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As Any) As Long
Private Declare PtrSafe Function MoveWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare PtrSafe Function DwmGetWindowAttribute Lib "dwmapi.dll" (ByVal hwnd As LongPtr, ByVal dwAttribute As Long, ByRef pvAttribute As Any, ByVal cbAttribute As Long) As Long
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#Else
Private Enum LongPtr
[_]
End Enum
Private Declare Function SendInput Lib "USER32.DLL" (ByVal cInputs As Long, pInputs As Any, ByVal cbSize As Integer) As Long
Private Declare Function SetWinEventHook Lib "USER32.DLL" (ByVal eventMin As Long, ByVal eventMax As Long, ByVal hmodWinEventProc As Long, ByVal pfnWinEventProc As LongPtr, ByVal idProcess As Long, ByVal idThread As Long, ByVal dwFlags As Long) As LongPtr
Private Declare Function UnhookWinEvent Lib "USER32.DLL" (ByVal hWinEventHook As LongPtr) As Long
Private Declare Function AccessibleObjectFromEvent Lib "oleacc.dll" (ByVal hwnd As LongPtr, ByVal dwObjectId As Long, ByVal dwChildID As Long, ppacc As IAccessible, pVarChild As Variant) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hUF As LongPtr) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As LongPtr, lpRect As Any) As Long
Private Declare Function MoveWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Private Declare Function DwmGetWindowAttribute Lib "dwmapi.dll" (ByVal hwnd As LongPtr, ByVal dwAttribute As Long, ByRef pvAttribute As Any, ByVal cbAttribute As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#End If
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Type RECT
X As POINTAPI
Y As POINTAPI
End Type
Private Type KEYBDINPUT
wVk As Integer
wScan As Integer
dwFlags As Long
time As Long
dwExtraInfo As LongPtr
#If Win64 Then
padding As LongPtr
#End If
End Type
Private Type tagINPUT
INPUTTYPE As Long
ki As KEYBDINPUT
End Type
Private hClip As LongPtr, hEventHook As LongPtr
Private lLeft As Long, lTop As Long
Public Function DisplayWindowsClip( _
Optional ByVal ParentObject As Object, _
Optional ByVal X As Long = -1&, _
Optional ByVal Y As Long = -1& _
) As Boolean
Const SM_CXSCREEN = 0&, SM_CYSCREEN = 1&
Dim tRect As RECT, hParent As LongPtr
If Not ParentObject Is Nothing Then
Select Case True
Case TypeOf ParentObject Is Application
hParent = Application.hwnd
Case TypeOf ParentObject Is Worksheet
hParent = FindWindowEx(Application.hwnd, NULL_PTR, "XLDESK", vbNullString)
hParent = FindWindowEx(hParent, NULL_PTR, "EXCEL7", vbNullString)
Case TypeOf ParentObject Is UserForm
Call IUnknown_GetWindow(ParentObject, VarPtr(hParent))
Case Else
'Invalid Object Passed! Function Ret= False
Exit Function
End Select
If hParent Then
Call GetWindowRect(hParent, tRect)
If TypeOf ParentObject Is UserForm Then
tRect.X.X = tRect.X.X - (tRect.Y.X - tRect.X.X)
End If
End If
End If
If ParentObject Is Nothing Then
If X = -1& Then
tRect.X.X = (GetSystemMetrics(SM_CXSCREEN) - (GetSystemMetrics(SM_CXSCREEN) * 0.23)) / 2&
Else
tRect.X.X = X
End If
If Y = -1& Then
tRect.X.Y = (GetSystemMetrics(SM_CYSCREEN) - (GetSystemMetrics(SM_CXSCREEN) * 0.28)) / 2&
Else
tRect.X.Y = Y
End If
End If
Call SetClipPosition(tRect.X)
DisplayWindowsClip = True
End Function
' _______________________________________ PRIVATE ROUTINES ______________________________________
Private Sub SetClipPosition(ByRef Pos As POINTAPI)
lLeft = Pos.X: lTop = Pos.Y
Call StartEventHook
End Sub
Private Sub StartEventHook()
Const WINEVENT_SKIPOWNPROCESS = &H2, EVENT_OBJECT_UNCLOAKED = &H8018&
Const DWM_CLOAKED_SHELL = &H2, DWMWA_CLOAKED = 14&
Dim lpvAttribute As Long
If hEventHook = NULL_PTR Then
hEventHook = SetWinEventHook(EVENT_OBJECT_UNCLOAKED, EVENT_OBJECT_UNCLOAKED, 0&, _
AddressOf WinEventProc, 0&, 0&, WINEVENT_SKIPOWNPROCESS)
Call LaunchWindowsClipborad
Do
Call DwmGetWindowAttribute(hClip, DWMWA_CLOAKED, lpvAttribute, LenB(lpvAttribute))
DoEvents
Loop Until hClip And lpvAttribute = DWM_CLOAKED_SHELL
Call UnhookWinEvent(hEventHook): hEventHook = NULL_PTR: hClip = NULL_PTR
Debug.Print "Hook released."
End If
End Sub
Private Sub WinEventProc( _
ByVal HookId As LongPtr, _
ByVal LEvent As Long, _
ByVal hwnd As LongPtr, _
ByVal idObject As Long, _
ByVal idChild As Long, _
ByVal idEventThread As Long, _
ByVal dwmsEventTime As Long _
)
Const EVENT_OBJECT_UNCLOAKED = &H8018&, S_OK = 0&
Dim vChild As Variant, oAccDlg As IAccessible
Dim sBuffer As String * 256&, lRet As Long
On Error Resume Next
If LEvent = EVENT_OBJECT_UNCLOAKED Then
If AccessibleObjectFromEvent(hwnd, idObject, idChild, oAccDlg, vChild) = S_OK Then
lRet = GetClassName(hwnd, sBuffer, 256&)
If VBA.Left(sBuffer, lRet) = "ApplicationFrameWindow" Then
If FindWindowEx(hwnd, NULL_PTR, "Windows.UI.Core.CoreWindow", "Microsoft Text Input Application") Then
hClip = hwnd
Sleep 25&: DoEvents
Call MoveWindow(hwnd, lLeft, lTop, 0&, 0&, 0&)
End If
End If
End If
End If
End Sub
Private Sub LaunchWindowsClipborad()
Const KEYEVENTF_KEYUP = &H2, KEYEVENTF_UNICODE = &H4, VK_LMENU = &H5B
ReDim InputArray(4&) As tagINPUT
InputArray(0&).INPUTTYPE = 1&
InputArray(0&).ki.wVk = VK_LMENU
InputArray(0&).ki.dwFlags = KEYEVENTF_UNICODE
InputArray(1&).INPUTTYPE = 1&
InputArray(1&).ki.wVk = AscW("V")
InputArray(1&).ki.dwFlags = KEYEVENTF_UNICODE
InputArray(2&).INPUTTYPE = 1&
InputArray(2&).ki.wVk = VK_LMENU
InputArray(2&).ki.dwFlags = KEYEVENTF_UNICODE + KEYEVENTF_KEYUP
InputArray(3&).INPUTTYPE = 1&
InputArray(3&).ki.wVk = AscW("V")
InputArray(3&).ki.dwFlags = KEYEVENTF_UNICODE + KEYEVENTF_KEYUP
Call SendInput(4&, InputArray(0&), LenB(InputArray(0&)))
End Sub