Re: Are VBA userforms always child of Windows desktop?
- From: "RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx>
- Date: Sat, 2 Jun 2007 17:12:17 +0100
One (final?) thing about this.
If I run the following code (from a button in the worksheet) directly after moving from the VBE to
the worksheet then the form doesn't flash. If I then run it again it will flash. Any idea what that is?
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 Const GA_PARENT As Long = 1
Private Const GA_ROOT As Long = 2
Private Const GA_ROOTOWNER As Long = 3
Private Declare Function GetAncestor Lib "user32.dll" _
(ByVal hwnd As Long, _
ByVal gaFlags As Long) As Long
'Stop flashing. The system restores the window to its original state.
Const FLASHW_STOP = 0
Const FLASHW_CAPTION = &H1 'Flash the window caption.
Const FLASHW_TRAY = &H2 'Flash the taskbar button.
'Flash both the window caption and taskbar button.
'This is equivalent to setting the FLASHW_CAPTION Or FLASHW_TRAY flags.
Const FLASHW_ALL = (FLASHW_CAPTION Or FLASHW_TRAY)
'Flash continuously, until the FLASHW_STOP flag is set.
Const FLASHW_TIMER = &H4
'Flash continuously until the window comes to the foreground.
Const FLASHW_TIMERNOFG = &HC
Private Type FLASHWINFO
cbSize As Long
hwnd As Long
dwFlags As Long
uCount As Long
dwTimeout As Long
End Type
Private Declare Function FlashWindowEx Lib "user32" _
(pfwi As FLASHWINFO) As Boolean
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, _
Optional lParentHwnd As Long = -1) As Long
Dim strFormType As String
Dim lStartWindowHwnd As Long
'Determine the form type
If Val(Application.Version) >= 9 Then
strFormType = "ThunderDFrame"
Else
strFormType = "ThunderXFrame"
End If
If lParentHwnd = -1 Then
lStartWindowHwnd = GetDesktopWindow()
End If
'Find the userform window
GetUserFormHwnd = FindWindowEx(lStartWindowHwnd, 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 lHwndUserForm As Long
Dim lHwndParent As Long
Dim lHwndDesktop As Long
Dim lHwndWorkbook As Long
Dim lHwndGetAncestorGA_PARENT As Long
Dim lHwndGetAncestorGA_ROOT As Long
Dim lHwndGetAncestorGA_ROOTOWNER As Long
Dim MyStr As String
Dim FlashInfo As FLASHWINFO
MyStr = String(100, Chr$(0))
Load UserForm1
UserForm1.Show
If lExcelHwnd = 0 Then
lExcelHwnd = GetExcelHwnd()
End If
lHwndWorkbook = GetWorkbookHwnd(lExcelHwnd, ThisWorkbook.Name)
lHwndUserForm = GetUserFormHwnd(UserForm1.Caption, lExcelHwnd)
lHwndParent = GetParent(lHwndUserForm)
'lHwndUserForm = GetUserFormHwnd(UserForm1.Caption, lHwndParent)
lHwndDesktop = GetDesktopWindow()
lHwndGetAncestorGA_PARENT = GetAncestor(lHwndUserForm, GA_PARENT)
lHwndGetAncestorGA_ROOT = GetAncestor(lHwndUserForm, GA_ROOT)
lHwndGetAncestorGA_ROOTOWNER = GetAncestor(lHwndUserForm, GA_ROOTOWNER)
GetWindowText lHwndParent, MyStr, 100
MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
MsgBox "Hwnd of the Excel application: " & lExcelHwnd & vbCrLf & _
"Hwnd of the userform: " & lHwndUserForm & vbCrLf & _
"Hwnd of the Windows desktop: " & lHwndDesktop & vbCrLf & _
"Hwnd of the parent (GetParent API) of the userform: " & lHwndParent & _
vbCrLf & _
"Hwnd of the active workbook: " & lHwndWorkbook & vbCrLf & vbCrLf & _
"Text of the parent window: " & MyStr & vbCrLf & vbCrLf & _
"Hwnd obtained with GetAncestor with GA_PARENT: " & _
lHwndGetAncestorGA_PARENT & vbCrLf & _
"Hwnd obtained with GetAncestor with GA_ROOT: " & _
lHwndGetAncestorGA_ROOT & vbCrLf & _
"Hwnd obtained with GetAncestor with GA_ROOTOWNER: " & _
lHwndGetAncestorGA_ROOTOWNER, , _
"windows related to this userform"
'Specifies the size of the structure.
FlashInfo.cbSize = Len(FlashInfo)
'Specifies the flash status
FlashInfo.dwFlags = FLASHW_ALL Or FLASHW_TIMER
'Specifies the rate, in milliseconds, at which the window will be flashed.
'If dwTimeout is zero, the function uses the default cursor blink rate.
FlashInfo.dwTimeout = 0
'Handle to the window to be flashed.
'The window can be either opened or minimized.
FlashInfo.hwnd = lHwndUserForm
'Specifies the number of times to flash the window.
FlashInfo.uCount = 3
'just to make sure we got the right Hwnd
'---------------------------------------
FlashWindowEx FlashInfo
End Sub
RBS
"Peter T" <peter_t@discussions> wrote in message news:OPsBpzSpHHA.4552@xxxxxxxxxxxxxxxxxxxxxxx
The one in my first post <g>
hwnMe = FindWindowA("ThunderDFrame", Me.Caption)
or with your code -
lHwnd_Userform = FindWindow("ThunderDFrame", Userform1.Caption) ' xl9 or
later
Regards,
Peter T
"RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx> wrote in message
news:eBzDttSpHHA.3944@xxxxxxxxxxxxxxxxxxxxxxx
> the simple one-liner failparticularly
Which one-liner is that Peter?
RBS
"Peter T" <peter_t@discussions> wrote in message
news:uZNYdqSpHHA.1216@xxxxxxxxxxxxxxxxxxxxxxx
>> In any case it always seems to find the right Hwnd of the Userform.
>
> Why might the simple one-liner fail to find the correct Hwnd,
> if the Userform's caption is temporarily changed to something unique.
>
> Regards,
> Peter T
>
> <snip>
>
>
.
- References:
- Are VBA userforms always child of Windows desktop?
- From: RB Smissaert
- Re: Are VBA userforms always child of Windows desktop?
- From: Peter T
- Re: Are VBA userforms always child of Windows desktop?
- From: RB Smissaert
- Re: Are VBA userforms always child of Windows desktop?
- From: Peter T
- Re: Are VBA userforms always child of Windows desktop?
- From: RB Smissaert
- Re: Are VBA userforms always child of Windows desktop?
- From: Peter T
- Are VBA userforms always child of Windows desktop?
- Prev by Date: Re: Multiply range values with Lookup-value?
- Next by Date: Re: Are VBA userforms always child of Windows desktop?
- Previous by thread: Re: Are VBA userforms always child of Windows desktop?
- Next by thread: Re: Are VBA userforms always child of Windows desktop?
- Index(es):
Relevant Pages
|