Announcement

Collapse
No announcement yet.

Auto click Yes or Alt-Y in another window

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

  • Auto click Yes or Alt-Y in another window

    Is it possible to find the Foreground Window, even if not created by your program and then find the yes button and click it.

    Bob Mechler

  • #2
    Did you see William Burns SendKeys?
    PowerBASIC and related source code. Please do not post questions or discussions, just source code.
    Rgds, Dave

    Comment


    • #3
      Thanks, I can see a ton of usages for this.

      Bob Mechler

      Comment


      • #4
        If you are looking to click a "YES" button on the foreground window, you can use a function like this. I stripped down one that I have used in the past.

        Code:
        #Dim All
        #Compile Exe
        #Include "WIN32API.INC"
        
        '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
        ' Enum all Child Windows callback
        '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
        Function EnumChildWin(ByVal hWnd AS Dword, ByVal dFlags AS Dword) AS Long
           Local iCount      As Long
           Local iRet        As Long
           Local sText       As String
           Local sLabel      As String
           Local hData       As Long
           Local hGlob       As Long
           Local zText       As Asciiz * %MAX_PATH
           Local iStyle      As Long
           GetClassName hWnd, zText, SizeOf(zText)		'get the class name to see if this is a button
           iStyle = GetWindowLong(hWnd, %GWL_STYLE)
           If zText = "Button" And ((iStyle And %BS_GROUPBOX) <> %BS_GROUPBOX) And IsWindowVisible(hWnd) Then
              If GetWindowText(hWnd, zText, ByVal %MAX_PATH) Then	'get the text for this item
                 sText = Remove$(Trim$(zText), "&")              'remove the accel symbols
        	  IF UCASE$(sText) = "YES" THEN   'YES button found
        		'GetWindowText(GetParent(hWnd), zText, ByVal %MAX_PATH)	'get the parent windows text to store in log
        		'LogThis "Clicking Button [" + sText + "] on " + zText		'send a message to our log
        		PostMessage hWnd, %BM_CLICK, 0, 0   'send the button a click message
        	  End If
              End If
           End If
           Function = %TRUE   'return TRUE to continue listing child windows
        End Function
        
        '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
        Function PBMain()
        	LOCAL hTopWin		AS DWORD
        	hTopWin = GetForegroundWindow()
        	if hTopWin Then
        		Call EnumChildWindows(hTopWin, CodePtr(EnumChildWin), 0)   'go through each item under the main window
        	End If
        End Function
        '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
        "I haven't lost my mind... its backed up on tape... I think??" :D

        Comment


        • #5
          Originally posted by BOB MECHLER View Post
          Thanks, I can see a ton of usages for this.

          Bob Mechler
          Take note of the disclaimer. Many things can go wrong if you don't use Journal Playback.

          James

          Comment


          • #6
            William,

            How can I test your code? I tried
            Code:
                Local x&
                x = MsgBox ("Testing William", %MB_YESNO, "Click Yes")
            in PBMain, If I don't click either one then I don't get to Call EnumChildWindows. If I do click either one, the Msgbox disappears so Enum doesn't see it.

            I tried setting a Msgbox in another program and then ran yours and it found the MB ("GTi_Button"), but it stays on it and I have to ACD your program.

            So just for fun I played around with your code and added a clipboard listing all the processes. Be old hat to you old dog experienced guys but some Newbies (and Dumbies like me) might find it interesting.


            Note, I found your Enum (decently commented) routine much simpler to follow than one I have been using (Peter L's?) for some time. His seemes to have a lot more API calls. (Probably does a lot more too that I don't use.) Thanks.

            Code:
            #Dim All
            #Compile Exe
            #Include "WIN32API.INC"
             
            '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
            ' Enum all Child Windows callback
            '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
            Global x&, s$, Last_s$, Class_ctr&, Everything$ '<<< Global just easier here for this example
            Macro Into_CLipboard
                  s$ = Left$(zText, Len(zText) -1) & $CrLf  'strip null
                '   s$ = s$ & "   " & sLabel & $CrLf  
                '   s$ = s$ & "   " & sText & $CrLf  
                  Incr Class_ctr 
                   If s$ <> Last_s$ Then
                      Everything$ = Everything$ & Using$("# Instances of ", Class_ctr) & s$ & $CrLf 
                      Reset Class_ctr     
                   End If      
                   Last_s$ = s$
            End Macro
             
            Function EnumChildWin(ByVal hWnd As Dword, ByVal dFlags As Dword) As Long
               Local iCount      As Long
               Local iRet        As Long
               Local sText       As String
               Local sLabel      As String
               Local hData       As Long
               Local hGlob       As Long
               Local zText       As Asciiz * %MAX_PATH
               Local iStyle      As Long
               GetClassName hWnd, zText, SizeOf(zText)  'get the class name to see if this is a button
               iStyle = GetWindowLong(hWnd, %GWL_STYLE)
                 Into_Clipboard
               If zText = "Button" And ((iStyle And %BS_GROUPBOX) <> %BS_GROUPBOX) And IsWindowVisible(hWnd) Then
            '      Into_Clipboard
                  If GetWindowText(hWnd, zText, ByVal %MAX_PATH) Then 'get the text for this item
                     sText = Remove$(Trim$(zText), "&")              'remove the accel symbols
               If UCase$(sText) = "YES" Then   'YES button found
              'GetWindowText(GetParent(hWnd), zText, ByVal %MAX_PATH) 'get the parent windows text to store in log
              'LogThis "Clicking Button [" + sText + "] on " + zText  'send a message to our log
              PostMessage hWnd, %BM_CLICK, 0, 0   'send the button a click message
               End If
                  End If
               End If
               Function = %TRUE   'return TRUE to continue listing child windows
            End Function
             
            '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
            Function PBMain()
             Local hTopWin  As Dword   
             hTopWin = GetForegroundWindow()
             If hTopWin Then
              Call EnumChildWindows(hTopWin, CodePtr(EnumChildWin), 0)   'go through each item under the main window
             End If
             
               ClipBoard Set Text Everything$ To x 
                ? Everything$,, "Also in Clipboard"
            End Function
            '==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==~==
            ========================================
            "Women might be able to fake orgasms.
            But men can fake a whole relationship."
            Sharon Stone
            ========================================
            Last edited by Gösta H. Lovgren-2; 28 Sep 2008, 11:21 PM. Reason: Insert the blank readability lines (LF's) PB deletes
            It's a pretty day. I hope you enjoy it.

            Gösta

            JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
            LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

            Comment


            • #7
              William's code should work fine but should it not, is there a really good example of the journal playback you talked about. I'm not familiar with it. I'll search the boards.

              One use I have in mind is to auto click that prompt that comes up in Outlook when less than a Domain Admin runs a program that attempts to send an Email using Outlook COM Dispatch.

              Using a starter example by Stavros in Poffs and looking at some VB code that would send Emails from the Draft folder, I got it working on my machine. However on the secretary's machine it would always prompt that another program was trying to send an email. Alt-Y sent by the application with a 5-7 second wait would clear or so I'm guessing.

              The other method I was thinking of would be instead of sending them, just display 1 at a time and send Alt-S (Send) to send them very quickly without the 5-7 second wait. Don't know if that will cause the prompt to come up or not just yet. I'll have to see.

              This particular customer wants about 300 statements with pdf statement emails attachments to go out at night. They want to use outlook to move the items to monthly folders for easy reference from the sent folder. A normal Domain user and not an Admin will do the mailing.

              I've seen at least one product that fools with the built-in Outlook security where the user is a plain Domain user and have the nag message not come up. I think that might be resisted by security conscious IT people.

              Bob Mechler

              Comment


              • #8
                Originally posted by Gösta H. Lovgren-2 View Post
                William,

                How can I test your code?...
                He wanted to click on the Yes button for the foreground window, not his own program. So to test the code, you could put a sleep 10000 at the front of the PBMain. This would give you 10 seconds after you run the program to open another program that asks a Yes/No question. Then just wait for it to answer.

                Bob, as for JournalPlayback. I can try to make a simple example to post. But if you want to research it, here is the main command to read up on:
                Code:
                SetWindowsHookEx(%WH_JOURNALPLAYBACK, CODEPTR(PlayHookProc), GetModuleHandle(BYVAL 0), 0)
                The Journal playback works from a record/playback methodology which makes it a little harder to work with dynamically in program. (change what to send on the fly) Which is why I have had better success using the SendKeys code. And (personally speaking) I have had issues with Journal playback not capturing all the keystrokes on some programs. (I did not spend a lot of time investigating the problem though, so it was probably something I was doing wrong.) But after work tomorrow I will see if I can put together a simple example of Journal playback. Journal playback does have several advantages, like sending messages directly to the target windows msg queue and locking the keyboard/mouse while it runs so the user does not interfere with the keystrokes. (although sometimes locking the keyboard/mouse while it runs is not the desired affect, so...)
                "I haven't lost my mind... its backed up on tape... I think??" :D

                Comment


                • #9
                  Thanks so much for pointing out the different options. I'll research the issue but frankly you have to wade through a lot of unrelated posts to find the really good ones.

                  Bob Mechler

                  Comment


                  • #10
                    Originally posted by William Burns View Post
                    He wanted to click on the Yes button for the foreground window, not his own program. So to test the code, you could put a sleep 10000 at the front of the PBMain. This would give you 10 seconds after you run the program to open another program that asks a Yes/No question. Then just wait for it to answer.
                    William, That works fine. I was expecting it close an already existing button but it doesn't do that.

                    Thanks your prompt reply.

                    =================================
                    "If you can't annoy somebody,
                    there's little point in writing."

                    Anonymous
                    =================================
                    It's a pretty day. I hope you enjoy it.

                    Gösta

                    JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                    LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                    Comment


                    • #11
                      Here is the example of the Journal Playback that I promised. As you will see after playing with it, it seems to miss some keys/mouse clicks. I am not sure if it has to do with timing issues or what. I will see if I can take some time to look over the API docs to see if I am doing something wrong. But I remember playing with it years ago and could not get it to be as reliable as I wanted. Plus take a look at the large keylog file it creates... like I said earlier, it is much harder to adjust this dynamically from inside your program. That is why I created the SendKeys code.

                      Code:
                      #COMPILE EXE
                      #DIM ALL
                       
                      #INCLUDE "WIN32API.INC"
                       
                      %IDD_DIALOG1   =  101
                      %IDC_BUTRECORD = 1005
                      %IDC_BUTPLAY   = 1010
                      %IDC_BUTSTOP   = 1015
                      %IDC_FRAME1    = 1020
                      %IDC_TXTFILE   = 1025
                      %IDC_BUTBROWSE = 1030
                      %IDC_LABMSG    = 1035
                      DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
                       
                      global ghDlg       as dword
                      global ghFile      As DWORD
                      global ghHook      as dword
                      GLOBAL giStop      as long
                       
                       
                      '--------------------------------------------------------------------------------
                      FUNCTION RecHookProc(BYVAL iCode AS LONG,  BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
                         Local EM          AS EventMsg PTR
                         if ghFile =0 or giStop then   'insure we have a valid file and we have not pressed stop
                            If ghHook then UnhookWindowsHookEx ghHook
                            if ghFile then CLOSE ghFile
                            ghFile = 0
                            ghHook = 0
                            Control Set Text ghDlg, %IDC_LABMSG, "Record stopped"
                            EXIT FUNCTION
                         end if
                         SELECT CASE iCode
                            CASE %HC_ACTION
                               EM = lParam
                               PRINT #ghFile, STR$(@EM.message) & $TAB & STR$(@EM.paramL) & $TAB & STR$(@EM.paramH) & $TAB & STR$(@EM.time) & $TAB & STR$(@EM.hWnd)
                         END SELECT
                         IF iCode < 0 THEN FUNCTION = CallNextHookEx (CODEPTR(RecHookProc), icode, wParam, lParam)
                      END FUNCTION
                      '--------------------------------------------------------------------------------
                       
                      '--------------------------------------------------------------------------------
                      FUNCTION PlayHookProc(BYVAL iCode AS LONG,  BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
                         Local EM          AS EventMsg PTR
                         local sText      as string
                         if ghFile =0 or EOF(ghFile) or giStop then   'check to see if we have more to read from file or we pressed stop
                            If ghHook then UnhookWindowsHookEx ghHook
                            if ghFile then CLOSE ghFile
                            ghFile = 0
                            ghHook = 0
                            Control Set Text ghDlg, %IDC_LABMSG, "Playback stopped"
                            EXIT FUNCTION
                         end if
                         SELECT CASE iCode
                            CASE %HC_GETNEXT
                               Line INPUT #ghFile, sText
                               SLEEP 25   'playback a little slower
                               EM = lParam
                               @EM.message = VAL(parse$(sText, $TAB, 1))
                               @EM.paramL  = VAL(parse$(sText, $TAB, 2))
                               @EM.paramH  = VAL(parse$(sText, $TAB, 3))
                               @EM.time    = VAL(parse$(sText, $TAB, 4))
                               @EM.hWnd    = VAL(parse$(sText, $TAB, 5))
                         END SELECT
                         
                         IF iCode < 0 THEN FUNCTION = CallNextHookEx(CODEPTR(PlayHookProc), icode, wParam, lParam)
                      END FUNCTION
                      '--------------------------------------------------------------------------------
                       
                       
                       
                       
                      '------------------------------------------------------------------------------
                      CALLBACK FUNCTION ShowDIALOG1Proc()
                         local sFile      as string
                         SELECT CASE AS LONG CBMSG
                            CASE %WM_CLOSE
                               If ghHook then UnhookWindowsHookEx ghHook
                               if ghFile then CLOSE ghFile
                               
                            CASE %WM_COMMAND
                               SELECT CASE AS LONG CBCTL
                                  CASE %IDC_BUTRECORD
                                     IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 and ghHook = 0 THEN
                                        control get text ghDlg, %IDC_TXTFILE to sFile
                                        try
                                           sleep 500
                                           giStop = 0
                                           ghFile = FreeFile
                                           Open sFile for OutPut as #ghFile
                                           ghHook = SetWindowsHookEx(%WH_JOURNALRECORD, CODEPTR(RecHookProc), GetModuleHandle(BYVAL 0), 0)
                                           Control Set Text ghDlg, %IDC_LABMSG, "Recording."
                                        catch
                                           msgbox Error$(Err),,"Error opening file"
                                        end try
                                     END IF
                                     
                                  CASE %IDC_BUTPLAY
                                     IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 and ghHook = 0 THEN
                                        control get text ghDlg, %IDC_TXTFILE to sFile
                                        try
                                           sleep 500
                                           giStop = 0
                                           ghFile = FreeFile
                                           Open sFile for InPut as #ghFile
                                           ghHook = SetWindowsHookEx(%WH_JOURNALPLAYBACK, CODEPTR(PlayHookProc), GetModuleHandle(BYVAL 0), 0)
                                           Control Set Text ghDlg, %IDC_LABMSG, "Playing."
                                        catch
                                           msgbox Error$(Err),,"Error opening file"
                                        end try
                                     END IF
                                     
                                  CASE %IDC_BUTBROWSE
                                     IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 AND ghHook = 0 THEN
                                        'NOTE: if you dont have PB9 you can remark out the following 2 lines which only let you browse for a file
                                        DISPLAY SAVEFILE ghDlg,,, "Choose keylog file", "", CHR$("Log File", 0, "*.LOG", 0), CURDIR$, "LOG", %OFN_NOCHANGEDIR TO sFile
                                        if mid$(sFile,2,1) = ":" then control set text ghDlg, %IDC_TXTFILE, sFile
                                     END IF
                                     
                                  CASE %IDC_BUTSTOP
                                     IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 AND ghHook <> 0 and giStop = %FALSE THEN
                                        giStop = %TRUE
                                        Control Set Text ghDlg, %IDC_LABMSG, "Aborting."
                                     END IF
                                     
                                  CASE %IDC_LABMSG
                                     
                               END SELECT
                         END SELECT
                      END FUNCTION
                      '------------------------------------------------------------------------------
                       
                      '------------------------------------------------------------------------------
                      FUNCTION PBMain() as LONG
                         LOCAL hDlg  AS DWORD
                         
                         DIALOG NEW 0, "Journal Playback", 115, 103, 213, 48, %WS_POPUP OR _
                         %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
                         %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME _
                         OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
                         %WS_EX_CONTROLPARENT OR %WS_EX_TOPMOST OR %WS_EX_LEFT OR _
                         %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
                         CONTROL ADD BUTTON,  hDlg, %IDC_BUTRECORD, "&Record", 5, 5, 35, 15
                         CONTROL ADD BUTTON,  hDlg, %IDC_BUTPLAY, "&Playback", 40, 5, 35, 15
                         CONTROL ADD BUTTON,  hDlg, %IDC_BUTSTOP, "&Stop", 80, 5, 35, 15
                         CONTROL ADD FRAME,   hDlg, %IDC_FRAME1, "Record/Playback file:", 5, 20, 205, 25
                         CONTROL ADD TEXTBOX, hDlg, %IDC_TXTFILE, "KeyStrokes.txt", 10, 30, 175, 10
                         CONTROL ADD BUTTON,  hDlg, %IDC_BUTBROWSE, "...", 190, 30, 15, 10
                         CONTROL ADD LABEL,   hDlg, %IDC_LABMSG, "", 125, 5, 80, 15, %WS_CHILD OR _
                         %WS_VISIBLE OR %SS_CENTER OR %SS_NOTIFY OR %SS_SUNKEN, %WS_EX_LEFT OR %WS_EX_LTRREADING
                      
                         ghDlg = hDlg
                         
                         DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc
                         
                      END FUNCTION
                      '------------------------------------------------------------------------------
                      "I haven't lost my mind... its backed up on tape... I think??" :D

                      Comment


                      • #12
                        Gosta has a legit use of sorts (unless I misread)

                        I've seen at least one product that fools with the built-in Outlook security where the user is a plain Domain user and have the nag message not come up. I think that might be resisted by security conscious IT people.
                        Count me in on that!!!!!!!!!!!!
                        On the other side, if I were the one trying to mass and not spam then I guess I would be asking the same question??? (could be handy, but unless you have full control, forget about it *LOL*)
                        Engineer's Motto: If it aint broke take it apart and fix it

                        "If at 1st you don't succeed... call it version 1.0"

                        "Half of Programming is coding"....."The other 90% is DEBUGGING"

                        "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                        Comment


                        • #13
                          ContextMagic had a program called ClickYes for free with their pro version costing 39.95.

                          The pro version can be set up to limit disabling the security nag message to certain programs only (the ones that do the mass mailing of statements with pdfs).

                          Anybody heard of this program? We are looking to advise people to use it if they have the problem. I'm a little wary.

                          Bob Mechler

                          Comment

                          Working...
                          X