|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Finding child? windowsHi all,
Sorry if this is very newbie. Despite a lot of info on the net I am having great difficulty with the following: I want to get a list of the open windows that are part of an application I am talking to. There seems to be no shortage of ways thru the WinAPI to do so, notably FindWindowEx and EnumChildWindows. So far, I have successful in retrieving the window handle of the main application. Being a relative novice to VB and esp. winAPI stuff, I got stuck when it comes to the listing the 'child' windows part. There is a lot of talk on 'callback' functions that I don't really understand. Any suggestions are appreciated. kind regards, arno To use an API function that provides callback functionality, you provide -
as one of the parameters to the callback-capable API call - the memory address of a function that you have defined in your application. Windows then uses this memory address (and thus, your provided function) to "call back" to your app to provide the information you requested. A callback function can be thought of as "here's what I want" (the type of data the API returns), and "here's where I want it put" (the address of the callback function). The memory address of your application-defined callback function is passed to the API using the AddressOf function introduced in VB5 and VB6 (note that VBA - the version of VB used by MS Office and some other commercial apps does not natively provide AddressOf, though this can be worked around). With real VB, your application-defined callback function must reside in a bas module. Furthermore, as Windows is passing data to the function the definition of your callback must adhere to the specifications expected by windows. You can name the callback anything you want as to Windows this is nothing more than a memory address. It is customary to use the name identified in the MSDN as this makes it clear to most what the purpose of a particular function is. In the case of EnumWindows, two pieces of data are passed back to the callback: the hwnd of the window being enumerated and an application-defined value that you assign when making the initial API call (more on this later). Because Windows may be calling this repeatedly (and very very rapidly), it is also customary to do a minimal amount of processing of the data Windows returns while inside the callback procedure. It is important to note that a callback function does not exist within Windows; that is, there is no API named EnumWindowsProc. Rather, The MSDN refers to the callback to EnumWindows as "EnumWindowsProc" in order to provide the required definition of the callback procedure that it expects when passing data to your app. The MSDN definition of EnumWindowsProc is: BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam ); .... which translates to VB code as: Public Function EnumWindowProc(ByVal hwnd As Long, _ ByVal lParam As Long) As Long The API (EnumWindows) is defined as: Declare Function EnumWindows Lib "user32" _ (ByVal lpEnumFunc As Long, _ ByVal lParam As Long) As Long .... and the calling syntax would be: Call EnumWindows(AddressOf EnumWindowProc, &H0) Call EnumWindows(AddressOf EnumWindowProc, &H0) Most callbacks have a short-circuit mechanism that allows you to stop the callback before all data has been received. This could be used, for example, when the data you've been expecting finally is provided and you don't need Windows to continue sending the callback further data. This short-circuiting is affected by setting the return value to the callback procedure. In the case of EnumWindowsProc, your application returns True to continue enumeration, or False to stop. (Remember that in C, True in defined as 1, not -1 - the value of VB's True constant. This may or may not make a difference to a call). So, to enumerate everything (all top-level windows) EnumWindowsProc returns 1... Public Function EnumWindowProc(ByVal hwnd As Long, _ ByVal lParam As Long) As Long <your code to handle the data returned to this function> EnumWindowProc = 1 End Function A function related to EnumWindows (the one you want) is called EnumChildWindows. EnumChildWindows also provides callback functionality through a callback defined and identified in the MSDN as "EnumChildProc": BOOL CALLBACK EnumChildProc( HWND hwnd, LPARAM lParam ); You'll see this definition matches the definition for EnumWindowsProc (the actual variable names are irrelevant to the code). So technically the callback you defined for EnumWindows could also be reused for EnumChildWindows. But personally, because you normally perform different actions on the data returned through callbacks depending on the API called, I find it easier to one define callback function for each individual API I use, rather than try to utilize the same callback function for multiple APIs (when all use the same definition, of course!) even when the definitions are identical. You can find an example of using both EnumWindows and EnumChildWindows in the demo at http://vbnet.mvps.org/code/enums/enumwindowsdemo.htm. There are a number of different APIs providing callback functionality on the parent index page http://vbnet.mvps.org/code/enums/. Or you could search for AddressOf on my site to see the list of 70 examples using this functionality. One caveat -- just because an API includes Enum in its name does not necessarily mean that API provides a callback. An example of this is EnumDisplayDevices -- this API needs to be repeatedly called in a loop with you (your app) incrementing a value in each subsequent call to get the next piece of information (see http://vbnet.mvps.org/code/enums/enumdisplaydevices.htm). ----------- With respect to a point I mentioned earlier, namely that some callbacks provide you to pass an application-defined value when making the initial API call --- consider EnumFontFamilies shown at http://vbnet.mvps.org/code/enums/enumfonts.htm. When calling this API, which does provide for a callback, the demo passes a list box as the application-defined value. This in turn is handed to the EnumFontFamProc routine where it is used to populate a list on the form without the necessity to use frmMain.List1.Additem directly. -- Show quoteHide quoteRandy Birch MS MVP Visual Basic http://vbnet.mvps.org/ Please reply to the newsgroups so all can participate. "arno" <rNOSPAMnospam@xs4all.nl> wrote in message news:2icp12lqhhft4cp8j4lvp3k4k7tpvi9bpt@4ax.com... : Hi all, : : Sorry if this is very newbie. Despite a lot of info on the net I am : having great difficulty with the following: : : I want to get a list of the open windows that are part of an : application I am talking to. There seems to be no shortage of ways : thru the WinAPI to do so, notably FindWindowEx and EnumChildWindows. : So far, I have successful in retrieving the window handle of the main : application. Being a relative novice to VB and esp. winAPI stuff, I : got stuck when it comes to the listing the 'child' windows part. There : is a lot of talk on 'callback' functions that I don't really : understand. Any suggestions are appreciated. : : kind regards, : arno Many thanks for your wealth of information. Very helpful indeed. I
feel confident I can get it done now. Thanks again arno On Sun, 19 Mar 2006 12:56:59 -0500, "Randy Birch" <rgb_removet***@mvps.org> wrote: Show quoteHide quote >To use an API function that provides callback functionality, you provide -
Microsoft SAPI 5.0 - Is there something better out there?
Adding MS Access type record navigation buttons to a form Find most similar filename Retval - Shell program run problem with parameters Sending Email with VB HiEdit Pro DAO Control Find Method VB6 keeps asking for VisualStudio 2005 DVD VB making a CSV from a filename Filling TreeView from directory |
|||||||||||||||||||||||