Re: Are VBA userforms always child of Windows desktop?



Looks like I may need to read the Appleman API book about this.
I only need this Hwnd of the parent (that seems to be the right word in this case), owner whatever to
use as the first argument (hwndParent) in FindWindowEx, to get the Hwnd of the Userform.
I have now used the Hwnd of the Windows desktop, the Active workbook and the Excel application
for this argument and they all work, so it doesn't seems to matter much.

RBS


"Peter T" <peter_t@discussions> wrote in message news:%238Q0NlSpHHA.3644@xxxxxxxxxxxxxxxxxxxxxxx
Not sure so sure now what the parent window is.

I think there's a difference between Parent, as in Parent/Child, and Owner
(as in belongs to) windows, though they can be the same. I might be wrong in
my way of thinking but I use the GetParent API to get 'owner' and the
GetAncestor API (with GA_PARENT) to get Parent.

I've always found the Parent of a Userform is the Desktop but its Owner is
the XLMAIN window (assuming the Userform is being run in Excel VBA).

I suppose which window you need will depend on the overall objective.

Regards,
Peter T

"RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx> wrote in message
news:eB9pVSSpHHA.3512@xxxxxxxxxxxxxxxxxxxxxxx
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


"Peter T" <peter_t@discussions> wrote in message
news:enwrKDRpHHA.3952@xxxxxxxxxxxxxxxxxxxxxxx
> Hi Bart,
>
> Whenever I've looked, which is not that often, the Userform's window's
> parent has always been the Desktop. But to check perhaps -
>
> Private Declare Function FindWindowA Lib "user32" ( _
> ByVal lpClassName As String, ByVal lpWindowName As String) As Long
>
> Private Declare Function GetAncestor Lib "user32.dll" ( _
> ByVal hwnd As Long, ByVal gaFlags As Long) As Long
>
> Private Declare Function GetDesktopWindow Lib "user32" () As Long
> Const GA_PARENT = 1
>
> Private Sub UserForm_Activate()
> Dim hwnMe&, hwnParent&, hwnDesktop&
>
> hwnMe = FindWindowA("ThunderDFrame", Me.Caption)
> hwnParent = GetAncestor(hwnMe, GA_PARENT)
> hwnDesktop = GetDesktopWindow
> MsgBox hwnMe & vbCr & hwnParent & vbCr & hwnDesktop
>
> End Sub
>
>> as I know I can alter the parent window of a form.
>
> 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 ?
>
> Regards,
> Peter T
>
>
> "RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx> wrote in message
> news:eQzW7SQpHHA.4112@xxxxxxxxxxxxxxxxxxxxxxx
>> Had a look at some code in the the book of Bullen et Al, Professional
> Excel
>> Development.
>> I thought that it was suggested that VBA Userforms are the children of
>> the
>> Excel
>> desktop window, but it appears that this is not the case and that >> these
>> windows are the
>> direct children of the Windows desktop.
>> Is this always the case?
>> I am interested in this as I need the form's hwnd.
>> I used to do this with the FindWindow API and this only needs the
form's
>> class name
>> (ThunderDFrame or ThunderXFrame) and the form's caption.
>> Possibly it is faster (not tested yet) to get this hwnd with the
>> FindWindowEx API, but then
>> I need to know for sure that the Windows desktop is indeed always the
> parent
>> of this form.
>> This is directly after the window is created as I know I can alter the
>> parent window of a form.
>> Thanks for any advice/insight.
>>
>> RBS
>>
>
>




.



Relevant Pages

  • Re: Creating new appointment & setting its properties
    ... The window and process subclassing I've seen with WordMail is horrendous, it's miles of code just to get a true hWnd for a WordMail window usually. ... Private Declare Function GetForegroundWindow Lib "User32.dll" As Long ... Private Declare Function FindWindowEx Lib "User32.dll" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long ...
    (microsoft.public.outlook.program_vba)
  • Re: Are VBA userforms always child of Windows desktop?
    ... Private Declare Function GetDesktopWindow Lib "user32" As Long ... Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long ... The system restores the window to its original state. ... Dim hWndDesktop As Long ...
    (microsoft.public.excel.programming)
  • re: Get the list of applications which are running
    ... Private Declare Function GetDesktopWindow Lib "user32" ... Alias "GetWindowLongA" (ByVal hwnd As Long, ... As String, ByVal cch As Long) As Long ... ' - An integer array used to return the window handles ...
    (microsoft.public.excel.programming)
  • Re: Name Box
    ... (ByVal hwnd As Long, _ ... Private Declare Function GetDesktopWindow Lib "user32" As Long ... ' Get the ID of the process that a window belongs to ...
    (microsoft.public.excel.worksheet.functions)
  • Re: Trying to return a child handle using FindWindowEx
    ... The owner of a window is not necessarily the parent of ... But returns 0 when starting from the parent. ... Private Declare Function apiGetDesktopWindow Lib "user32" Alias ...
    (microsoft.public.vb.winapi)

Loading