Hi Peter,
Not sure so sure now what the parent window is.
Spy++ always says it is the Windows desktop, but
running this code makes me doubt now:
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function GetWindowThreadProcessId _
Lib "user32" _
(ByVal hwnd As Long, _
ByRef lpdwProcessId As Long) As Long
Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As String, _
ByVal lpsz2 As String) As Long
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" _
Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
Private lExcelHwnd As Long
Function GetExcelHwnd() As Long
'---------------------------------------------------------
'Finds a top-level window of the given class and
'caption that belongs to this instance of Excel,
'by matching the process IDs
'sClass The window class name to look for
'sCaption The window caption to look for
'Returns: Long The handle of Excel's main window
'---------------------------------------------------------
Dim hWndDesktop As Long
Dim hwnd As Long
Dim hProcThis As Long
Dim hProcWindow As Long
Dim sClass As String
Dim sCaption As String
If Val(Application.Version) >= 10 Then
GetExcelHwnd = Application.hwnd
Exit Function
End If
sClass = "XLMAIN"
sCaption = Application.Caption
'All top-level windows are children of the desktop,
'so get that handle first
hWndDesktop = GetDesktopWindow 'isn't this always 0?
'Get the ID of this instance of Excel, to match
hProcThis = GetCurrentProcessId
Do
'Find the next child window of the desktop that
'matches the given window class and/or caption.
'The first time in, hWnd will be zero, so we'll get
'the first matching window. Each call will pass the
'handle of the window we found the last time, thereby
'getting the next one (if any)
hwnd = FindWindowEx(hWndDesktop, hwnd, sClass, sCaption)
'Get the ID of the process that owns the window we found
GetWindowThreadProcessId hwnd, hProcWindow
'Loop until the window's process matches this process,
'or we didn't find the window
Loop Until hProcWindow = hProcThis Or hwnd = 0
GetExcelHwnd = hwnd
End Function
Function GetUserFormHwnd(strWindowCaption As String) As Long
Dim strFormType As String
'Determine the form type
If Val(Application.Version) >= 9 Then
strFormType = "ThunderDFrame"
Else
strFormType = "ThunderXFrame"
End If
'Find the userform window
GetUserFormHwnd = FindWindowEx(GetDesktopWindow, 0, _
strFormType, strWindowCaption)
End Function
Function GetWorkbookHwnd(lXLHwnd As Long, _
strWindowCaption As String) As Long
Dim lHwndXLDesk As Long
If lXLHwnd = 0 Then
lXLHwnd = GetExcelHwnd()
lExcelHwnd = lXLHwnd
End If
'Find the Excel desktop
lHwndXLDesk = FindWindowEx(lXLHwnd, 0, "XLDESK", vbNullString)
'Find the Workbook window
GetWorkbookHwnd = FindWindowEx(lHwndXLDesk, 0, _
"EXCEL7", strWindowCaption)
End Function
Sub test()
Dim lHwnd As Long
Dim lHwndParent As Long
Dim lHwndDesktop As Long
Dim lHwndWorkbook As Long
Dim MyStr As String
MyStr = String(100, Chr$(0))
Load UserForm1
UserForm1.Show 0
lExcelHwnd = GetExcelHwnd()
lHwnd = GetUserFormHwnd(UserForm1.Caption)
lHwndParent = GetParent(lHwnd)
lHwndDesktop = GetDesktopWindow()
lHwndWorkbook = GetWorkbookHwnd(lExcelHwnd, ThisWorkbook.Name)
GetWindowText lHwndParent, MyStr, 100
MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
MsgBox "Hwnd of the userform: " & lHwnd & vbCrLf & _
"Hwnd of the Windows desktop: " & lHwndDesktop & vbCrLf & _
"Hwnd of the parent of the userform: " & lHwndParent & vbCrLf & _
"Hwnd of the active workbook: " & lHwndWorkbook & vbCrLf & _
"Text of the parent window: " & MyStr, , _
"windows related to this userform"
End Sub
Do you know if it's possible to make a borderless/captionless VB6 form the
child of a userform, so it will remain withing the userform
I would think so, but will need to test.
RBS