Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Win API / February 2008



Tip: Looking for answers? Try searching our database.

Finding open windows

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Juergen Grieb - 12 Feb 2008 14:00 GMT
Hi,

my Access app starts an instance of Word in an Acc97 form. So far I
have
complete control over Word, except in the circumstance that Word has
other "windows" (including dialogs like the printing dialog) open.

Searching the web I found no reliable way to get Word's status in case
another Word window is open. So I thought, that finding out if Word
has other windows open would be enough. Since I cannot get that
information from Word (it doesn't respond if a dialog is open) I
thought that API would do the trick.

Unfortunatly, I have no experience at all with API. FindWindowEx and
EnumChildWindows seems like what I need, but I wasn't able to figure
out how to use them to get the wanted information.

Can anybody please tell me how to get all open "windows" of an
existing Word instance?

Thanks a lot!

Juergen
Juergen Thuemmler - 12 Feb 2008 16:23 GMT
> Can anybody please tell me how to get all open "windows" of an
> existing Word instance?

When you have at least one window handle of this Word instance, you can use
"GetWindowThreadProcessId()" to get the ThreadID of Word and then
"EnumThreadWindows()" to get all other windows listed in the corresponding
callback function "EnumThreadWndProc()".

Juergen.
Juergen Grieb - 13 Feb 2008 06:54 GMT
> When you have at least one window handle of this Word instance, you can use
> "GetWindowThreadProcessId()" to get the ThreadID of Word and then
> "EnumThreadWindows()" to get all other windows listed in the corresponding
> callback function "EnumThreadWndProc()".

I have a window handle and was able to obtain the PID. Unfortunately,
I'm not able to get EnumThreadWindows to work with VBA:

Private Declare Function GetWindowThreadProcessId Lib
"user32.dll" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function EnumThreadWindows Lib "user32" (ByVal
dwThreadId As Long, ByVal lpfn As Long, ByVal lParam As Collection) As
Long

Private Function EnumThreadWndProc(ByVal hWnd As Long, ByVal Windows
As Collection) As Long
   Windows.Add hWnd
   EnumThreadWndProc = 1
End Function

Private Sub Irgendwas()
 Dim ret As Long
 Dim wrdPID As Long
 Dim Windows As Collection

 Set Windows = New Collection
 ret = GetWindowThreadProcessId(wrdHndl, wrdPID)
 ret = EnumThreadWindows(wrdPID, AddrOf("EnumThreadWndProc"),
Windows)
End Sub

I get no error, but my collection is empty all the time. Any
suggestions?

Juergen
Juergen Thuemmler - 13 Feb 2008 08:37 GMT
> I have a window handle and was able to obtain the PID. Unfortunately,
> I'm not able to get EnumThreadWindows to work with VBA:

Put the following code into a new VB project module, enter a valid window
handle in Sub Main and run the project.

Juergen.

Option Explicit

Declare Function GetWindowThreadProcessId& Lib "user32" (ByVal Hwnd&,
lpdwProcessId&)
Declare Function EnumThreadWindows& Lib "user32" (ByVal dwThreadId&, ByVal
lpfn&, ByVal lParam&)
Declare Function GetClassName& Lib "user32" Alias "GetClassNameA" (ByVal
Hwnd&, ByVal lpClassName$, ByVal nMaxCount&)

Sub Main()
Dim Hwnd&, TID&, PID&
Hwnd = 394550  '<<<<<< Must be a valid Handle #########
TID = GetWindowThreadProcessId(Hwnd, PID)
Call EnumThreadWindows(TID, AddressOf ThreadWndProc, 0)
End Sub

Public Function ThreadWndProc&(ByVal Hwnd&, ByVal dl&)
Debug.Print Hwnd, WindowClass(Hwnd)
ThreadWndProc = 1
End Function

Function WindowClass$(ByVal Hwnd&)
Dim tbuf$, dl&

tbuf = String$(256, 0)
dl = GetClassName(Hwnd, tbuf, 255)
If dl > 0 Then WindowClass = LCase$(Left$(tbuf, dl))
End Function
Juergen Grieb - 13 Feb 2008 09:21 GMT
> Put the following code into a new VB project module, enter a valid window
> handle in Sub Main and run the project.

Thanks for your help!

Your code crashes Access badly. I don't use VB but VBA. There is no
AddressOf in VBA but I use:

Public Function AddrOf(strFuncName As String) As Long
   Dim hProject As Long
   Dim lngResult As Long
   Dim strID As String
   Dim lpfn As Long
   Dim strFuncNameUnicode As String

   Const NO_ERROR = 0
   Call GetCurrentVbaProject(hProject)
  If hProject <> 0 Then
       lngResult = GetFuncID(hProject, strFuncNameUnicode, strID)
       If lngResult = NO_ERROR Then
            lngResult = GetAddr(hProject, strID, lpfn)
           If lngResult = NO_ERROR Then
               AddrOf = lpfn
           End If
       End If
   End If
End Function

Do you have any idea what the problem could be?

Juergen
NeilH - 13 Feb 2008 09:28 GMT
> > Put the following code into a new VB project module, enter a valid window
> > handle in Sub Main and run the project.
[quoted text clipped - 27 lines]
>
> Juergen

Yes, very simply problem!
You are in the WRONG newsgroup!
You need a VBA newsgroup, not a VB group.
Juergen Thuemmler - 13 Feb 2008 09:52 GMT
> Your code crashes Access badly. I don't use VB but VBA. There is no
> AddressOf in VBA but I use:
<...>
>    Call GetCurrentVbaProject(hProject)
>    lngResult = GetFuncID(hProject, strFuncNameUnicode, strID)
>    lngResult = GetAddr(hProject, strID, lpfn)

Sorry, but I don't know the functions you use...My knowledge about VBA is
very poor.

Juergen.
Vinchenzo vinç - 16 Feb 2008 11:32 GMT
>> Put the following code into a new VB project module, enter a valid window
>> handle in Sub Main and run the project.
[quoted text clipped - 25 lines]
>
> Do you have any idea what the problem could be?

   Yes, Juergen, the problem is related to WinAPI, but take into account that not all people knows about Kaplan-Getz AddrOf "workaround", and can seems a VBA problem.

   The problem is your function call to EnumThreadWindows:

'*************
 ret = GetWindowThreadProcessId(wrdHndl, wrdPID)
 ret = EnumThreadWindows(wrdPID, AddrOf("EnumThreadWndProc"), Windows)
'*************

   GetWindowThreadProcessId returns the identifier of the thread, and this is the value that you need to pass to EnumThreadWindows instead of the process id 'wrdPID' (look twice at the "Sub Main" that Thuemmler has already posted). Then for instance, your calls should be:

'------------------------
···
Dim wrdThreadID As Long

···
wrdThreadID = GetWindowsThreadProcessId(wrdHndl, 0&) 'Actually, you don't need the ProcID
EnumThreadWindows wrdThreadID, AddrOf("EnumThreadWndProc"), Windows
···
'------------------------

Signature

   Regards
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Preceding answers in Google:
   http://groups.google.com/group/microsoft.public.vb.winapi
( i ) Temperance in the forum:
   http://www.microsoft.com/communities/conduct/default.mspx
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.