hatman
Well-known Member
- Joined
- Apr 8, 2005
- Messages
- 2,664
So I have a solution that works (though it isn't quite as bullet-proof as I would like). What I am interested in is an explanation why NONE of the seemingly more bullet-proof solutions work.
In controlling Excel from a VB 6.0 application, at some point, the user can display the Format Axis dialog of the Excel instance, which is done programmatically using the Dialogs().Show method. The problem comes in where I need to halt the recalculation before the dialog is displayed, and resume recalc after it is manually closed. Oh, and the user may have other instances of the Excel Application open, not under of the VB 6.0 application. To do this, i need teh HWND of the Format Axis window, then periodically monitor it unil it is closed.
My first approach was to use the HWND of the XLMAIN window to find the appropriate child window. But after 3 different methods (some of which I later read in various articles actually call EnumWindows in teh background anyway, so perhaps they aren't as unique as I thought) I determined that the Format Axis window isn't visible as a child. WHY NOT???
The FindWindow function works to find the most recently created inistance of the window, which is probably fine, since it gets called immediately after the instance I am looking for is created, making it extremely unlikely to get stuck with the wrong instance.
In controlling Excel from a VB 6.0 application, at some point, the user can display the Format Axis dialog of the Excel instance, which is done programmatically using the Dialogs().Show method. The problem comes in where I need to halt the recalculation before the dialog is displayed, and resume recalc after it is manually closed. Oh, and the user may have other instances of the Excel Application open, not under of the VB 6.0 application. To do this, i need teh HWND of the Format Axis window, then periodically monitor it unil it is closed.
My first approach was to use the HWND of the XLMAIN window to find the appropriate child window. But after 3 different methods (some of which I later read in various articles actually call EnumWindows in teh background anyway, so perhaps they aren't as unique as I thought) I determined that the Format Axis window isn't visible as a child. WHY NOT???
The FindWindow function works to find the most recently created inistance of the window, which is probably fine, since it gets called immediately after the instance I am looking for is created, making it extremely unlikely to get stuck with the wrong instance.
Code:
Option Explicit
Private Declare Function EnumChildWindows _
Lib "user32" _
(ByVal hWndParent As Long, _
ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long
Public Declare Function GetClassName _
Lib "user32" Alias "GetClassNameA" _
(ByVal hwnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
Public Declare Function GetWindowText _
Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
Public Declare Function GetWindowTextLength _
Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long
Public Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Public Declare Function GetParent _
Lib "user32.dll" _
(ByVal hwnd As Long) As Long
Public Declare Function FindWindowX _
Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, _
ByVal hWnd2 As Long, _
ByVal lpsz1 As Long, _
ByVal lpsz2 As Long) As Long
Public Declare Function GetWindow _
Lib "user32" _
(ByVal hwnd As Long, _
ByVal wCmd As Long) As Long
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2
Private Const GW_HWNDPREV = 3
Dim windows() As Long
Dim windowsCount As Long
Sub Compare_Them_All()
Sheet3.Rows.Clear
Chart4.Activate
Chart4.Axes(xlPrimary).Select
Application.Dialogs(xlDialogFormatLegend).Show
Call EnumWindow_Method
Call FindWindowX_Method
Call FindWindow_Method
Call GetWindow_Method
End Sub
Sub EnumWindow_Method()
Dim a() As Long
Dim cnt As Long
Dim sClass As String
Dim getwindowclass As String
Dim ControlText As String
sClass = Space$(256)
GetClassName Application.hwnd, sClass, 255
getwindowclass = Left$(sClass, InStr(sClass, vbNullChar) - 1)
ControlText = String(GetWindowTextLength(Application.hwnd) + 1, Chr$(0))
GetWindowText Application.hwnd, ControlText, Len(ControlText)
Sheet3.Range("A1").Value = Application.hwnd
Sheet3.Range("B1").Value = getwindowclass
Sheet3.Range("C1").Value = ControlText
a = ChildWindows(Application.hwnd)
For cnt = 1 To UBound(a, 1)
sClass = Space$(256)
GetClassName a(cnt), sClass, 255
getwindowclass = Left$(sClass, InStr(sClass, vbNullChar) - 1)
ControlText = String(GetWindowTextLength(a(cnt)) + 1, Chr$(0))
GetWindowText a(cnt), ControlText, Len(ControlText)
Sheet3.Range("A" & cnt + 1).Value = a(cnt)
Sheet3.Range("B" & cnt + 1).Value = getwindowclass
Sheet3.Range("C" & cnt + 1).Value = ControlText
Next cnt
End Sub
Function ChildWindows(ByVal hwnd As Long) As Long()
windowsCount = 0
EnumChildWindows hwnd, AddressOf EnumWindows_CBK, 1
ReDim Preserve windows(windowsCount) As Long
ChildWindows = windows()
End Function
Private Function EnumWindows_CBK(ByVal hwnd As Long, ByVal lParam As Long) As Long
If windowsCount = 0 Then
ReDim windows(100) As Long
ElseIf windowsCount >= UBound(windows) Then
ReDim Preserve windows(windowsCount + 100) As Long
End If
windowsCount = windowsCount + 1
windows(windowsCount) = hwnd
EnumWindows_CBK = 1
End Function
Sub FindWindowX_Method()
Dim hChild As Long
Dim cnt As Long
Dim sClass As String
Dim getwindowclass As String
Dim ControlText As String
hChild = FindWindowX(Application.hwnd, 0, 0, 0)
cnt = 2
Do
sClass = Space$(256)
GetClassName hChild, sClass, 255
getwindowclass = Left$(sClass, InStr(sClass, vbNullChar) - 1)
ControlText = String(GetWindowTextLength(hChild) + 1, Chr$(0))
GetWindowText hChild, ControlText, Len(ControlText)
Sheet3.Range("E" & cnt).Value = hChild
Sheet3.Range("F" & cnt).Value = getwindowclass
Sheet3.Range("G" & cnt).Value = ControlText
hChild = FindWindowX(Application.hwnd, hChild, 0, 0)
cnt = cnt + 1
Loop Until hChild = 0
End Sub
Sub FindWindow_Method()
Dim DialogHwnd As Long
Dim parent_h As Long
Dim sClass As String
Dim getwindowclass As String
Dim ControlText As String
'this one only gets the MOST RECENT instance.
DialogHwnd = FindWindow("NUIDialog", "Format Axis")
parent_h = GetParent(DialogHwnd)
sClass = Space$(256)
GetClassName DialogHwnd, sClass, 255
getwindowclass = Left$(sClass, InStr(sClass, vbNullChar) - 1)
ControlText = String(GetWindowTextLength(DialogHwnd) + 1, Chr$(0))
GetWindowText DialogHwnd, ControlText, Len(ControlText)
Sheet3.Range("M2").Value = DialogHwnd
Sheet3.Range("N2").Value = getwindowclass
Sheet3.Range("O2").Value = ControlText
sClass = Space$(256)
GetClassName parent_h, sClass, 255
getwindowclass = Left$(sClass, InStr(sClass, vbNullChar) - 1)
ControlText = String(GetWindowTextLength(parent_h) + 1, Chr$(0))
GetWindowText parent_h, ControlText, Len(ControlText)
Sheet3.Range("M1").Value = parent_h
Sheet3.Range("N1").Value = getwindowclass
Sheet3.Range("O1").Value = ControlText
End Sub
Sub GetWindow_Method()
Dim lngSrch As Long
Dim ControlText As String
Dim sClass As String
Dim getwindowclass As String
Dim cnt As Integer
lngSrch = Application.hwnd
lngSrch = GetWindow(lngSrch, GW_CHILD)
cnt = 2
Do
lngSrch = GetWindow(lngSrch, GW_HWNDNEXT)
If lngSrch = 0 Then
Exit Do
End If
ControlText = String(GetWindowTextLength(lngSrch) + 1, Chr$(0))
GetWindowText lngSrch, ControlText, Len(ControlText)
sClass = Space$(256)
GetClassName lngSrch, sClass, 255
getwindowclass = Left$(sClass, InStr(sClass, vbNullChar) - 1)
Sheet3.Range("I" & cnt).Value = lngSrch
Sheet3.Range("J" & cnt).Value = getwindowclass
Sheet3.Range("K" & cnt).Value = ControlText
cnt = cnt + 1
Loop
End Sub