Question

Controlling 3rd Party Application

Asked by: revstudio

I am using EnumWindows and EnumChildWindows to get the handles of all running applications.

Say I am looking for a specific ClassName(CN) or MainWindowTitle(MWT) and once I find it I want to iterate through the controls of that specific form. How can I do this?

Basically what I am looking to do is launch an application, wait for the CN or MWT to show up, change the selection in a specific dropdown combo box, click a button (which launches a new form), wait for its CN or MWT to show up, fill in a few textboxes, and click another button.

I obviously don't expect all that code, but if I can get the control handles and maybe an example of how to do any function (click a button) I should be able to figure out the rest.

I tried uploading a 2MB .Zip file of my project but needless to say just about every file extension wasn't in the list.

Added a .JPG, thought it might help. The code snippet is what populates 'Form1' of the .JPG

    Private Sub RadButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton1.Click
 
        Dim winEnum As New WindowsEnumerator
        Dim winList As New System.Collections.Generic.List(Of WindowsEnumTest.ApiWindow)
        Dim childList As New System.Collections.Generic.List(Of WindowsEnumTest.ApiWindow)
 
        winList = winEnum.GetTopLevelWindows()
 
        RadTextBox1.Clear()
        RadTextBox2.Clear()
        RadTextBox3.Clear()
 
        For Each apiWin As WindowsEnumTest.ApiWindow In winList
            RadTextBox1.Text += apiWin.MainWindowTitle + vbCrLf
            RadTextBox2.Text += apiWin.ClassName + vbCrLf
 
            childList = winEnum.GetChildWindows(apiWin.hWnd)
 
            For Each apiChild As WindowsEnumTest.ApiWindow In childList
                RadTextBox3.Text += apiWin.MainWindowTitle + ":" + apiChild.MainWindowTitle + vbCrLf
 
            Next
        Next
 
    End Sub

                                  
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:

Select allOpen in new window

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-07-03 at 08:14:44ID24542516
Topic

Microsoft Visual Basic.Net

Participating Experts
1
Points
500
Comments
20

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. Form, Form1 and TextBox
    1. Form, Form1 and TextBox are all classes. 2. Form is the class of Form1. 3. For any class, we can do Dim objectName As className Set objectName = New className 4. But why I can do that only with From1?
  2. EnumWindows????
    I use EnumWindows with a callback function, when I check the returned HWND(s) with ISWindow? I get false!!!!!! Can you tell me why I hear no Beep here? function CallBackFun(H:LongWord; A:Integer):Boolean; begin Form1.Memo1.Lines.Add(IntToStr(H)); If IsWindow(H) then Be...
  3. Iterating through dir of JPG file displaying each in turn
    I have a program that records up to 10 JPG files per second to a directory, the files are sequentially named by date, time and millisecond, i.e.: pic 17 24 55 23.jpg pic 17 24 55 53.jpg pic 17 24 56 27.jpg basically I have an ActiveX control with a SetImage method to displ...
  4. EnumWindows
    Could anyone give me an example on how to use EnumWindows? For example i would like to get the names of all windows and put them in a memo. Thanks in advance!
  5. Get main forms Classname starting from only the path to the…
    Hi, i wonder if it's possible to get the classname of the window when u only have the path to the exe to start with ? I was thinking like something like letting it run hidden, get it's classname from the main form of the application (the exe). Only problem is i have no cl...
  6. List all applications using EnumWindows in .NET
    After doing research I've found that process.GetProcessesByName("") will only display active processes. I need to list all processes. How do I list all processes using EnumWindows in .NET

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: Idle_MindPosted on 2009-07-03 at 09:25:35ID: 24773307

Did you get the WindowsEnumerator code from here?
http://kellychronicles.spaces.live.com/blog/cns!A0D71E1614E8DBF8!217.entry

If YOU are starting the application then simply pass the MainWindowHandle() property to the GetChildWindows() function:

        Dim P As Process = Process.Start("calc")
        P.WaitForInputIdle()

        Dim childList As System.Collections.Generic.List(Of WindowsEnumTest.ApiWindow)
        childList = winEnum.GetChildWindows(P.MainWindowHandle.ToInt32) ' <--- using our instance of Process called "P"
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            RadTextBox3.Text += apiWin.MainWindowTitle + ":" + apiChild.MainWindowTitle + vbCrLf
        Next

To click a button, you could use:

    Private Const WM_LBUTTONDOWN As Integer = &H201
    Private Const BM_SETSTATE As Integer = &HF3
    Private Const BM_CLICK As Integer = &HF5
    Private Const WM_LBUTTONUP As Integer = &H202
 
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal parent As IntPtr, ByVal child As IntPtr, _
        ByVal className As String, ByVal caption As String) As IntPtr
 
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, _
         ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
    Private Sub ClickButton(ByVal handle As IntPtr)
        Call SendMessage(handle, WM_LBUTTONDOWN, 0, 0)
        Call SendMessage(handle, BM_SETSTATE, 1, 0)
        Call SendMessage(handle, BM_CLICK, 0, 0)
        Call SendMessage(handle, WM_LBUTTONUP, 0, 0)
    End Sub

 

by: revstudioPosted on 2009-07-03 at 09:58:26ID: 24773452

Based on your code snippet I created the following snippet, however no controls were returned.

Private Sub RadButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton1.Click
 
        Dim winEnum As New WindowsEnumerator
        Dim childList As New System.Collections.Generic.List(Of WindowsEnumTest.ApiWindow)
 
        RadTextBox3.Clear()
 
        Dim p As Process = Process.Start("C:\Program Files\3Shape\ScanItLegato\Scanit.exe")
        p.WaitForInputIdle()
 
        childList = winEnum.GetChildWindows(p.MainWindowHandle.ToInt32)
 
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            RadTextBox3.Text += p.MainWindowTitle + ":" + _
                apiChild.MainWindowTitle + ":" + apiChild.ClassName + _
                ":" + apiChild.hWnd.ToString + vbNewLine
        Next
    End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:

Select allOpen in new window

 

by: revstudioPosted on 2009-07-03 at 11:45:37ID: 24773885

Oddly enough, I can change the process that I start to another application like "notepad.exe" and it does return controls :(

 

by: Idle_MindPosted on 2009-07-03 at 13:47:54ID: 24774333

Use Spy++ or the free WinSpector to explore the application further:
http://www.windows-spy.com/

Do you get separate windows with these tools?  Probably not.  If this is the case then your options become much more limited!

Options?...
(1) Use a possibly less reliable automation process by injecting keystrokes.  This could be simply like using SendKeys.Send() or more sophisticated with SendMessage() or SendInput().
(2) Use some kind of framework provided by "ScanIt".  Is there an API, COM interface, ActiveX control etc?...
(3) Does the app allow any kind of automation via command-line switches?

 

by: Idle_MindPosted on 2009-07-03 at 13:48:20ID: 24774337

Can you post a screenshot of the application running?

 

by: revstudioPosted on 2009-07-06 at 09:18:42ID: 24786665

Here is a screenshot of the application running, as well as Winspector's findings. The document also includes explanations of the steps I need to take.

Thanks in advance.

 

by: revstudioPosted on 2009-07-06 at 10:47:38ID: 24787498

A little more info...

This application AutoIT, actually show's where I click within the Toolbar), but I'm still getting more and more confused as I get deeper and deeper.

 

by: Idle_MindPosted on 2009-07-06 at 11:35:50ID: 24787928

The standard .Net Toolstrip also has Buttons on it where each Button does NOT have its own handle so I've tested with that.

The example below clicks at the point (45, 10) relative to the ToolStrip upper left corner.  This clicked on the second button in my screenshot.

So all you need to do is figure out the handle to the ToolBar in your external app and then figure out the correct "offset" coords to click on:

Public Class Form1
 
    Private Sub ToolStripButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click
        MessageBox.Show("ToolStripButton 1")
    End Sub
 
    Private Sub ToolStripButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton2.Click
        MessageBox.Show("ToolStripButton 2")
    End Sub
 
    Private Sub ToolStripButton3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton3.Click
        MessageBox.Show("ToolStripButton 1")
    End Sub
 
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
    Private Const WM_LBUTTONUP As Integer = &H202
    Private Const WM_LBUTTONDOWN As Integer = &H201
 
    Private Sub LeftClickAt(ByVal handle As IntPtr, ByVal OffsetPt As Point)
        If Not handle.Equals(IntPtr.Zero) Then
            Dim coords As Integer = CombineCoords(OffsetPt.X, OffsetPt.Y)
            Call SendMessage(handle, WM_LBUTTONDOWN, 0, coords)
            Call SendMessage(handle, WM_LBUTTONUP, 0, coords)
        End If
    End Sub
 
    Private Function CombineCoords(ByVal X As Integer, ByVal Y As Integer) As Integer
        Return X + Y * 65536
    End Function
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        LeftClickAt(Me.ToolStrip1.Handle, New Point(45, 10))
    End Sub
 
End Class
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:

Select allOpen in new window

 

by: revstudioPosted on 2009-07-06 at 11:52:10ID: 24788075

You are the man.
Can you give me one example of sending text to a textbox :)

 

by: Idle_MindPosted on 2009-07-06 at 12:05:30ID: 24788200

 

by: revstudioPosted on 2009-07-06 at 12:16:31ID: 24788324

Thank you I'll take a look at your other post.

I noticed that when executing the code below that my application behaves as if RadButton3.Click is still "active" or in process. Is this normal behavior?

   Private Sub RadButton2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton2.Click
 
        RadTextBox3.Clear()
        RadTextBox4.Clear()
 
        winList = winEnum.GetTopLevelWindows("TShapeItMainForm.UnicodeClass")
 
        For Each apiWin As WindowsEnumTest.ApiWindow In winList
 
            childList = winEnum.GetChildWindows(apiWin.hWnd)
 
            For Each apiChild As WindowsEnumTest.ApiWindow In childList
                If apiChild.MainWindowTitle = "Toolbar3Shape3" And apiChild.ClassName = "TdfToolbar97.UnicodeClass" Then
                    GlobHwnd = apiChild.hWnd
                End If
            Next
        Next
    End Sub
 
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
    Private Const WM_LBUTTONUP As Integer = &H202
    Private Const WM_LBUTTONDOWN As Integer = &H201
    Private Const WM_SETTEXT = &HC
 
    Private Sub LeftClickAt(ByVal handle As IntPtr, ByVal OffsetPt As Point)
        If Not handle.Equals(IntPtr.Zero) Then
            Dim coords As Integer = CombineCoords(OffsetPt.X, OffsetPt.Y)
            Call SendMessage(handle, WM_LBUTTONDOWN, 0, coords)
            Call SendMessage(handle, WM_LBUTTONUP, 0, coords)
        End If
    End Sub
 
    Private Function CombineCoords(ByVal X As Integer, ByVal Y As Integer) As Integer
        Return X + Y * 65536
    End Function
 
    Private Sub RadButton3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton3.Click
        LeftClickAt(GlobHwnd, New Point(100, 25))
    End Sub
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:

Select allOpen in new window

 

by: Idle_MindPosted on 2009-07-06 at 12:22:06ID: 24788367

Most likely...since we are not giving focus to other control and also we have not physically moved the mouse over it so probably won't get any visual feedback off of it.

 

by: revstudioPosted on 2009-07-06 at 12:39:24ID: 24788511

Ok,

I'm going to award you the points but figured I'd ask a few more questions (on topic) if you don't mind.

Once I have the next form opened. I need to put some data in the text boxes. However, as I look at the Winspector information on the text boxes they all have the same ClassName and no MainWindowTitle. How do I figure out which text box is the one I am looking for?  Or would you like me to ask as another question :)

Look at the .JPG. I am looking for the TCompactEdit.UnicodeClass that is expanded.

 

by: Idle_MindPosted on 2009-07-06 at 12:51:00ID: 24788622

When you have more than one control of the same type (classname) then you can make multiple calls to FindWindowEx() to get the correct one:

    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal parent As IntPtr, ByVal child As IntPtr, _
        ByVal className As String, ByVal caption As String) As IntPtr

So...

(1) Get a handle to the TdfInfoGroup.UnicodeClass "Order" control either using your enumerator code or thru FindWindow()/FindWindowEx():

    Handle1 = somehow get the root window handle...    

(2) Pass handle #1 to FindWindowEx() to get the TdfInfoPanel control:

    Handle2 = FindWindowEx(Handle1, IntPtr.Zero, "TdInfopanel", Nothing)

(3) Get a handle to the First TdInfoRow:

    Handle3 = FindWindowEx(Handle2, IntPtr.Zero, "TdInfoRow", Nothing)

(4) Pass Handle3 as the "child" using Handle2 as the parent to get the Second TdInfoRow:

    Handle4 = FindWindowEx(Handle2, Handle3, "TdInfoRow", Nothing)

I coded this in the browser but I'm pretty sure it's correct.

 

by: Idle_MindPosted on 2009-07-06 at 12:53:17ID: 24788640

Oops, forgot step #5...

(5) Pass Handle4 to get the final control:

    Handle5 = FindWindowEx(Handle4, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)

Now Handle5 should point to your desired control.

 

by: revstudioPosted on 2009-07-06 at 13:35:54ID: 24788999

Thanks for Step #5, I noticed it was missing but followed your example and figured the last step out.

The main issue I am having now is with calling the other form up.Once it is up using "LeftClickAt" the calling application is stuck waiting for LeftClickAt to return. I added a message box and it won't display until I close the form we called with LeftClickAt. So needless to say I can't interact with the form any further. Any suggestions?

 

by: Idle_MindPosted on 2009-07-06 at 13:41:36ID: 24789042

Try using PostMessage() instead of SendMessage():

    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

 

by: revstudioPosted on 2009-07-07 at 07:11:31ID: 24794364

The PostMessage() worked much better.

I had to use a combination of the EnumWindows, EnumChildWindows, and FindWindowsEx to accomplish it but your help was invaluable.

Here's the code I ended up with:

RadButton4_Click sends text to a control nested...

Form, Panel, Panel, Panel, Group, Group, Group, Group, Panel, Row, Row, Edit (Order No)

I included RadButton5_Click because it was the other fields I needed to populate and the way they were nested I had to use a slightly different approach and thought it might be helpful to someone in the future.
RadButton5_Click sends text to a control nested...

Form, Panel, Panel, Panel, Group, Group, Group, Panel, Row, Row, Row, Row, Row, Edit (Last Name), Row, Edit (First Name)

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
Private Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" _
    (ByVal handle As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
 
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
        (ByVal handle As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
 
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal parent As IntPtr, ByVal child As IntPtr, ByVal className As String, ByVal caption As String) As IntPtr
 
Private Const WM_LBUTTONUP As Integer = &H202
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_SETTEXT = &HC
 
Private Sub RadButton4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton4.Click
 
        Dim Handle1, Handle2, Handle3, Handle4, Handle5, Handle6 As Integer
        Dim GroupCount As Integer = 0
 
        winList.Clear()
        childList.Clear()
 
        winList = winEnum.GetTopLevelWindows("TShowShellManagerOrderForm.UnicodeClass")
 
        For Each apiWin As WindowsEnumTest.ApiWindow In winList
 
            childList = winEnum.GetChildWindows(apiWin.hWnd)
 
            For Each apiChild As WindowsEnumTest.ApiWindow In childList
                If apiChild.ClassName = "TdfInfoPanel" Then
                    If GroupCount = 2 Then
                        Handle1 = apiChild.hWnd
                    End If
                    GroupCount += 1
                End If
 
            Next
        Next
 
        GroupCount = 0
        childList.Clear()
        childList = winEnum.GetChildWindows(Handle1)
 
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            If apiChild.ClassName = "TdfInfoGroup.UnicodeClass" Then
                If GroupCount = 3 Then
                    Handle2 = apiChild.hWnd
                End If
                GroupCount += 1
            End If
 
        Next
 
        Handle3 = FindWindowEx(Handle2, IntPtr.Zero, "TdfInfoPanel", Nothing)
        Handle4 = FindWindowEx(Handle3, IntPtr.Zero, "TdfInfoRow", Nothing)
        Handle5 = FindWindowEx(Handle3, Handle4, "TdfInfoRow", Nothing)
        Handle6 = FindWindowEx(Handle5, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)
 
        Call SendMessageByString(Handle6, WM_SETTEXT, 0, "1000001")
 
    End Sub
 
    Private Sub RadButton5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton5.Click
 
        Dim Handle1, Handle2, Handle3, Handle4, Handle5, Handle6, Handle7 As Integer
        Dim GroupCount As Integer = 0
 
        winList.Clear()
        childList.Clear()
 
        winList = winEnum.GetTopLevelWindows("TShowShellManagerOrderForm.UnicodeClass")
 
        For Each apiWin As WindowsEnumTest.ApiWindow In winList
 
            childList = winEnum.GetChildWindows(apiWin.hWnd)
 
            For Each apiChild As WindowsEnumTest.ApiWindow In childList
                If apiChild.ClassName = "TdfInfoPanel" Then
                    If GroupCount = 2 Then
                        Handle1 = apiChild.hWnd
                    End If
                    GroupCount += 1
                End If
 
            Next
        Next
 
        GroupCount = 0
        childList.Clear()
        childList = winEnum.GetChildWindows(Handle1)
 
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            If apiChild.ClassName = "TdfInfoGroup.UnicodeClass" Then
                If GroupCount = 2 Then
                    Handle2 = apiChild.hWnd
                End If
                GroupCount += 1
            End If
 
        Next
 
        Handle3 = FindWindowEx(Handle2, IntPtr.Zero, "TdfInfoPanel", Nothing)
 
        GroupCount = 0
        childList.Clear()
        childList = winEnum.GetChildWindows(Handle3)
        'MessageBox.Show(childList.Count.ToString, "childList.Count")
 
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            If apiChild.ClassName = "TdfInfoRow" Then
                If GroupCount = 4 Then
                    Handle4 = apiChild.hWnd
                ElseIf GroupCount = 5 Then
                    Handle5 = apiChild.hWnd
                End If
                GroupCount += 1
            End If
        Next
 
        Handle6 = FindWindowEx(Handle4, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)
        Handle7 = FindWindowEx(Handle5, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)
 
        Call SendMessageByString(Handle6, WM_SETTEXT, 0, "LastName")
        Call SendMessageByString(Handle7, WM_SETTEXT, 0, "FirstName")
 
    End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:

Select allOpen in new window

 

by: Idle_MindPosted on 2009-07-07 at 08:54:41ID: 24795364

Awesome...glad you were able to put it all together!

The very nature of these types of questions make them the most difficult at EE to answer.  Just getting the necessary preliminary information is tricky in itself...as the experts don't have the app in front of them to interrogate and experiment with.

As you've found out, there are a myriad of Win APIs and approaches that can be used...and often no concrete, clear path to which is best and/or whether a combination is needed.

Glad I was able to gently guide you in the right direction.  It's obvious to me that you are a fairly proficient programmer who just needed some help with a new territory.  =)

 

by: revstudioPosted on 2009-07-07 at 09:08:49ID: 24795489

Thanks again for all the help.

I updated the code above to run through the entire hierarchy and get all the handles. I think it is cleaner although challenging to follow if  you haven't "been through the pain"

Private Sub RadButton5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadButton5.Click
 
        Dim Handle1, Handle2, Handle3, Handle4, Handle5, Handle6, Handle7, Handle8, Handle9, Handle10, Handle11 As Integer
        Dim GroupCount As Integer = 0
 
        winList.Clear()
        childList.Clear()
 
        winList = winEnum.GetTopLevelWindows("TShowShellManagerOrderForm.UnicodeClass")
 
        For Each apiWin As WindowsEnumTest.ApiWindow In winList
 
            childList = winEnum.GetChildWindows(apiWin.hWnd)
            For Each apiChild As WindowsEnumTest.ApiWindow In childList
                If apiChild.ClassName = "TdfInfoPanel" Then
                    If GroupCount = 2 Then
                        Handle1 = apiChild.hWnd
                    End If
                    GroupCount += 1
                End If
 
            Next
        Next
 
        GroupCount = 0
        childList.Clear()
        childList = winEnum.GetChildWindows(Handle1)
 
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            If apiChild.ClassName = "TdfInfoGroup.UnicodeClass" Then
                If GroupCount = 2 Then
                    Handle2 = apiChild.hWnd
                ElseIf GroupCount = 3 Then
                    Handle3 = apiChild.hWnd
                End If
                GroupCount += 1
            End If
 
        Next
 
        Handle4 = FindWindowEx(Handle2, IntPtr.Zero, "TdfInfoPanel", Nothing)
        Handle5 = FindWindowEx(Handle3, IntPtr.Zero, "TdfInfoPanel", Nothing)
 
        GroupCount = 0
        childList.Clear()
        childList = winEnum.GetChildWindows(Handle4)
 
        'First and Last Name
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            If apiChild.ClassName = "TdfInfoRow" Then
                If GroupCount = 4 Then
                    Handle6 = apiChild.hWnd
                ElseIf GroupCount = 5 Then
                    Handle7 = apiChild.hWnd
                End If
                GroupCount += 1
            End If
        Next
 
        GroupCount = 0
        childList.Clear()
        childList = winEnum.GetChildWindows(Handle5)
 
        'Order No.
        For Each apiChild As WindowsEnumTest.ApiWindow In childList
            If apiChild.ClassName = "TdfInfoRow" Then
                If GroupCount = 1 Then
                    Handle8 = apiChild.hWnd
                End If
                GroupCount += 1
            End If
        Next
 
        Handle9 = FindWindowEx(Handle6, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)
        Handle10 = FindWindowEx(Handle7, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)
        Handle11 = FindWindowEx(Handle8, IntPtr.Zero, "TCompactEdit.UnicodeClass", Nothing)
 
        Call SendMessageByString(Handle9, WM_SETTEXT, 0, "LastName")
        Call SendMessageByString(Handle10, WM_SETTEXT, 0, "FirstName")
        Call SendMessageByString(Handle11, WM_SETTEXT, 0, "1000001")
 
    End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:

Select allOpen in new window

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...