Announcement

Collapse
No announcement yet.

FindButtonInWindow with some kinks

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • FindButtonInWindow with some kinks

    Following is a simple standard function to retrieve the handle of a button inside any open window for access in an other running application.
    As You can see I inserted two MsgBoxes at significant places. The function is running well as long as the MsgBoxes are not commented out. As soon as they are only one item the loops is handled, all others are overridden. How can I insert a delay or anything else providing a smooth working of the function?

    Code:
    '-------------------------------------------------------------------------------------------------------
    ' FUNCTION FindButtonInWindow
    '-------------------------------------------------------------------------------------------------------
    Function FindButtonInWindow(sWndTitle As String, sBtnText As String) As Dword
        'INPUT:     sWndTitle as Titel of the Window, sBtnText as Text of the Button
        'OUTPUT:  Handle of the found button as [Dword]
    
        On Error Resume Next
        Dim Btn As Long, CurHwnd As Dword, szT As Asciiz * 128
        Dim Length As Long, x As Long, y As Long 
        Function = 0
        ' Trying to find the handle of the View Code Button so that
        ' by clicking this program's button, we can see the code
        ' window for this form.
        CurHwnd = GetDesktopWindow()            'Get Desktop handle
        CurHwnd = GetWindow(CurHwnd, %GW_Child)  'Find Child Windows of Desktop
        Do
            If CurHwnd = 0 Then Exit Do         'No (more) matches found
            ' Find out how long the text in this window is
            Length = GetWindowTextLength(CurHwnd)
            Length = GetWindowText(CurHwnd, szT, Length + 1)
            If InStr(szT, sWndTitle) Then 
    MsgBox ""
                ' The value of sWindowTitle was found in this Window's text
                CurHwnd = GetWindow(CurHwnd, %GW_Child)
                ' Looking now for the Window's child windows
                Do
                    If CurHwnd = 0 Then Exit Function 'No (more) matches found
                    ' Find out how long the text in this window is
                    Length = GetWindowTextLength(CurHwnd)
                    Length = GetWindowText(CurHwnd, szT, Length + 1)
                    If InStr(szT, sBtnText) Then
    MsgBox ""
                        ' This is the handle we want
                        '### Click(CurHwnd)            'alternatively click the Button
                        Function = CurHwnd
                        Exit Function                 'Exit the Sub
                    End If
                CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                Loop
            End If
            CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
        Loop
    End Function
    Norbert Doerre

  • #2
    You could use the:
    DECLARE SUB apiSleep LIB "KERNEL32.DLL" ALIAS "Sleep" (BYVAL dwMilliseconds AS DWORD)
    From the Win32API, or maybe rethink and wrap it where you can execute each loop on a WinTimer tick event?
    Furcadia, an interesting online MMORPG in which you can create and program your own content.

    Comment


    • #3
      Messageboxes are not the best way to get debug/display output from GUI programs. The extra message loop created by MSGBOX seems to do something strange and wonderous.

      You might try Simple STDOUT for PB/DLL and PB/Win 2-13-04

      Also, EnumChildWindows might work a little better for you, since all the 'real action' can be coded in one place: your callback function. I know there are examples here in Source Code Forum.

      This is specifically "get handle to a BUTTON control with text "X" which is an immediate child of the top-level window whose caption (title) is "Y," right?

      And then you want to do what with that handle?

      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        I'll bet the MSGBOX is affecting the Z-Order, which directly affects GetWindow() when HWND_NEXT is used.

        Change to the EnumChildWindows and/or replace MSGBOX with STDOUT or "something else"
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Michael, I've known about the timing difficulties with this type of code since the last ten years, but I needed it only I think twice during all the time. So I never had much interest in it. I took the code from an ancient Pascal program and translated it to PB. The window handles were still Integers at that time. I don't know if there might be some similiar articles in the PB forum. I tried already to search, but with no good result because it's always hard for me to input the translated max. three search criteria. But I'm going to try it once again now.
          The code is for an old friend of mine working with a huge building administration program named "Domus", wanting me to write a small add to extract some sql data in the background by 'remote' click on a checkbox in an invisible Domus window. That's all.
          I asked here in the forum because I know that "sleep" or similiar only stops the whole process without any decelerating effect.
          Norbert Doerre

          Comment


          • #6
            This just became a never mind, my SDK broke on this machine.
            Last edited by colin glenn; 11 Mar 2008, 05:30 PM.
            Furcadia, an interesting online MMORPG in which you can create and program your own content.

            Comment


            • #7
              It seems to work for me (I had to make the search case-insensitive to avoid insanity). Under what circumstances does it fail in your testing?

              Code:
              #PBFORMS CREATED V1.51
              #COMPILE EXE
              #DIM ALL
              
              #PBFORMS BEGIN INCLUDES
              #IF NOT %DEF(%WINAPI)
                  #INCLUDE "WIN32API.INC"
              #ENDIF
              #PBFORMS END INCLUDES
              
              #PBFORMS BEGIN CONSTANTS
              %IDD_DIALOG1  =  101
              %IDC_WINDOW_TB = 1001
              %IDC_BUTTON1  = 1002
              %IDC_BUTTON_TB = 1003
              %IDC_LABEL1   = 1004
              %IDC_LABEL2   = 1005
              #PBFORMS END CONSTANTS
              
              DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
              DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
              #PBFORMS DECLARATIONS
              
              '-------------------------------------------------------------------------------------------------------
              ' FUNCTION FindButtonInWindow
              '-------------------------------------------------------------------------------------------------------
              FUNCTION FindButtonInWindow(sWndTitle AS STRING, sBtnText AS STRING) AS DWORD
                  'INPUT:     sWndTitle as Titel of the Window, sBtnText as Text of the Button
                  'OUTPUT:  Handle of the found button as [Dword]
              
                  ON ERROR RESUME NEXT
                  DIM Btn AS LONG, CurHwnd AS DWORD, szT AS ASCIIZ * 128
                  DIM Length AS LONG, x AS LONG, y AS LONG
                  FUNCTION = 0
                  ' Trying to find the handle of the View Code Button so that
                  ' by clicking this program's button, we can see the code
                  ' window for this form.
                  CurHwnd = GetDesktopWindow()            'Get Desktop handle
                  CurHwnd = GetWindow(CurHwnd, %GW_Child)  'Find Child Windows of Desktop
                  DO
                      IF CurHwnd = 0 THEN EXIT DO         'No (more) matches found
                      ' Find out how long the text in this window is
                      Length = GetWindowTextLength(CurHwnd)
                      Length = GetWindowText(CurHwnd, szT, Length + 1)
                      IF INSTR(UCASE$(szT), UCASE$(sWndTitle)) THEN
                          'MSGBOX ""
                          ' The value of sWindowTitle was found in this Window's text
                          CurHwnd = GetWindow(CurHwnd, %GW_Child)
                          ' Looking now for the Window's child windows
                          DO
                              IF CurHwnd = 0 THEN EXIT FUNCTION 'No (more) matches found
                              ' Find out how long the text in this window is
                              Length = GetWindowTextLength(CurHwnd)
                              Length = GetWindowText(CurHwnd, szT, Length + 1)
                              IF INSTR(UCASE$(szT), UCASE$(sBtnText)) THEN
                                  'MSGBOX ""
                                  ' This is the handle we want
                                  '### Click(CurHwnd)            'alternatively click the Button
                                  FUNCTION = CurHwnd
                                  EXIT FUNCTION                 'Exit the Sub
                              END IF
                          CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                          LOOP
                      END IF
                      CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                  LOOP
              END FUNCTION
              
              '--------------------------------------------------------------------------
              CALLBACK FUNCTION ShowDIALOG1Proc()
                  LOCAL s1, s2 AS STRING
              
                  SELECT CASE AS LONG CBMSG
                      CASE %WM_INITDIALOG
              
              
                      CASE %WM_COMMAND
                          SELECT CASE AS LONG CBCTL
                              CASE %IDC_WINDOW_TB
              
                              CASE %IDC_BUTTON1
                                  IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                                      CONTROL GET TEXT CBHNDL, %IDC_WINDOW_TB TO s1
                                      CONTROL GET TEXT CBHNDL, %IDC_button_TB TO s2
                                      ? STR$(FindButtonInWindow(s1, s2))
                                  END IF
              
                              CASE %IDC_BUTTON_TB
              
                              CASE %IDC_LABEL1
              
                              CASE %IDC_LABEL2
              
                          END SELECT
                  END SELECT
              END FUNCTION
              
              FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                  LOCAL lRslt AS LONG
              
              #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                  LOCAL hDlg  AS DWORD
              
                  DIALOG NEW hParent, "DoerreNFindButton", 117, 128, 201, 121, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
                      %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT _
                      OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                  CONTROL ADD TEXTBOX, hDlg, %IDC_WINDOW_TB, "TextBox1", 15, 15, 170, 20
                  CONTROL ADD BUTTON,  hDlg, %IDC_BUTTON1, "Go", 155, 95, 35, 15
                  CONTROL ADD TEXTBOX, hDlg, %IDC_BUTTON_TB, "TextBox1", 15, 50, 170, 20
                  CONTROL ADD LABEL,   hDlg, %IDC_LABEL1, "Window Title", 15, 5, 60, 10
                  CONTROL ADD LABEL,   hDlg, %IDC_LABEL2, "Button Legend", 15, 40, 60, 10
              #PBFORMS END DIALOG
              
                  DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
              
              #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
              #PBFORMS END CLEANUP
              
                  FUNCTION = lRslt
              END FUNCTION
              
              
              '=============================================================================
              FUNCTION PBMAIN()
                  ShowDIALOG1 %HWND_DESKTOP
              END FUNCTION

              Comment


              • #8
                Or, why not update a progress bar?

                Comment


                • #9
                  Originally posted by Michael Mattias View Post
                  I'll bet the MSGBOX is affecting the Z-Order, which directly affects GetWindow() when HWND_NEXT is used.
                  Change to the EnumChildWindows and/or replace MSGBOX with STDOUT or "something else"
                  Michael, we misunderstood once again:
                  I inserted the MSGBOXes only to achieve a proper result.
                  As far as I found out in the mean time, only the upper one is necessary. The second one can be commented out. As soon as I aditionally comment out the upper one, the routine delivers a crippled result because the loop is stopped with a zero result after the first correct one was found. After uncommenting the MSGBOX I have just to click the OK button of the MSGBOX to get the next correct result and so on....
                  When the desired Window is finally found by the first loop, the second loop is able to run without any delay, and the function's result is a proper and usable handle of the CheckBox.
                  Norbert Doerre

                  Comment


                  • #10
                    Originally posted by colin glenn View Post
                    This just became a never mind, my SDK broke on this machine.
                    Chris, thanks for the hint!!!
                    I'll try it out, but tomorrow. Local time is 23:50 now.
                    My code is usually compiled to a DLL. May be that this might be the cause for some timing trouble. This is hard to find, hovever, at least without a real time DLL debugger. I will alternatively compile to an EXE and try it again. Just this makes programming interesting - at least for me.
                    Norbert Doerre

                    Comment


                    • #11
                      Oh I see now. It was a programming error we couldn't find because there was insufficient code posted to compile and run. (Mr. Holbrook is far more accommodating than I).

                      Still leaves valid the point re MSGBOX: not a good tool when debugging re-entrant code.
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Hm. bit suspicious that the parent and child loops use the same window handle.

                        Comment


                        • #13
                          Chris is right,
                          having both the dialog do/loop and control do/loop
                          using the same "CurHwnd" variable will give strange result
                          if a dialog with no valid button text is found via "InStr(szT, sWndTitle)"
                          becose the GetWindow in the second loop will restart at zero...

                          Other than this, the program run fine on my side too,
                          anyway, here is a variation that does more checking
                          and use 2 differents handles to avoid this problem.
                          This routine also make sure that the control text come from a button

                          Code:
                          %MAX_CLASSNAME   = 256
                          %MAX_CAPTIONNAME = 256
                          %MAX_CONTROLNAME = 256
                          '______________________________________________________________________________
                           
                          FUNCTION FindButtonInWindow(sDialog AS STRING, sButton AS STRING) AS DWORD
                           LOCAL hDialogTry    AS DWORD
                           LOCAL hControlTry   AS DWORD
                           LOCAL zDialogTry    AS ASCIIZ * %MAX_CAPTIONNAME 
                           LOCAL zButtonTry    AS ASCIIZ * %MAX_CONTROLNAME
                           LOCAL zClass        AS ASCIIZ * %MAX_CLASSNAME
                           LOCAL LenDialogTry  AS LONG
                           LOCAL LenButtonTry  AS LONG
                           
                           hDialogTry = GetTopWindow(%HWND_DESKTOP)
                           DO WHILE hDialogTry 
                             LenDialogTry = GetWindowText(hDialogTry, zDialogTry, %MAX_CAPTIONNAME)
                             IF LenDialogTry THEN
                               IF LEFT$(UCASE$(zDialogTry), LenDialogTry) = UCASE$(sDialog) THEN
                                 hControlTry = GetWindow(hDialogTry, %GW_Child)
                                 DO WHILE hControlTry
                                   GetClassName(hControlTry, zClass, %MAX_CLASSNAME)
                                   IF LEFT$(UCASE$(zClass), 6) = "BUTTON" THEN
                                     LenButtonTry = GetWindowText(hControlTry, zButtonTry, %MAX_CONTROLNAME)             
                                     IF LEFT$(UCASE$(zButtonTry), LenButtonTry) = UCASE$(sButton) THEN
                                       FUNCTION = hControlTry
                                       EXIT, EXIT
                                     END IF
                                   END IF
                                   hControlTry = GetWindow(hControlTry, %GW_HWNDNEXT)
                                 LOOP
                               END IF
                             END IF
                             hDialogTry = GetWindow(hDialogTry, %GW_HWNDNEXT) 
                           LOOP
                           
                          END FUNCTION
                          '______________________________________________________________________________

                          Comment


                          • #14
                            Code:
                            ' find_target_window.bas
                            ' 03.12.08
                            #COMPILE EXE
                            #DIM    ALL
                            
                            
                            #INCLUDE "Win32API.INC"
                            
                            TYPE EnumCHildParamType
                                szSearchText AS ASCIIZ * 128
                                hWndFound    AS LONG
                            END TYPE
                            
                            
                            FUNCTION PBMAIN () AS LONG
                            
                             LOCAL szParentText AS ASCIIZ * 128, szControlText AS ASCIIZ * 128, hWndStart AS LONG, hWndControl AS LONG
                             
                             LOCAL S AS STRING
                            
                             hWndStart     = GetDesktopWindow()
                             szParentText   = "PB/Win IDE"
                             szControlText  = "D:\Software_Development\pbwin80\work\Find_target_window.bas"
                            
                             CALL FindHandleToControlGivenParentWindowTextAndControlWindowText(hWndStart, szParentText, szControlText) TO hWndControl
                             
                             s  = USING$ ("Parent Text '&'" & $CRLF & "Child Text '&'" & $CRLF, szParentTExt, szControlText)
                            
                              IF ISTRUE hWndControl THEN
                                 s  = S & USING$ ("Target Window found handle is # ", hWndControl)
                            
                              ELSE
                                 s  = S & "target window not found"
                              END IF
                              MSGBOX S, %MB_ICONINFORMATION, "That wasn't so hard now, was it?"
                            
                            END FUNCTION
                            
                            ' returns: FALSE==> no such window found
                            '          TRUE ==> handle to target window
                            FUNCTION  FindHandleToControlGivenParentWindowTextAndControlWindowText _
                                (hWndStart AS LONG, szparentText AS ASCIIZ, szControlText AS ASCIIZ) AS LONG
                            
                                LOCAL lparam AS LONG, iRet AS LONG, dwCbAddr AS DWORD
                                LOCAL P AS EnumChildParamType , whWnd AS LONG
                            
                                p.szSearchText = szParentText
                                p.hWndFound    = %NULL
                                FUNCTION       = 0&             ' default ==> not found
                            
                                lparam   = VARPTR ( P)
                                dwcbAddr = CODEPTR (EnumChildFunction)
                            
                                iRet  = EnumChildWindows (hWndStart, dwCbAddr, BYVAL lparam)
                                ' The SDK doc for this function says TRUE= success, FALSE = failed.
                                ' That is a little misleading.
                                ' It returns TRUE if the enum completes; FALSE if it is terminated.
                                ' If it returns FALSE here it was terminated because we got a match on the
                                ' parent text which of course to us means "success."
                                IF ISFALSE iRET THEN
                                         P.szSearchText  = szControlText
                                         WhWnd           = P.HwndFound
                                         P.hWndFound     = %NULL
                                         iret            = EnumChildWindows (whwnd, dwCbAddr, BYVAL lparam)
                                         IF ISFALSE iRet THEN             ' we found our child window text, too!
                                            FUNCTION =  P.hWndFound       ' will either be zero or not
                                         END IF
                                END IF  ' if we got a hit on the parent window text
                            
                            END FUNCTION
                            
                            
                            FUNCTION EnumChildFunction (BYVAL hWnd AS LONG, P AS EnumChildParamType) AS LONG
                            
                               LOCAL szText AS ASCIIZ * %MAX_PATH, nChar AS LONG
                            
                               nChar = GetWindowText (hWnd, szText, SIZEOF(szText))
                               IF lstrcmp (szText, P.szSearchText) = 0& THEN   ' use lstrcmpi for case-insensitive search
                                    P.HwndFound = hWnd
                                    FUNCTION    =  0
                               ELSE
                                    FUNCTION    = %TRUE
                               END IF
                            
                            END FUNCTION
                            ' END OF FILE
                            MCM
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              Just coming back from that office needing 'remote access' to the Domus program hidden dialog. Well, I found out today that this it not a simple one but a systab control with one page only. I could get access to all buttons with my spy program.
                              The unskilled persons there seem to see no problem with getting access to the checkbox after they saw that I could make the dialog temporary visible with my DDT Spy. The handles of the hoovered controls are visible, and parent info is also correct. But trying to get the handles in forward "GetWindow" mode (from parent to control Wnd) fails by 50%, because controls are not found, as I described yesterday.
                              I know that it is not a good deal with systabs. But now i know at least what to search for.
                              Norbert Doerre

                              Comment


                              • #16
                                To look at this problem I built a treeview of the windows & controls. Don't quite understand it though, either I did it wrong or there are a lot of nameless windows hanging around! PB Win 8.04.

                                Code:
                                ' build a treeview of windows on the desktop and their controls
                                '
                                ' Chris Holbrook Mar 2008
                                #PBFORMS CREATED V1.51
                                #COMPILE EXE
                                #DIM ALL
                                
                                #PBFORMS BEGIN INCLUDES
                                #IF NOT %DEF(%WINAPI)
                                    #INCLUDE "WIN32API.INC"
                                #ENDIF
                                #IF NOT %DEF(%COMMCTRL_INC)
                                    #INCLUDE "COMMCTRL.INC"
                                #ENDIF
                                #INCLUDE "PBForms.INC"
                                #PBFORMS END INCLUDES
                                
                                #PBFORMS BEGIN CONSTANTS
                                %IDD_DIALOG1 =  101
                                %IDC_TV      = 1003
                                #PBFORMS END CONSTANTS
                                
                                #PBFORMS DECLARATIONS
                                
                                GLOBAL gdwOrigEditProc AS DWORD
                                '-----------------------------------------------------------
                                FUNCTION TreeViewInsertItem(BYVAL hTree AS DWORD, BYVAL hParent AS DWORD, sItem AS STRING) AS LONG
                                    LOCAL tTVItem   AS TV_ITEM
                                    LOCAL tTVInsert AS TV_INSERTSTRUCT
                                
                                    IF hParent THEN
                                        tTVItem.mask      = %TVIF_CHILDREN OR %TVIF_HANDLE
                                        tTVItem.hItem     = hParent
                                        tTVItem.cchildren = 1
                                        TreeView_SetItem hTree, tTVItem
                                    END IF
                                
                                    tTVInsert.hParent              = hParent
                                    tTVInsert.Item.Item.mask       = %TVIF_TEXT
                                    tTVInsert.Item.Item.pszText    = STRPTR(sItem)
                                    tTVInsert.Item.Item.cchTextMax = LEN(sItem)
                                
                                    FUNCTION = TreeView_InsertItem(hTree, tTVInsert)
                                END FUNCTION
                                
                                '-------------------------------------------------------------------------------------------------------
                                FUNCTION MakeTV(hd AS DWORD, hTV AS DWORD) AS DWORD
                                    LOCAL r, rUs AS rect
                                    LOCAL szbuf AS ASCIZ * 256
                                    LOCAL l, hroot, happ, hchild AS LONG
                                    LOCAL CurHwnd, child  AS DWORD
                                    LOCAL  szT AS ASCIIZ * 128
                                    DIM Length AS LONG, x AS LONG, y AS LONG
                                
                                    getwindowrect(hD, rUS)  ' get rect of our edit control
                                
                                    ' Trying to find the handle of the View Code Button so that
                                    ' by clicking this program's button, we can see the code
                                    ' window for this form.
                                    CurHwnd = GetDesktopWindow()            'Get Desktop handle
                                    hroot = TreeViewInsertItem(hTV, %NULL, "Desktop")
                                    CurHwnd = GetWindow(CurHwnd, %GW_Child)  'Find Child Windows of Desktop
                                    WHILE CurhWnd <> 0
                                        L = GetWindowTextLength(CurHwnd)
                                        L = GetWindowText(CurHwnd, szT, L + 1)
                                        happ = TreeViewInsertItem(hTV, hroot, TRIM$(szt))
                                
                                        ' Looking now for the Window's child windows
                                        Child = GetWindow(CurHwnd, %GW_Child)
                                
                                        WHILE Child <> 0
                                            IF child <> hd THEN ' don't do it to ourself
                                                getclassname( Child, szbuf, SIZEOF(szbuf))
                                                L = GetWindowTextLength(Child)
                                                L = GetWindowText(Child, szT, L + 1)
                                                hchild = TreeViewInsertItem(hTV, happ, TRIM$(szbuf + ":" + szt))
                                            END IF
                                            Child = GetWindow(Child, %GW_HwndNext) 'Keep looking
                                        WEND
                                        CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                                    WEND
                                END FUNCTION
                                '---------------------------------------------------------------------
                                CALLBACK FUNCTION ShowDIALOG1Proc()
                                    STATIC hText, hTV AS DWORD
                                    LOCAL r AS rect
                                    STATIC intextbox AS pointapi
                                
                                
                                    SELECT CASE AS LONG CBMSG
                                        CASE %WM_INITDIALOG
                                        hTV = getdlgitem(CBHNDL, %IDC_TV)
                                        mAKEtv ( CBHNDL, Htv)
                                        CASE %WM_COMMAND
                                            SELECT CASE AS LONG CBCTL
                                
                                            END SELECT
                                    END SELECT
                                END FUNCTION
                                '-------------------------------------------------------------
                                FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
                                    LOCAL lRslt AS LONG
                                
                                #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
                                    LOCAL hDlg  AS DWORD
                                
                                    DIALOG NEW hParent, "Windows Treeview", 107, 96, 195, 225, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
                                        %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT _
                                        OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                                    CONTROL ADD "SysTreeView32", hDlg, %IDC_TV, "SysTreeView32_1", 5, 5, 185, 215, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR _
                                        %TVS_HASBUTTONS OR %TVS_HASLINES OR %TVS_LINESATROOT OR %TVS_SHOWSELALWAYS, %WS_EX_LEFT OR %WS_EX_CLIENTEDGE OR _
                                        %WS_EX_RIGHTSCROLLBAR
                                #PBFORMS END DIALOG
                                
                                
                                    DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
                                
                                #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
                                #PBFORMS END CLEANUP
                                
                                    FUNCTION = lRslt
                                END FUNCTION
                                
                                '===============================================================
                                FUNCTION PBMAIN()
                                    PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
                                
                                    ShowDIALOG1 %HWND_DESKTOP
                                END FUNCTION

                                Comment


                                • #17
                                  Chris,
                                  sorry for the following code looking weird!
                                  It's too late now to work it out for the forum. But I intended to show You that my first code is running fine finding the checkbox control in the Systab.
                                  I'll send the complete code tomorrow.
                                  I had to add some lines as You can see. It is in a very rough state.
                                  I marked these lines with '# at their end.
                                  The code to be deleted has a hyphen ' at the start of their lines.

                                  Code:
                                  '-------------------------------------------------------------------------------------------------------
                                  ' FUNCTION FindButtonInWindow
                                  '-------------------------------------------------------------------------------------------------------
                                  Function FindButtonInWindow(sWndTitle As String, sBtnText As String) As Dword
                                  	On Error Resume Next
                                  	Dim Btn As Long, CurHwnd As Dword, szT As Asciiz * 128
                                  	Dim Length As Long, x As Long, y As Long 
                                  	Function = 0
                                  	' Trying to find the handle of the View Code Button so that
                                  	' by clicking this program's button, we can see the code
                                  	' window for this form.
                                  	CurHwnd = GetDesktopWindow()             'Get Desktop handle
                                  	CurHwnd = GetWindow(CurHwnd, %GW_Child)  'Find Child Windows of Desktop
                                  	Do
                                  		If CurHwnd = 0 Then Exit Do          'No (more) matches found
                                  		' Find out how long the text in this window is
                                  		Length = GetWindowTextLength(CurHwnd)
                                  		Length = GetWindowText(CurHwnd, szT, Length + 1)
                                  		If InStr(szT, sWndTitle) Then 
                                  			debug "1", szT, sWndTitle, CurHwnd
                                  			MsgBox""
                                  			' The value of sWindowTitle was found in this Window's text
                                  			Local szTabName As Asciiz * 128  						'#
                                  			szTabName = "TxtAtbTab"										'#  the name of the open tab area in SysTab Control
                                  			CurhWnd = FindWindow("", szTabName)						'#
                                  			debug "2", szTabName, szTabName, CurHwnd     		'#
                                  			MsgBox""				                           		'#
                                           Local szChkName As Asciiz * 128  						'#
                                           szChkName = "Layer als Textlayer verwenden"			'#  the name of the text checkbox in SysTab Control
                                           CurhWnd = FindWindowEx(CurHwnd, 0, "", szChkName)	'#
                                  			debug "3", CurhWnd                           		'#
                                  			MsgBox""				                           		'#
                                  				
                                  '            CurHwnd = GetWindow(CurHwnd, %GW_Child)
                                  '            ' Looking now for the Window's child windows
                                  '            Do
                                  '                If CurHwnd = 0 Then Exit Function 'No (more) matches found
                                  '                ' Find out how long the text in this window is
                                  '                Length = GetWindowTextLength(CurHwnd)
                                  '                Length = GetWindowText(CurHwnd, szT, Length + 1)
                                  '                If InStr(szT, sBtnText) Then
                                  'debug "3", szT, sBtnText
                                  '                    ' This is the handle we want
                                  '                    '### Click(CurHwnd)            'Click the View Code Button
                                  '                    Function = CurHwnd
                                  '                    Exit Function                 'Exit the Sub
                                  '                End If
                                  '            CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                                  '            Loop
                                          End If
                                          CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                                      Loop
                                  End Function
                                  Norbert Doerre

                                  Comment


                                  • #18
                                    > either I did it wrong or there are a lot of nameless windows hanging around!

                                    You did it right. I, too, had a (large) bunch of nameless windows whilst testing the "EnumChildWindows" version I posted above.
                                    Michael Mattias
                                    Tal Systems (retired)
                                    Port Washington WI USA
                                    [email protected]
                                    http://www.talsystems.com

                                    Comment


                                    • #19
                                      It is running...

                                      Michael,
                                      the following code finds the hWnd of any control inside a modeless systab control. This is why the function MUST contain 'Dialog DoEvents' in the loop.
                                      If it is not inserted the fucnction does not succeed.
                                      This code has become very small because i avoided to make it 'general'.
                                      So, if for instance the tab areas of the systab control don't have names You have either to scan all tabs by activating them in a loop with 'send' or to use their class name. In the current case I could identify the tab by it's name.
                                      Code:
                                      '-------------------------------------------------------------------------------------------------------
                                      ' FUNCTION FindButtonInWindow
                                      '-------------------------------------------------------------------------------------------------------
                                      Function FindButtonInWindow (sWndTitle As String, sTabName As String, sBtnText As String) As Dword
                                      	'Called by 'VCSetTextUseTextLayer'
                                      	'INPUT:	sWndTitle	= title of the dialog containing the systab control
                                      	'			sTabname		= Name of the systab page area containing the button
                                      	'			sBtnText		= Caption of the button to be searched for
                                      	'OUTPUT:	Handle of the control to be found
                                      	Local CurHwnd As Long
                                      	Local szT As Asciiz * 128
                                      	Local Length As Long
                                      	Local szTabName As Asciiz * 128
                                         Local szChkName As Asciiz * 128
                                      	Local i As Integer
                                      	On Error Resume Next
                                      	Function = 0
                                      	CurHwnd = GetDesktopWindow()             'Get Desktop handle
                                      	CurHwnd = GetWindow(CurHwnd, %GW_Child)  'Find Child Windows of Desktop
                                      	Do Until CurHwnd = 0
                                      		Dialog DoEvents 'Important to give some loop time
                                      		Length = GetWindowTextLength(CurHwnd)
                                      		Length = GetWindowText(CurHwnd, szT, Length + 1)
                                      		If InStr(szT, sWndTitle) Then 
                                      			szTabName = sTabName	'the name of the open tab area in SysTab Control
                                      			CurhWnd = FindWindow("", szTabName)
                                               szChkName = sBtnText 'the name of the text checkbox in SysTab Control
                                               CurhWnd = FindWindowEx(CurHwnd, 0, "", szChkName)
                                      			If CurHwnd Then Function = CurHwnd
                                             End If
                                             CurHwnd = GetWindow(CurHwnd, %GW_HwndNext) 'Keep looking
                                         Loop
                                      End Function
                                      Norbert Doerre

                                      Comment


                                      • #20
                                        Well, if what you have ain't working, try it the way I wrote it. My method doesn't give a hoot about DDT SDK or DIALOG DOEVENTS or CurHwnd=0 loops.

                                        It's not like the CALL syntax I came up with is terribly complicated or anything.

                                        However, if you have to drill down more than one level (ie beyond simple parent-child) then that function has to be rewritten to recurse, which for sure I can't get to until I get back from vacation.

                                        MCM
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X