Results 1 to 7 of 7

Thread: Finding child by its first word

  1. #1

    Thread Starter
    Hyperactive Member Skatebone's Avatar
    Join Date
    Jan 2009
    Location
    Malta
    Posts
    279

    Finding child by its first word

    Hey guys

    I got a situation where i have the first word only of a a child window and the rest of the name changes. I need to find this child window using findwindowex i think by not knowing the full name.

    Searching the processes wont work since it is a child.

    Tnx alot ^^
    Life runs on code

  2. #2
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: Finding child by its first word

    Enum all child windows (getting their handles) and send GetWindowText to each one. You can then see if the returned strings contain the first part.
    http://www.vbforums.com/showpost.php...30&postcount=6
    VB 2005, Win Xp Pro sp2

  3. #3

    Thread Starter
    Hyperactive Member Skatebone's Avatar
    Join Date
    Jan 2009
    Location
    Malta
    Posts
    279

    Re: Finding child by its first word

    Tnx alot bro
    Last edited by Skatebone; May 23rd, 2009 at 01:11 PM.
    Life runs on code

  4. #4

    Thread Starter
    Hyperactive Member Skatebone's Avatar
    Join Date
    Jan 2009
    Location
    Malta
    Posts
    279

    Re: Finding child by its first word

    It is giving me example these values:

    201e4
    20208
    201b0
    1002c

    I appreciate your help alot but i might be needing some spoon feeding here cause im not expert in the subject yet
    Life runs on code

  5. #5
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: Finding child by its first word

    No problem. This whole thing may seem complicated but in reality FindWindowEx is performing the same thing. It is a Windows functions that first sends a WM_GETTEXTLENGTH, then a WM_GETTEXT message to all child windows. We do the same thing, because we need a partial match only.

    WM_GETTEXTLENGTH tells us the number of chars in the title. We then create a StringBuilder with enough capacity to hold those chars and use WM_GETTEXT to actually fill the StringBuilder.

    Since I don't know what program you are interested in, the example below is using Windows Calculator to find the handle of the label 'Degrees' by searching for 'degr'. Just make sure that Calculator is running and in scientific mode (View -> Scientific).
    Code:
        'APIs needed to get the Handles of all child windows
        Private Declare Auto Function FindWindowEx Lib "user32" _
        (ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, _
        ByVal ClassName As String, ByVal WindowTitle As String) As IntPtr
    
    
        Private Declare Auto Function EnumChildWindows Lib "user32" _
        (ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
        ByVal lParam As IntPtr) As Boolean
    
        Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, _
        ByVal Parameter As IntPtr) As Boolean
        '----------------------------------------------------------------------
    
    
        'APIs needed to get a WindowTitle
        Private Declare Auto Function SendMessageSTRINGlength Lib "user32" Alias "SendMessage" _
        (ByVal hwnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    
    
        Private Declare Auto Function SendMessageSTRINGget Lib "user32" Alias "SendMessage" _
        (ByVal hwnd As IntPtr, ByVal wMsg As Integer, _
        ByVal wParam As Integer, ByVal lParam As System.Text.StringBuilder) As IntPtr
    
        Private Const WM_GETTEXTLENGTH As Integer = &HE
        Private Const WM_GETTEXT As Integer = &HD
        '----------------------------------------------------------------------
    
    
        Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    
            'let's use Windows Calculator as an example
            Dim MainHandle As IntPtr
            MainHandle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "SciCalc", "Calculator")
    
            Dim ChildHandles() As IntPtr = GetChildWindows(MainHandle)
    
            'for visual confirmation
            For i As Integer = 0 To ChildHandles.Length - 1
                ListBox1.Items.Add(i & ": " & System.Convert.ToString(ChildHandles(i).ToInt32, 16))
            Next
    
    
    
            'here we go through all the window titles
            For i As Integer = 0 To ChildHandles.GetUpperBound(0)
    
                'get the length of the text 
                Dim txtLength As IntPtr
                txtLength = SendMessageSTRINGlength(ChildHandles(i), WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)
    
    
                'create buffer for the returned string
                Dim returnedText As New System.Text.StringBuilder(txtLength.ToInt32 + 1)
    
                'get the window text. Length + 1 because of the null termination
                SendMessageSTRINGget(ChildHandles(i), WM_GETTEXT, txtLength.ToInt32 + 1, returnedText)
    
    
                'here we look for the first part of a window title
                If returnedText.ToString.Contains("Degr") Then
    
                    'ChildHandles(i) is the handle we need
                    MessageBox.Show(System.Convert.ToString(ChildHandles(i).ToInt32, 16) & _
                    " is a handle to a child window" & vbCrLf & "whose title contains degr")
    
                    'no need to search for more since we just found we need
                    Exit For
                End If
            Next
    
        End Sub
    
    
    
    
        Public Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
            Dim ChildrenList As New List(Of IntPtr)
            Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
            Try
                EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
            Finally
                If ListHandle.IsAllocated Then ListHandle.Free()
            End Try
            Return ChildrenList.ToArray
        End Function
    
        Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
            Dim ChildrenList As List(Of IntPtr) = CType(GCHandle.FromIntPtr(Parameter).Target, Global.System.Collections.Generic.List(Of Global.System.IntPtr))
            If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
            ChildrenList.Add(Handle)
            Return True
        End Function
    VB 2005, Win Xp Pro sp2

  6. #6

    Thread Starter
    Hyperactive Member Skatebone's Avatar
    Join Date
    Jan 2009
    Location
    Malta
    Posts
    279

    Re: Finding child by its first word

    Tnx alot bro

    Very helpful
    Life runs on code

  7. #7
    Hyperactive Member Always_Confused's Avatar
    Join Date
    Jun 2006
    Location
    Alabama USA
    Posts
    417

    Re: Finding child by its first word

    What are you trying to achieve? Are you checking to see if the child form is already open?
    If you find information helpful from any member, please take a second and rate their post. Its a nice gesture of your appreciation.

    "I have not failed 10,000 times. I have successfully identified 10,000 ways that will not work" Thomas Edison

    Do illiterate people get the full effect of Alphabet Soup?

    ADO FAQ 2005-2008 Masked Textbox Patch FoxPro Date MZ Tools Great Free Tool

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width