+ Reply to Thread
Results 1 to 11 of 11

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

  1. #1
    RB Smissaert
    Guest

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

    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



  2. #2
    Peter T
    Guest

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

    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@blueyonder.co.uk> wrote in message
    news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    > 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
    >
    >




  3. #3
    RB Smissaert
    Guest

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

    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@TK2MSFTNGP15.phx.gbl...
    > 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@blueyonder.co.uk> wrote in message
    > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >> 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
    >>
    >>

    >
    >



  4. #4
    RB Smissaert
    Guest

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

    Oops, overlooked one important thing:
    Doing dim bFound in the recursive routine will make the variable False every
    time it passes this line of code. Declaring it Static shows there is lots of
    code running after a find.
    Maybe I am on the right track here.

    RBS


    "RB Smissaert" <bartsmissaert@blueyonder.co.uk> wrote in message
    news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    > 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@TK2MSFTNGP15.phx.gbl...
    >> 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@blueyonder.co.uk> wrote in message
    >> news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >>> 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
    >>>
    >>>

    >>
    >>

    >



  5. #5
    Peter T
    Guest

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

    > 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@blueyonder.co.uk> wrote in message
    news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    > 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@TK2MSFTNGP15.phx.gbl...
    > > 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@blueyonder.co.uk> wrote in message
    > > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    > >> 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
    > >>
    > >>

    > >
    > >

    >




  6. #6
    RB Smissaert
    Guest

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

    Hi Peter,

    Thanks, the second method works indeed, so I now got this:

    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 nHold 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 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

    nTmp = FindWindowHwndLike_B(hwnd, ClassName, WindowTitle, _
    level, nHold)
    If nTmp Then nResult = nTmp

    '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

    FindWindowHwndLike_B = nResult

    End Function


    Still, I am wondering now if I really need the 3 extra variables you have
    introduced.
    I agree though that it is better now, because it is nice to make the
    function self-contained and not needing
    a private or public variable.
    Will see if I can simplify it a bit.


    RBS



    "Peter T" <peter_t@discussions> wrote in message
    news:evy3b7$rFHA.4072@TK2MSFTNGP09.phx.gbl...
    >> 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@blueyonder.co.uk> wrote in message
    > news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    >> 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@TK2MSFTNGP15.phx.gbl...
    >> > 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@blueyonder.co.uk> wrote in message
    >> > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >> >> 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
    >> >>
    >> >>
    >> >
    >> >

    >>

    >
    >



  7. #7
    RB Smissaert
    Guest

    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@TK2MSFTNGP09.phx.gbl...
    >> 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@blueyonder.co.uk> wrote in message
    > news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    >> 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@TK2MSFTNGP15.phx.gbl...
    >> > 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@blueyonder.co.uk> wrote in message
    >> > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >> >> 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
    >> >>
    >> >>
    >> >
    >> >

    >>

    >
    >



  8. #8
    RB Smissaert
    Guest

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

    This will make it slightly quicker:

    If InStr(1, sWindowTitle, WindowTitle, vbBinaryCompare) > 0 And _
    sClassName Like ClassName & "*" Then
    FindWindowHwndLike_B = hwnd
    lHolder = hwnd
    Exit Function
    End If

    I want it case-sensitive, so that is OK.
    Couldn't find anything for the ClassName comparison.

    RBS


    "Peter T" <peter_t@discussions> wrote in message
    news:evy3b7$rFHA.4072@TK2MSFTNGP09.phx.gbl...
    >> 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@blueyonder.co.uk> wrote in message
    > news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    >> 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@TK2MSFTNGP15.phx.gbl...
    >> > 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@blueyonder.co.uk> wrote in message
    >> > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >> >> 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
    >> >>
    >> >>
    >> >
    >> >

    >>

    >
    >



  9. #9
    RB Smissaert
    Guest

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

    Actually it can be speeded up further by declaring everything ByRef:

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

    RBS

    "Peter T" <peter_t@discussions> wrote in message
    news:evy3b7$rFHA.4072@TK2MSFTNGP09.phx.gbl...
    >> 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@blueyonder.co.uk> wrote in message
    > news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    >> 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@TK2MSFTNGP15.phx.gbl...
    >> > 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@blueyonder.co.uk> wrote in message
    >> > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >> >> 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
    >> >>
    >> >>
    >> >
    >> >

    >>

    >
    >



  10. #10
    Peter T
    Guest

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

    Re your last 4 posts:

    2/4
    > It looks you can indeed simplify by getting rid of 2 variables and just

    keep
    > the extra
    > one nHolder (which I renamed to lHolder):


    Exactly. But I'm surprised your tester() msgbox in this post (as quoted
    below) shows a value, I would have expected you would need to do -

    Dim n as long
    call FindWindowHwndLike_B(0, "Static", "DOB", 0, n)
    Msgbox n

    To clarify what I should have done previously, in my demo altogether I
    introduced 4 var's vs your original.

    Passed to the function
    bUsetmpVar : purely for testing two methods whereby the function returns a
    value, or does not (like your original).
    nHold : the ByRef arg

    Declared in the function
    nTmp & nResult

    Simply the ByRef nHold arg works fine, though of course the function may not
    return a value (depends on levels of recursions). With this method get rid
    of nTmp & nResult and don't rely on the function returning a value.

    However, if you want the function to consistently return a value, then use
    nTmp & nResult and can dispense with the ByRef nHold arg.

    With your recursive routine both methods work, I suspect the byRef arg
    faster. However some routines may dictate one or other, or even both
    methods.

    > nHolder (which I renamed to lHolder):


    Guess I ought to get out of my "n" convention for longs, and adapt to the
    rest of the world and use an l !

    ============

    3/4 Text Compare etc
    > I want it case-sensitive, so that is OK.
    > Couldn't find anything for the ClassName comparison.


    I don't quite follow. If you want case-sensitive nothing is required and NOT
    Option Text (Option Compare Binary ?)

    ============

    4/4
    > Actually it can be speeded up further by declaring everything ByRef:


    Yes ByRef is always faster, though depending on the routine ByVal might be
    required for some var's.

    ============

    FWIW, for enumerating all windows this is probably faster (XL2K or later)

    Public Declare Function EnumWindows Lib "user32" _
    (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean

    EnumWindows AddressOf MyFunc, ByVal 0&
    then in MyFunc return value to a module/public variable

    though probably not appropriate for your particular "get out when got
    something" routine.

    Regards,
    Peter T

    PS, not sure if you noticed but I posted a question minutes after your OP,
    it's still looking very solitary !


    "RB Smissaert" <bartsmissaert@blueyonder.co.uk> wrote in message
    news:OxCIwqAsFHA.904@tk2msftngp13.phx.gbl...
    > Actually it can be speeded up further by declaring everything ByRef:
    >
    > Function FindWindowHwndLike(hWndStart As Long, _
    > ClassName As String, _
    > WindowTitle As String, _
    > level As Long, _
    > lHolder As Long) As Long
    >
    > RBS
    >
    > "Peter T" <peter_t@discussions> wrote in message
    > news:evy3b7$rFHA.4072@TK2MSFTNGP09.phx.gbl...
    > >> 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@blueyonder.co.uk> wrote in message
    > > news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    > >> 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@TK2MSFTNGP15.phx.gbl...
    > >> > 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@blueyonder.co.uk> wrote in message
    > >> > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    > >> >> 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
    > >> >>
    > >> >>
    > >> >
    > >> >
    > >>

    > >
    > >

    >




  11. #11
    RB Smissaert
    Guest

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

    Will have a look at all this, but it seems to be working all fine now and
    fully behaving like a function.
    Also knocked about 5% of the time off.
    Had a look at your new posting, but not sure I quite understand it.
    Must be the late hour after a busy day.

    RBS

    "Peter T" <peter_t@discussions> wrote in message
    news:exEPefBsFHA.332@tk2msftngp13.phx.gbl...
    > Re your last 4 posts:
    >
    > 2/4
    >> It looks you can indeed simplify by getting rid of 2 variables and just

    > keep
    >> the extra
    >> one nHolder (which I renamed to lHolder):

    >
    > Exactly. But I'm surprised your tester() msgbox in this post (as quoted
    > below) shows a value, I would have expected you would need to do -
    >
    > Dim n as long
    > call FindWindowHwndLike_B(0, "Static", "DOB", 0, n)
    > Msgbox n
    >
    > To clarify what I should have done previously, in my demo altogether I
    > introduced 4 var's vs your original.
    >
    > Passed to the function
    > bUsetmpVar : purely for testing two methods whereby the function returns a
    > value, or does not (like your original).
    > nHold : the ByRef arg
    >
    > Declared in the function
    > nTmp & nResult
    >
    > Simply the ByRef nHold arg works fine, though of course the function may
    > not
    > return a value (depends on levels of recursions). With this method get rid
    > of nTmp & nResult and don't rely on the function returning a value.
    >
    > However, if you want the function to consistently return a value, then use
    > nTmp & nResult and can dispense with the ByRef nHold arg.
    >
    > With your recursive routine both methods work, I suspect the byRef arg
    > faster. However some routines may dictate one or other, or even both
    > methods.
    >
    >> nHolder (which I renamed to lHolder):

    >
    > Guess I ought to get out of my "n" convention for longs, and adapt to the
    > rest of the world and use an l !
    >
    > ============
    >
    > 3/4 Text Compare etc
    >> I want it case-sensitive, so that is OK.
    >> Couldn't find anything for the ClassName comparison.

    >
    > I don't quite follow. If you want case-sensitive nothing is required and
    > NOT
    > Option Text (Option Compare Binary ?)
    >
    > ============
    >
    > 4/4
    >> Actually it can be speeded up further by declaring everything ByRef:

    >
    > Yes ByRef is always faster, though depending on the routine ByVal might be
    > required for some var's.
    >
    > ============
    >
    > FWIW, for enumerating all windows this is probably faster (XL2K or later)
    >
    > Public Declare Function EnumWindows Lib "user32" _
    > (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean
    >
    > EnumWindows AddressOf MyFunc, ByVal 0&
    > then in MyFunc return value to a module/public variable
    >
    > though probably not appropriate for your particular "get out when got
    > something" routine.
    >
    > Regards,
    > Peter T
    >
    > PS, not sure if you noticed but I posted a question minutes after your OP,
    > it's still looking very solitary !
    >
    >
    > "RB Smissaert" <bartsmissaert@blueyonder.co.uk> wrote in message
    > news:OxCIwqAsFHA.904@tk2msftngp13.phx.gbl...
    >> Actually it can be speeded up further by declaring everything ByRef:
    >>
    >> Function FindWindowHwndLike(hWndStart As Long, _
    >> ClassName As String, _
    >> WindowTitle As String, _
    >> level As Long, _
    >> lHolder As Long) As Long
    >>
    >> RBS
    >>
    >> "Peter T" <peter_t@discussions> wrote in message
    >> news:evy3b7$rFHA.4072@TK2MSFTNGP09.phx.gbl...
    >> >> 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@blueyonder.co.uk> wrote in message
    >> > news:Owlj6A$rFHA.2348@tk2msftngp13.phx.gbl...
    >> >> 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@TK2MSFTNGP15.phx.gbl...
    >> >> > 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@blueyonder.co.uk> wrote in message
    >> >> > news:OTtUyQ8rFHA.4040@TK2MSFTNGP14.phx.gbl...
    >> >> >> 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
    >> >> >>
    >> >> >>
    >> >> >
    >> >> >
    >> >>
    >> >
    >> >

    >>

    >
    >



+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

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

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1