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 IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hUF As LongPtr) As Long
Private Declare PtrSafe Function IIDFromString Lib "ole32.dll" (ByVal lpsz As LongPtr, ByVal lpiid As LongPtr) As LongPtr
Private Declare PtrSafe Function ObjectFromLresult Lib "oleacc" (ByVal lResult As LongPtr, ByVal riid As LongPtr, ByVal wParam As LongPtr, ppvObject As Any) As Long
Private Declare PtrSafe Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As LongPtr, ByVal wFlag As Long) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As Long
#Else
Private Enum LongPtr
[_]
End Enum
Private Declare Function IUnknown_GetWindow Lib "shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hUF As LongPtr) As Long
Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpsz As LongPtr, ByVal lpiid As LongPtr) As LongPtr
Private Declare Function ObjectFromLresult Lib "oleacc" (ByVal lResult As LongPtr, ByVal riid As LongPtr, ByVal wParam As LongPtr, ppvObject As Any) As Long
Private Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As LongPtr, ByVal wFlag As Long) As LongPtr
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As Long
#End If
Public Sub Show_Form( _
ByVal UserForm As MSForms.UserForm, _
ByVal Modal As Boolean, _
Optional ByVal FormAlreadyActivated As Boolean = False _
)
Dim hwnd As LongPtr
Call IUnknown_GetWindow(UserForm, VarPtr(hwnd))
Set UserForm = HwndToDispatch(hwnd)
With UserForm
.Tag = IIf(FormAlreadyActivated, "Activated", "")
.StartUpPosition = -(Not FormAlreadyActivated)
.Hide
.Show -Modal
End With
End Sub
Private Function HwndToDispatch(ByVal hwnd As LongPtr) As MSForms.UserForm
Const WM_GETOBJECT = &H3D&, OBJID_CLIENT = &HFFFFFFFC
Const GW_CHILD = 5&, S_OK = 0&
Const IID_IDISPATCH = "{00020400-0000-0000-C000-000000000046}"
Dim oDisp As MSForms.UserForm
Dim hClient As LongPtr, lResult As Long
Dim tGUID(0& To 3&) As Long
hClient = GetNextWindow(hwnd, GW_CHILD)
lResult = SendMessage(hClient, WM_GETOBJECT, NULL_PTR, ByVal OBJID_CLIENT)
If lResult Then
If IIDFromString(StrPtr(IID_IDISPATCH), VarPtr(tGUID(0&))) = S_OK Then
If ObjectFromLresult(lResult, VarPtr(tGUID(0&)), NULL_PTR, oDisp) = S_OK Then
If Not oDisp Is Nothing Then
Set HwndToDispatch = oDisp
End If
End If
End If
End If
End Function