Help, with AppActivate

fox_adel
fox_adel used Ask the Experts™
on
I am using VB6.

I am using AppActivate to activate an application. Then I use the the SendKeys to start aapplication macro. But in the macro a sub-window opens up, so when I do another SendKeys(file save) nothing happens.

Any ideas?

Thanks,

fox_adel

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
why not use appactivate again before doing the second sendkeys ??
You're going to need to obtain the new window handle, then appactivate it also.

Use FindWindow/FindWindowEx to get the handle:

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Or if you know the title of the window that popped up(always the same) AND it appears in the Taskbar, you can use appactivate on the new title window, then send the next set of keystrokes


Author

Commented:
muskad202,

tried it. still no response.

twalgrave,

I check that info out.

>>"Or if you know the title of the window that popped up(always the same) AND it appears in the Taskbar, you can use appactivate on the new title window, then send the next set of keystrokes"<<

Yeah, the sub-window does come up in the task bar.  But the macro also closes that window, so it no longer exsists.
Can I still use the FindWindow?
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
Was the macro built in a Microsoft Office application?  If so you can use the Application.Run method.  I'm not sure if you can use this method outside of Microsoft applications but it's probably worth a try.

Here's an example of how you could run an excel macro from VB:

First you would have to set a reference to the Microsoft Excel Object Library.  (Tools / References)

In your code you could do something like this:


Sub RunMacro()

    Excel.Application.Run FileName.xls!MacroName

End Sub

You can also pass parameters if you need to.
Well,  if you want to send keys to that window, you gotta send them while it is open.  If the result of the keystrokes or subsequent ones close the windows afterwards, it's fine.  How would you expect to send a message to a window that closed AFTER it closed?

Author

Commented:
jbauer22,
The application is not an MS product.

twalgrave,
I'm not trying to send any keys to the sub-window.  Infact the macro opens up this sub-window, then closes it, and continues on doing other macro stuff to the application.  But when VB is ready to excute the next SendKeys, the application is not active any more.

So will the FindWindow still work?

Thanks for the input, experts.

Author

Commented:
twalgrave,

I get a compile error when I pasted:
>>Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long<<

I am very new to VB, do i have to have a reference loaded?

Commented:
Was the macro built in a Microsoft Office application?  If so you can use the Application.Run method.  I'm not sure if you can use this method outside of Microsoft applications but it's probably worth a try.

Here's an example of how you could run an excel macro from VB:

First you would have to set a reference to the Microsoft Excel Object Library.  (Tools / References)

In your code you could do something like this:


Sub RunMacro()

    Excel.Application.Run FileName.xls!MacroName

End Sub

You can also pass parameters if you need to.
fox_adel,

No you don't need to provide any references.  Chances are that you you received the "Contants, fixed-length strings...error".  What this means is that the Public should be changed to private in certain circumstances.
also, the declaration should appear in the General Declarations segment, not in a code segment like Command1_Click.

Author

Commented:
twalgrave,

I get a compile error when I pasted:
>>Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long<<

I am very new to VB, do i have to have a reference loaded?

Author

Commented:
twalgrave,

I get a compile error when I pasted:
>>Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long<<

I am very new to VB, do i have to have a reference loaded?
try not to use refresh on the page.  Go up and to the left and select "Reload this question" to get it to refresh.

Author

Commented:
twalgrave,

I get a compile error when I pasted:
>>Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long<<

I am very new to VB, do i have to have a reference loaded?

Author

Commented:
>>try not to use refresh on the page<<
oops, sorry about that. Just registered to today with ExpertsExchange. I'm such a Stupid newbie, lol

twalgrave,
I have other clicks to do before the final excute click in the form. I am able to change drive and folder, but other clicks in form are non-responsive.

I have added to the general area:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

I also tried adding to general area and in the excute click:
hWndProE = FindWindow(vbNullString, sApplication)

So what do you think?
we're running around in circles here.  Do you have sample code?

Author

Commented:
Option Explicit

    Dim sMapFile As String          ' MapKey Files
    Dim sMapKey As String           ' MapKey to run
    Dim bDrawing As Boolean         ' Is this file a Drawing
    Dim sCadkeyFile As String
    Dim sIgsFile As String
    Dim sDwgFile As String
    Dim sDxfFile As String
    Dim sCTemp As String
    Dim sCadkeyTemp As String
    Dim sIgsTemp As String
    Dim sDwgTemp As String
    Dim sDxfTemp As String
    Dim sPurgeFile As String
    Dim iFindChar As Integer
    Dim sFile As String
    'Dim sFilePeriod As String
    Dim sFileLoc As String
    Dim iYNcont As Integer
    Dim fs As New FileSystemObject
    Dim fso, txtfile
    Dim lFileLoop As Long
    Dim lMainFreeFile As Long
    Dim lFreeFile As Long
    Dim sFileText As String
    Dim sTextLine As String
    Dim sFileName As String
    Dim sILoadDir As String
    Dim sFile2 As String
    Dim PauseTime, Start    ' For Delays
   
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    'hWndProE = FindWindow(vbNullString, "Pro/ENGINEER")
   

Private Sub Form_Load()
    ' Check For Admin Log In
    iYNcont = MsgBox("Are you Logged in as Admin?", vbYesNo, "Continue")
    If iYNcont = vbNo Then
        End
    End If
   
    ' "Start in" Directory for Pro/ENGINEER
    ChDrive "C"
    ChDir "C:\ptc"
   
    ' Is Pro/ENGINEER started?
    iYNcont = MsgBox("Is Pro/ENGINEER started?" & (Chr(13)) & (Chr(13)) & "Note: Pro/ENGINEER needs to be MAXIMIZED", vbYesNo, "Continue")
    If iYNcont = vbNo Then
        ExecCmd "d:\ptc\proe\bin\proe.bat"  'Start Pro/Engineer
        ' Delay for Pro/E Start
        PauseTime = 20  ' Set duration.
        Do While Timer < Start + PauseTime
            DoEvents   ' Yield to other processes.
        Loop
    End If
End Sub

Private Sub Drive1_Change()
    Dir1.Path = Drive1.Drive
End Sub

Private Sub Dir1_Change()
    File1.Path = Dir1.Path
End Sub

Private Sub Type_DRW_Click()
    File1.Pattern = "*.drw.*"
    sMapFile = "c-file.txt"
    bDrawing = True
End Sub

Private Sub Type_F_ASM_Click()
    sMapFile = "fab-asm.txt"
    File1.Pattern = "*.asm.*"
    sMapKey = "batfa"
    bDrawing = False
End Sub

Private Sub Type_F_PRT_Click()
    sMapFile = "fab-prt.txt"
    File1.Pattern = "*.prt.*"
    sMapKey = "batfp"
    bDrawing = False
End Sub

Private Sub Type_P_ASM_Click()
    sMapFile = "pur-asm.txt"
    File1.Pattern = "*.asm.*"
    sMapKey = "batpa"
    bDrawing = False
End Sub

Private Sub Type_P_PRT_Click()
    sMapFile = "pur-prt.txt"
    File1.Pattern = "*.prt.*"
    sMapKey = "batpp"
    bDrawing = False
End Sub

Private Sub Excute_Click()
   
 
    sCTemp = "c:\temp\"                             ' Temp Dir
    sCadkeyTemp = sCTemp & "*.prt"                  ' Temp Dir with CADKEY Files-created for CopyFile
    sIgsTemp = sCTemp & "*.igs"                     ' Temp Dir with IGS Files-created for CopyFile
    sDwgTemp = sCTemp & "*.dwg"                     ' Temp Dir with DWG Files-created for CopyFile
    sDxfFile = sCTemp & "*.dxf"                     ' Temp Dir with DXF Files-created for CopyFile
    'sFileLoc = "P:\brent_f\bat-test"                ' Where Programs files are located at
    sPurgeFile = sFileLoc & "\" & "up-purge.bat"    ' Where the Purge Dir and file located
    lMainFreeFile = FreeFile

    ' Handling for if selected dir is at the root of a drive
    If Len(Dir1.Path) = 3 Then
    sCadkeyFile = Dir1.Path & "*.prt"           ' Selected Directory with CADKEY File
    sIgsFile = Dir1.Path & "*.igs"              ' Selected Directory with IGS File
    sDwgFile = Dir1.Path & "*.dwg"              ' Selected Directory with DWG File
    sDxfFile = Dir1.Path & "*.dxf"              ' Selected Directory with DXF File
    Else
    sCadkeyFile = Dir1.Path & "\" & "*.prt"
    sIgsFile = Dir1.Path & "\" & "*.igs"
    sDwgFile = Dir1.Path & "\" & "*.dwg"
    sDxfFile = Dir1.Path & "\" & "*.dxf"
    End If

    ' Set Drive and Directory
    ChDrive Drive1.Drive
    ChDir Dir1.Path
   
   
    Dim strLine As String
    Dim strVar As String
    Dim i As Integer
       
    ' Change Working Directory
    AppActivate "Pro/ENGINEER", True        ' Activate Application - CANNOT be MINIMIZED
    SendKeys "%(fw)", True                  ' Set the Program directory
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5 ' Set duration.
    Do While Timer < Start + PauseTime
        DoEvents   ' Yield to other processes.
    Loop
    SendKeys Dir1.Path & "\", True                ' Change directory to file list
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5  ' Set duration.
    Do While Timer < Start + PauseTime
        DoEvents   ' Yield to other processes.
    Loop
    SendKeys "~", True                      ' Enter key
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5  ' Set duration.
    Do While Timer < Start + PauseTime
        DoEvents   ' Yield to other processes.
    Loop
    SendKeys "{TAB}", True                      ' Enter key
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5  ' Set duration.
    Do While Timer < Start + PauseTime
        DoEvents   ' Yield to other processes.
    Loop
    SendKeys "{TAB}", True                      ' Enter key
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5  ' Set duration.
    Do While Timer < Start + PauseTime
        DoEvents   ' Yield to other processes.
    Loop
    SendKeys "{TAB}", True                      ' Enter key
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5  ' Set duration.
    Do While Timer < Start + PauseTime
        DoEvents   ' Yield to other processes.
    Loop
    SendKeys "~", True                      ' Enter Key
    ' delay
    Start = Timer   ' Set start time.
    PauseTime = 0.5  ' Set duration.
    Do While Timer < Start + PauseTime
         DoEvents   ' Yield to other processes.
    Loop
    'SendKeys "~", True                      ' Enter Key
    ' delay
    'Start = Timer   ' Set start time.
    'PauseTime = 0.5  ' Set duration.
    'Do While Timer < Start + PauseTime
         'DoEvents   ' Yield to other processes.
    'Loop
        For lFileLoop = 0 To File1.ListCount - 1
            If bDrawing = True Then
                Open File1.List(lFileLoop) For Input As 1
                    Do While Not EOF(1)
                    Line Input #1, strLine
                    i = InStr(1, strLine, "SIZE")
                        If i <> 0 Then
                            strVar = Mid(strLine, i - 2, 1)
                            Exit Do
                        End If
                    Loop
                Close 1
                If strVar = "B" Then
                    sMapKey = "batdb"
                ElseIf strVar = "C" Then
                    sMapKey = "batdc"
                ElseIf strVar = "D" Then
                    sMapKey = "batdd"
                ElseIf strVar = "E" Then
                    sMapKey = "batde"
                End If
            End If
            ' delay
            'Start = Timer   ' Set start time.
            'PauseTime = 0.5  ' Set duration.
            'Do While Timer < Start + PauseTime
                'DoEvents   ' Yield to other processes.
            'Loop
            SendKeys "^(o)", True                   ' Open File
            ' delay
            Start = Timer   ' Set start time.
            PauseTime = 0.5  ' Set duration.
            Do While Timer < Start + PauseTime
                DoEvents   ' Yield to other processes.
            Loop
            SendKeys File1.List(lFileLoop), True    ' File in File List
            ' delay
            Start = Timer   ' Set start time.
            PauseTime = 0.5  ' Set duration.
            Do While Timer < Start + PauseTime
                DoEvents   ' Yield to other processes.
            Loop
            SendKeys "~", True                      ' Enter Key
            ' delay
            Start = Timer   ' Set start time.
            PauseTime = 0.5  ' Set duration.
            Do While Timer < Start + PauseTime
                DoEvents   ' Yield to other processes.
            Loop
            SendKeys "~", True                      ' Enter Key for Generic
            ' delay
            Start = Timer   ' Set start time.
            PauseTime = 3  ' Set duration.
            Do While Timer < Start + PauseTime
                DoEvents   ' Yield to other processes.
            Loop
            SendKeys sMapKey, True                  ' Process Macro
            ' delay
            Start = Timer   ' Set start time.
            PauseTime = 10  ' Set duration.
            Do While Timer < Start + PauseTime
                DoEvents   ' Yield to other processes.
            Loop
           
            'AppActivate "Pro/ENGINEER"        ' Activate Application - CANNOT be MINIMIZED
            SendKeys "%(fs)", True                   ' Save File in File List
            ' delay
            Start = Timer   ' Set start time.
            PauseTime = 0.5  ' Set duration.
            Do While Timer < Start + PauseTime
                DoEvents   ' Yield to other processes.
            Loop
            'SendKeys "~", True                      ' Enter Key
            ' delay
            'Start = Timer   ' Set start time.
            'PauseTime = 0.5  ' Set duration.
            'Do While Timer < Start + PauseTime
                'DoEvents   ' Yield to other processes.
            'Loop
            'SendKeys "%(fec)", True                 ' Erase Program Memory
            ' delay
            'Start = Timer   ' Set start time.
            'PauseTime = 0.5  ' Set duration.
            'Do While Timer < Start + PauseTime
                'DoEvents   ' Yield to other processes.
            'Loop
            'SendKeys "~", True                      ' Enter Key
            ' delay
            'Start = Timer   ' Set start time.
            'PauseTime = 0.5  ' Set duration.
            'Do While Timer < Start + PauseTime
                'DoEvents   ' Yield to other processes.
            'Loop
        Next lFileLoop

Author

Commented:
The sMapKey is the macro call.

hope this helps, thanks.
OK now which sendkeys work and when do they stop?

Author

Commented:
SendKeys sMapKey, True                  ' Process Macro
           ' delay
           Start = Timer   ' Set start time.
           PauseTime = 10  ' Set duration.
           Do While Timer < Start + PauseTime
               DoEvents   ' Yield to other processes.
           Loop
           
           'AppActivate "Pro/ENGINEER"        ' Activate Application - CANNOT be MINIMIZED
           SendKeys "%(fs)", True                   ' Save File in File List

SendKeys sMapKey
is the macro call. In this macro, a subwindow opens up, subwindow does it's thing, then closes the subwindow. after the subwindow is closed the macro finishes it's business. (Macro runs fine)

Then VB next command comes

SendKeys "%(fs)", True
VB does not send a file save to the application.
(This SendKeys stops working)

What I have notice, when placing a break after the >>SendKeys sMapKey, True,<< is when I manually click Alt+F+S, it's the File pull down menu from VB.

I have placed the break after other SendKeys and the application is active, not VB.  So I am guessing that when that subwindow opens up, it loses the AppActivate.

So what do you think?
Thanks.

I agree.
I see the Appactivate commented out just before the Sendkeys "%s".  Was this the result of attempting to do the appactivate like muskad202 suggested or is it supposed to be in there.  Also note that the Program's title bar could change as a result of the save, so the appactivate may drop off because of that.  If you know in advance what the title is going to be, reissue the appactivate what the new title of the app is.  If not, we have to get more creative.

Author

Commented:
>>I see the Appactivate commented out just before the Sendkeys "%s".  Was this the result of attempting to do the appactivate like muskad202 suggested or is it supposed to be in there<<

Yeah that was a attempt.  The result is the it would not do the next SendKeys until I click on the VB form in the taskbar.
It acts like a step function, which is unacceptable. But it does go to the next SendKeys.

>>Also note that the Program's title bar could change as a result of the save, so the appactivate may drop off because of that<<

Yeah the title does change, but >>Pro/ENGINEER<< is still in the title and verified that it does work.

twalgrave, thanks for help me out.  I like VB, I just wish I knew more.
Try performing an activate me.caption in the code, then Appactivate PRO/ENGINEER.

Author

Commented:
Looking up me.caption.  Bare with me, I'm a newb.
Activates itself. Me references the form in this case and .caption references the title.

Author

Commented:
I'm a little confused.
>> Me references the form << What do you mean by reference?
>>.caption references the title<< Is Pro/ENGINEER the title?



In VB help they show these Examples:
Sub Form_Load()
   Me.Caption = ShowDialog(Me.Caption)
End Sub


Private WithEvents mdgs As Dialogs
Private Sub mdgs_NotifyClients(Byval Data As String)
   Me.Caption = Data
End Sub

Private Sub Form_Click()
   If mdgs Is Nothing Then
      Set mdgs = New Dialogs
   End If
   mdgs.ShowDialog Me.Caption, False
End Sub

What I mean by "references the form" it means, the keyword Me (in this instance) is like a variable that points to the form itself (i.e. Setting me.width = 100 is equivalent to Setting Form1.width = 100).
So one can conclude that me.caption retrieves the caption of the current form (it would be the equivalent to saying Form1.Caption), but since each form is named differently, VB has allowed us to use a special word (Me) so we don't have to type in the form name each time.

Note:  Me doesn't only refer to forms, I'll leave that homework up to you.

Author

Commented:
I used:
AppActivate Me.Caption, True
AppActivate "Pro/ENGINEER", True

Same result as before,
The Macro completes run. No action happens for the SendKeys for Save File(next step), until I click on the VB Form in the Win task bar, then A File Save happens in Pro/Engineer.

Without AppActivate "Pro/ENGINEER", true Visual Basic Application is active after macro run.


Note:
With AppActivate "Pro/ENGINEER", When the Marco Completes, Pro/Engineer is activated, I am able to Manually key in ALT+f+s(File Save) and it does work the way I want it to.

Author

Commented:
Another Clue:

With AppActivate "Pro/ENGINEER", true
Pro/Engineer is active but waits until VB form in Win Task Bar is click. then SendKeys is sent to Pro/Engineer.

With AppActivate "Pro/ENGINEER"
Visual Basic is active, SendKeys is sent to Visual Basic.

Author

Commented:
I found the problem.

SendKeys sMapKey, True                  ' Process Macro
' delay
Start = Timer   ' Set start time.
PauseTime = 10  ' Set duration.
Do While Timer < Start + PauseTime
 DoEvents   ' Yield to other processes.
Loop

I increased the PauseTime. The pause time was not long enough for the marco to complete. So another AppActivate is not needed at all.
These Fixed delay times will work for now, but I need a way of monitoring the application(Pro/Engineer) for busy activity.
Ah a solution!  You gotta love that.  Thanks for the points.

Here's some info on determining when a shelled process has terminated (not really pretinent in this case I don't think, but may get you looking in the right direction). I'm not sure if you can detect what state a program is in if you are trying to leave that program running.  Perhaps Pro/Engineer exposes some hooks for you to work with.

http://support.microsoft.com/default.aspx?scid=KB;en-us;q96844

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial