Jaafar Tribak
Well-known Member
- Joined
- Dec 5, 2002
- Messages
- 9,621
- Office Version
- 2016
- Platform
- Windows
Hi all,
Just wanted to share this little known API function for those who need to retrieve the Window handle (hwnd) of a userform.
As you all know, the standard approach is to use the FindWindow API but this has two awkward issues :
1- The first argument of the FindWindow API expects the UserForm Window Class name . This adds complexity to the code because there are two different Class names (ThunderXFrame vs ThunderDFrame) depending on the excel application version ...So an extra check is needed.
2 - The FindWindow function expects the Form's Caption to be passed in its second argument . This too, may cause a problem if there happens to be more than one instance of a userform loaded @ the same time with the same Caption.
Fortunately, there is this handy API that I came accross recently called IUnknown_GetWindow which dispenses us from the two problems mentioned above and is very simple . This API is exported by its ordinal number by the shlwapi library.
The API has two parameters : An IN parameter that receives a pointer to userform object and an OUT parameter that returns a pointer to the hwnd.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb773814(v=vs.85).aspx
Usage Example:
One would expect to use this neat API to get the much needed hwnd of a workbook window .. Unfortunately, this is not true. This API function seems to only work with a limted number of COM Interfaces .
Just wanted to share this little known API function for those who need to retrieve the Window handle (hwnd) of a userform.
As you all know, the standard approach is to use the FindWindow API but this has two awkward issues :
Code:
[COLOR=#000000]Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long[/COLOR]
1- The first argument of the FindWindow API expects the UserForm Window Class name . This adds complexity to the code because there are two different Class names (ThunderXFrame vs ThunderDFrame) depending on the excel application version ...So an extra check is needed.
2 - The FindWindow function expects the Form's Caption to be passed in its second argument . This too, may cause a problem if there happens to be more than one instance of a userform loaded @ the same time with the same Caption.
Fortunately, there is this handy API that I came accross recently called IUnknown_GetWindow which dispenses us from the two problems mentioned above and is very simple . This API is exported by its ordinal number by the shlwapi library.
The API has two parameters : An IN parameter that receives a pointer to userform object and an OUT parameter that returns a pointer to the hwnd.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb773814(v=vs.85).aspx
Usage Example:
Code:
Option Explicit
#If Win64 Then
Private Declare PtrSafe Function IUnknown_GetWindow Lib _
"shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hwnd As LongPtr) As Long
#Else
Private Declare Function IUnknown_GetWindow Lib _
"shlwapi" Alias "#172" (ByVal pIUnk As IUnknown, ByVal hwnd As Long) As Long
#End If
Public Function GetUserformHwnd(ByVal ufmTarget As MSForms.UserForm) As Long
IUnknown_GetWindow ufmTarget, VarPtr(GetUserformHwnd)
End Function
Sub Test()
Dim ufm1 As UserForm1
Dim ufm2 As UserForm1
Dim lngUserform As Long
Set ufm1 = New UserForm1
Set ufm2 = New UserForm1
For lngUserform = 0 To UserForms.Count - 1
Debug.Print GetUserformHwnd(UserForms(lngUserform))
Next lngUserform
End Sub
One would expect to use this neat API to get the much needed hwnd of a workbook window .. Unfortunately, this is not true. This API function seems to only work with a limted number of COM Interfaces .
Last edited: