Click here to Skip to main content
15,040,212 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
By way of background I am trying to add UIAutomation support for VB6 applications and have reached an impasse. I have written several UIAutomation providers in C++ that invoke control methods to provide the necessary control and query functions and have added code to the VB6 app in the main exe and each dll that registers the exe or dll with a central uiprovider factory that uses the control hWnds and classnames to attach a provider to the control. SOme VB6 controls can be serviced by the default Win32 providers already built in to UiAutomation but not all. Unfortunately the default automationid is not set in for form windows and is the control id for controls and VB6 dynamically allocates the ids sequentially using the defined order within the parent form. When a control is added tit is placed at the head of the list so changing all other control ids on the form thus requiring any uiautomation references to require changing as well.

By creating my own providers and gaining access to the application forms and controls I am able to change this so that the control "names" are the automation id instead and and I can use the control interfaces to access and drive control attributes. To do this I need to be able to map window handles to the associated VB6 controls.

From my initial reading of the VB6 documentation I believed that the global "Forms" collection would allow me to enumerate "ALL" active forms within an application but this appears not to be true, each dll/ocx seems to have its own independent form collection but this was easy to work around by getting each dll/ocx and the exe to register with my provider factory. Then I can enumerate controls on a form to execute the search for a given window handle and provide an enumerator for forms/controls. At this point I hit the problem of UserControls, See simplified code below which illustrates the problem, real code has error handling to cater for windowless controls and thse which do not expose their window handle as a property.

Function SearchForm(theForm as Form, long hWnd) As Object
Dim theControl as Control

For Each theControl In theForm.Controls ' Iterate over controls on Form
If theControl.hWnd = hWnd Then
SearchForm = theControl ' If found target return it
Exit For
else If IsUserControl(theControl) Then ' Uses test windows classname because TypeOf
' does not work
Dim theUserControl As UserControl
Dim theResult As Control
' ********
Set theUserControl = theControl ' If we have found a UserControl search it
' This Set Fails even if Control is
' referencing a UserControl
' for same reason I cannot use TypeOf to detect
' user controls.
' **********
Set theResult = Search(theUserControl, hWnd) ' recursive search UserControl child
' controls
If Not theResult Is Nothing Then
Set SearchForm = theResult
Exit For
End If
End If
Next theControl
End Function

I have extracted the type info of various VB6 entities and tried to solve this in C++ but it appears that controls do not allow access to the _UserControl interface via QueryInterface().

Also the typeinfo retrieved from VB6.OLB seems strange and calling exposed methods often crashes or returns odd data, it is like the typeinfo does not reflect the actual implementation.

Does anyone have a better solution for mapping hWnds to VB6 controls or know how to switch from "Control" to "UserControl" in order to enumerate its children?

Thanks Andy Hitchins
Updated 27-May-14 21:47pm
karthik Udhayakumar 27-May-14 14:48pm
Interesting ,can you pls use the improve question widget and produce your code and where you are facing a issue?
Anthoner Monzon 28-Jan-15 1:52am
Hi, I'm also interested on this especially the windowless part, which has no window handle. hope there is an solution for this one. Thank you in advance
Member 10982768 26-Sep-18 2:32am
Hi, this is what I am trying to do at the moment? Anybody?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900