Re: Why doesn't this recursive function return the right value?



It looks you can indeed simplify by getting rid of 2 variables and just keep the extra
one nHolder (which I renamed to lHolder):


Sub tester()
   MsgBox FindWindowHwndLike_B(0, "Static", "DOB", 0, 0)
End Sub

Function FindWindowHwndLike_B(ByVal hWndStart As Long, _
                             ByVal ClassName As String, _
                             ByVal WindowTitle As String, _
                             ByVal level As Long, _
                             ByRef lHolder As Long) As Long

   'finds the first window where the class name start with ClassName
   'and where the Window title starts with WindowTitle, returns Hwnd
   '-----------------------------------------------------------------
   Dim hwnd As Long
   Dim sWindowTitle As String
   Dim sClassName As String
   Dim r As Long

   'Initialize if necessary. This is only executed
   'when level = 0 and hWndStart = 0, normally
   'only on the first call to the routine.
   If level = 0 Then
       If hWndStart = 0 Then
           hWndStart = GetDesktopWindow()
       End If
   End If

   'Increase recursion counter
   level = level + 1

   'Get first child window
   hwnd = GetWindow(hWndStart, GW_CHILD)

   Do Until hwnd = 0

       'Search children by recursion

       lHolder = FindWindowHwndLike_B(hwnd, ClassName, WindowTitle, _
                                      level, lHolder)

       'Get the window text
       sWindowTitle = Space$(255)
       r = GetWindowText(hwnd, sWindowTitle, 255)
       sWindowTitle = Left$(sWindowTitle, r)

       'get the class name
       sClassName = Space$(255)
       r = GetClassName(hwnd, sClassName, 255)
       sClassName = Left$(sClassName, r)

       'Check if the window matches the search parameters
       If (sWindowTitle Like "*" & WindowTitle & "*") And _
          (sClassName Like ClassName & "*") Then
           FindWindowHwndLike_B = hwnd
           lHolder = hwnd
           Exit Function
       End If

       'Get next child window
       hwnd = GetWindow(hwnd, GW_HWNDNEXT)

   Loop

   FindWindowHwndLike_B = lHolder

End Function


RBS


"Peter T" <peter_t@discussions> wrote in message news:evy3b7$rFHA.4072@xxxxxxxxxxxxxxxxxxxxxxx
How and where are nTmp and nResult declared?

Sorry, I should have stated within the FindWindowHwndLike function

Following attempts to demonstrate the two methods I mentioned earlier -
- an additional ByRef var to pass back to the calling routing
- re-assigning the value to the Function on each return back up the stack

requires the same API's & Const's per your OP, maybe also Compare Text (just
in case)


Option Compare Text

Sub tester2()
Dim s1 As String, s2 As String
Dim x As Long, y As Long

s1 = "EXCE": s2 = "Book" ' eg like EXCEL7 & Book1.xls

x = FindWindowHwndLike_B(0, s1, s2, 0, y, False)
MsgBox "Func-return " & x & vbCr & "ByRef Arg  " & y

x = FindWindowHwndLike_B(0, s1, s2, 0, y, True)
MsgBox "Func-return " & x & vbCr & "ByRef Arg  " & y

End Sub

Function FindWindowHwndLike_B(ByVal hWndStart As Long, _
                           ByVal ClassName As String, _
                           ByVal WindowTitle As String, _
                           ByVal level As Long, _
                           ByRef nHold As Long, _
                           bUseTmpVar As Boolean) As Long

   'finds the first window where the class name start with ClassName
   'and where the Window title starts with WindowTitle, returns Hwnd
   '-----------------------------------------------------------------
   Dim hwnd As Long
   Dim sWindowTitle As String
   Dim sClassName As String
   Dim r As Long
   Dim nTmp As Long
   Dim nResult As Long

   'Initialize if necessary. This is only executed
   'when level = 0 and hWndStart = 0, normally
   'only on the first call to the routine.
   If level = 0 Then
       If hWndStart = 0 Then
           hWndStart = GetDesktopWindow()
       End If
   End If

   'Increase recursion counter
   level = level + 1

   'Get first child window
   hwnd = GetWindow(hWndStart, GW_CHILD)

   Do Until hwnd = 0

       'Search children by recursion

If bUseTmpVar Then
   nTmp = FindWindowHwndLike_B(hwnd, ClassName, WindowTitle, _
                               level, nHold, bUseTmpVar)
   If nTmp Then nResult = nTmp
Else
   Call FindWindowHwndLike_B(hwnd, ClassName, WindowTitle, _
                               level, nHold, bUseTmpVar)
End If

       'Get the window text
       sWindowTitle = Space$(255)
       r = GetWindowText(hwnd, sWindowTitle, 255)
       sWindowTitle = Left$(sWindowTitle, r)

       'get the class name
       sClassName = Space$(255)
       r = GetClassName(hwnd, sClassName, 255)
       sClassName = Left$(sClassName, r)

       'Check if the window matches the search parameters
       If (sWindowTitle Like "*" & WindowTitle & "*") And _
          (sClassName Like ClassName & "*") Then
           FindWindowHwndLike_B = hwnd
           nHold = hwnd
           Exit Function
       End If

       'Get next child window
       hwnd = GetWindow(hwnd, GW_HWNDNEXT)

   Loop
   If bUseTmpVar Then
       FindWindowHwndLike_B = nResult
   End If
End Function

Regards,
Peter T


"RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx> wrote in message news:Owlj6A$rFHA.2348@xxxxxxxxxxxxxxxxxxxxxxx
Hi Peter,


Sorry, but I don't understand this bit at all:

'recursive
nTmp = FindWindowHwndLike(hwnd, ClassName, WindowTitle, level)
If nTmp Then nResult = nTmp

'then finally -
FindWindowHwndLike = nResult
Exit function

How and where are nTmp and nResult declared?
Why would it make a difference?
I tried something like you suggested, but still get zero.

What I don't understand is this: It finds the right window, with the right
hwnd, but it returns zero.
Where does the variable hwnd change from the right value to zero?
I put messageboxes in the recursive function that could show after the
right
window was found, but nil of these show, so no code runs after the window
was found:


Function FindWindowHwndLike(ByVal hWndStart As Long, _ ByVal ClassName As String, _ ByVal WindowTitle As String, _ ByVal level As Long) As Long

    'finds the first window where the class name start with ClassName
    'and where the Window title starts with WindowTitle, returns Hwnd
    '-----------------------------------------------------------------
    Dim hwnd As Long
    Dim sWindowTitle As String
    Dim sClassName As String
    Dim r As Long
    Dim bFound As Boolean

    If bFound Then
        MsgBox "test1"
    End If

    'Initialize if necessary. This is only executed
    'when level = 0 and hWndStart = 0, normally
    'only on the first call to the routine.
    If level = 0 Then
        If hWndStart = 0 Then
            hWndStart = GetDesktopWindow()
        End If
    End If

    'Increase recursion counter
    level = level + 1

    'Get first child window
    hwnd = GetWindow(hWndStart, GW_CHILD)

    If bFound Then
        MsgBox "test2"
    End If

    Do Until hwnd = 0

        If bFound Then
            MsgBox "test3"
        End If

        'Search children by recursion
        FindWindowHwndLike hwnd, ClassName, WindowTitle, level

        'Get the window text
        sWindowTitle = Space$(255)
        r = GetWindowText(hwnd, sWindowTitle, 255)
        sWindowTitle = Left$(sWindowTitle, r)

        'get the class name
        sClassName = Space$(255)
        r = GetClassName(hwnd, sClassName, 255)
        sClassName = Left$(sClassName, r)

        'Check if the window matches the search parameters
        If (sWindowTitle Like "*" & WindowTitle & "*") And _
           (sClassName Like ClassName & "*") Then

            If bFound Then
                MsgBox "test4"
            End If

            bFound = True
            MsgBox hwnd
            FindWindowHwndLike = hwnd
            Exit Function
            If bFound Then
                MsgBox "test5"
            End If

        End If

        If bFound Then
            MsgBox "test6"
        End If

        'Get next child window
        hwnd = GetWindow(hwnd, GW_HWNDNEXT)

        If bFound Then
            MsgBox "test7"
        End If

    Loop

    If bFound Then
        MsgBox "test8"
    End If

End Function


The trouble probably is that recursive function are bit mind-boggling in
any
case and I might be overlooking something simple here.
I just know that in my particular situation I don't have to worry about
more
than one qualifying windows.
Thanks in any case for your suggestions.


RBS


"Peter T" <peter_t@discussions> wrote in message
news:uNJd1m9rFHA.3340@xxxxxxxxxxxxxxxxxxxxxxx
> Hi Bart,
>
> My take is the function return value persists only in the calling > stack.
>
> So two solutions, the first as you've described and include an
additional
> ByRef arg to return the value all the way back to the original calling
> routine. Or something like this:
>
> 'recursive
> nTmp = FindWindowHwndLike(hwnd, ClassName, WindowTitle, level)
> If nTmp Then nResult = nTmp
>
> 'then finally -
> FindWindowHwndLike = nResult
> Exit function
>
> I think passing the additional ByRef arg would be faster.
>
> Just a thought, maybe build an array of all the "like" window captions,
> just
> in case more than one.
>
> Regards,
> Peter T
>
>
>
> "RB Smissaert" <bartsmissaert@xxxxxxxxxxxxxxxx> wrote in message
> news:OTtUyQ8rFHA.4040@xxxxxxxxxxxxxxxxxxxxxxx
>> Have a recursive function that returns the window handle of a
particular
>> window, based on the window type and text.
>> It works fine and it finds the right window, but it just doesn't >> return
> the
>> right value. It returns zero.
>> When I do a msgbox before the Exit function it shows fine, or when I
>> retrieve the value with a private variable I get the right value as
well.
> It
>> is not a problem, but just wondering why this happens.
>>
>> Option Explicit
>> Private Declare Function GetDesktopWindow Lib "user32" () As Long
>> Private Declare Function GetWindow Lib "user32" _
>>                                   (ByVal hwnd As Long, _
>>                                    ByVal wCmd As Long) As Long
>> Private Declare Function GetWindowText Lib "user32" _
>>                                       Alias "GetWindowTextA" _
>>                                       (ByVal hwnd As Long, _
>>                                        ByVal lpString As String, _
>>                                        ByVal cch As Long) As Long
>> Private Declare Function GetClassName Lib "user32" _
>>                                      Alias "GetClassNameA" _
>>                                      (ByVal hwnd As Long, _
>>                                       ByVal lpClassName As String, _
>>                                       ByVal nMaxCount As Long) As Long
>> Private Const GW_HWNDFIRST = 0
>> Private Const GW_HWNDLAST = 1
>> Private Const GW_HWNDNEXT = 2
>> Private Const GW_HWNDPREV = 3
>> Private Const GW_OWNER = 4
>> Private Const GW_CHILD = 5
>>
>> Sub tester()
>>     MsgBox FindWindowHwndLike(0, "Static", "DOB", 0)
>> End Sub
>>
>>
>> Function FindWindowHwndLike(ByVal hWndStart As Long, _
>>                             ByVal ClassName As String, _
>>                             ByVal WindowTitle As String, _
>>                             ByVal level As Long) As Long
>>
>>     'finds the first window where the class name start with ClassName
>>     'and where the Window title starts with WindowTitle, returns Hwnd
>>     '-----------------------------------------------------------------
>>     Dim hwnd As Long
>>     Dim sWindowTitle As String
>>     Dim sClassName As String
>>     Dim r As Long
>>
>>     'Initialize if necessary. This is only executed
>>     'when level = 0 and hWndStart = 0, normally
>>     'only on the first call to the routine.
>>     If level = 0 Then
>>         If hWndStart = 0 Then
>>             hWndStart = GetDesktopWindow()
>>         End If
>>     End If
>>
>>     'Increase recursion counter
>>     level = level + 1
>>
>>     'Get first child window
>>     hwnd = GetWindow(hWndStart, GW_CHILD)
>>
>>     Do Until hwnd = 0
>>
>>         'Search children by recursion
>>         Call FindWindowHwndLike(hwnd, ClassName, WindowTitle, level)
>>
>>         'Get the window text
>>         sWindowTitle = Space$(255)
>>         r = GetWindowText(hwnd, sWindowTitle, 255)
>>         sWindowTitle = Left$(sWindowTitle, r)
>>
>>         'get the class name
>>         sClassName = Space$(255)
>>         r = GetClassName(hwnd, sClassName, 255)
>>         sClassName = Left$(sClassName, r)
>>
>>         'Check if the window matches the search parameters
>>         If (sWindowTitle Like "*" & WindowTitle & "*") And _
>>            (sClassName Like ClassName & "*") Then
>>             FindWindowHwndLike = hwnd
>>             Exit Function
>>         End If
>>
>>         'Get next child window
>>         hwnd = GetWindow(hwnd, GW_HWNDNEXT)
>>
>>     Loop
>>
>> End Function
>>
>>
>> Thanks for any advice.
>>
>>
>> RBS
>>
>>
>
>




.



Relevant Pages


Quantcast