Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Accessing Windows

Status
Not open for further replies.

ssmgr

Technical User
Feb 2, 2003
40
AU
A question for the windows gurus. Is there a way to interrogate windows to find out what windows are currently open?

If I know the title of a window, I can access it using the VBA.Appactivate method. However, what if I don't know it's title? Is there a way to obtain the title of all windows?
Any ideas would be welcome.

Steve
 
Hi, one way to do it is to use the EnumWindows API function
 
Steve - good question.

I've got a similar requirement. So I thought I'd piggy back onto yours and with a bit of luck some kind soul will...

I need to locate an open window with a known name. To be specific "New Message", being the title of a new Outlook Express message window before the subject line is filled.

I then need to locate child windows within that form in the order of; To: line, Subject: line and message body. For each of these child windows I need to send some text (typically from an Access97 module). If possible, when that's all done I'd like to either locate the Send button on the form and send a click to the button to send the email or switch to that window so the user can view the results and click Send.

The reason for all this is because the DoCmd.SendObject method to send an email from Access97 via the default mail client (Outlook Express in my case) does not work under Win2000 or XP. Nor does clicking on File/Send. MS security features in these later OSs refuse to allow access to the mail client.

However, you can open a new message window and if you manually switch to that window you can fill in the fields and send an email without a hitch. But I need to create an semi-automatic solution. Ergo I'm hoping to circumvent the problem by fooling XP into thinking that the operator is keying into Outlook Express directly.

I just yesterday bought a copy of Dan Appleman's Visual Basic Programmer's Guide to the Win32 API ... BUT its two and a half inches thick!! At my reading speed it'll be time for the 2008 Olympics before I get close. So come on all you API wizards show me how it's done - PLEASE.

Gratefull thanks - in anticipation.
Rod
 
tomreid: Can you be a little bit more specific please?

How do I access the "EnumWindows API function"? I found it in User32.dll, so I assume I need to declare the function within my code. What syntax, how do I call it and what does it return?

I don't have access to a decent reference book, so would really like to see a snippet of code so I can see how it flows. Can you help me out please?

Also interested in seeing the answer to Rod's question.

Steve
 
Hi Steve, et al,

check this site out:
This chap has done some sterling work explaining many API functions, although I don't seem to be able to get the EnumWindows and EnumChildWindows functions to work properly.
Probablly me.

I did get to flash a window's title bar. That was exciting for half a second.

Still hoping for a solution folks.

Rod
 
Rod,
That's a really good website, thanks for the info.

Now I have my next problem: I'm using Office97 VBA, (not VB) under Windows NT 4.0, and I can't get VBA to recognise the "Addressof" operator. I therefore can't run my callback function.

I've read that Addressof was added to VB in Version 5.0; does anyone know if it is supported in VBA (Office 97)?

If not, then I won't be able to use the Enumwindows function to find all open windows. Is there a way in VBA to access the TaskBar that lists all the processes running?

Steve

 
From MSDN,

"The EnumChildWindows function enumerates the child windows that belong to the specified parent window by passing the handle to each child window, in turn, to an application-defined callback function. EnumChildWindows continues until the last child window is enumerated or the callback function returns FALSE."

Use it like this.
The code below should print out all top-level window titles. For child windows you'd use enumchildwindows in a similar way.

Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lparam As Long) As Long

Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long

Public Function EnumWindowsProc1(ByVal hwnd As Long, ByVal lparam As Long) As Boolean
Dim ssave As String, ret As Long
ret = GetWindowTextLength(hwnd)
ssave = Space(ret)
GetWindowText hwnd, ssave, ret + 1
msgbox ssave
EnumWindowsProc1 = True
End If

End Function

'
' Call the above function like this
'
Sub printwindowtitles()

EnumWindows AddressOf EnumWindowsProc1, ByVal 0&

End Sub



Hope this help you. Cheers
 
Tomreid, thanks for the info, however since I'm using VBA (not VB), and VBA doesn't seem to have the Addressof operator, I can't use it.

I don't suppose you'd know if I can determine the memory address of my callback function any other way ....?
 
tomreid, thank you, it does indeed work. Now all I have to do is step through it and find out how ......

Thanks again.

Steve
 
In case anyone's interested, I found an easy way to get the open window captions without using a callback function at
I have adapted it to write the captions from all open windows to the active excel sheet:


----
Option Explicit

' Declarations
Private Const GW_CHILD = 5
Private Const GW_HWNDNEXT = 2

Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal _
wCmd 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 Sub getwindows()

Dim dhwnd As Long ' desktop window handle
Dim hwnd As Long ' window handle
Dim rval As Long ' return value
Dim wname As String ' window name
Dim i As Integer

dhwnd = GetDesktopWindow()
hwnd = GetWindow(dhwnd, GW_CHILD)

Range("a1").Activate
Do While hwnd <> 0
wname = Space(260)
rval = GetWindowText(hwnd, wname, 260)
wname = Left(wname, InStr(wname, Chr(0)) - 1)
If Len(wname) Then
ActiveCell.Value = wname
Activecell.Offset(1,0).Activate
End If
hwnd = GetWindow(hwnd, GW_HWNDNEXT)
Loop

End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top