Jump to content
reikenberg

WinExits works, WinActivate fails!?

Recommended Posts

Hello,

i want to automate a window. If i run the window on XP and try to control it with WinExits and WinActivate it works without problems. If i run it on a Win2003 Server RC2 running on VMware WinExists works but WinActivate always fails. But controlling checkboxes for example works on both systems.

I don´t know know how to slove this problem, any advise?

Sincerly

Rigoletto

Share this post


Link to post
Share on other sites

Tut - Ta - da - daaa!!

Run("notepad.exe")
WinWaitActive("")

$Title = "Untitled -"

While WinExists($Title)
    If WinExists($Title) Then
        if WinActive($Title) Then
            ; do your stuff
        Else
            WinSetState("", "", @SW_MINIMIZE)
        EndIf
    EndIf
    Sleep(2000)
WEnd

I have been on this for move than 1/2 hour and I tried "EVERYTHING"

.... Finally got this to work!!

@Salty, I noticed you have been here a while too - nothing else seems to work, how about for you?

8)

Share this post


Link to post
Share on other sites

Hello,

i trying around and find out that WinActivate only works when somebody is watching at the desktop where the window that should be controlled exists. Via RDP for example. But if the RDP window minimized WinActivate always fails.

Here is our complete code:

#NoTrayIcon
#Region;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_outfile=P:\TC_Auto\InERP_BP_Watcher.exe
#AutoIt3Wrapper_Res_Fileversion=1.0.0.20
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_Language=1031
#EndRegion;**** Directives created by AutoIt3Wrapper_GUI ****
#Include <Constants.au3>

Opt("CaretCoordMode", 0)
Opt("MouseCoordMode", 0)
Opt("SendKeyDelay", 1000)

Dim $crlf = chr(13) & chr(10)
Dim $rv
Dim $parameter
Dim $focus
Dim $clipboard
Dim $exititem
Dim $infoitem
Dim $app_to_watch = "Batch Printer"
Dim $app_text
Dim $temp[10]

Dim $szIPADDRESS = @IPAddress1
Dim $nPORT = 62222
Dim $MainSocket, $szIP_Accepted
Dim $ConnectedSocket = -1
Dim $msg, $recv

If $CmdLIne[0] = 1 Then
    $parameter = $CmdLine[1]
EndIf

init()

While 1
    $msg = TrayGetMsg()
    Select
        Case $msg = 0
            If Not WinExists($app_to_watch) Then
            ;MsgBox(0, "Zu überwachendes Fenster fehlt", $app_to_watch)
            EndIf
            
            If $ConnectedSocket = -1 Then
                $ConnectedSocket = TCPAccept($MainSocket)
            EndIf
            If $ConnectedSocket >= 0 Then
                $szIP_Accepted = SocketToIP($ConnectedSocket)
                $recv = TCPRecv($ConnectedSocket, 2048)
                if $recv = "" and @error = "10054" then
                    $ConnectedSocket = -1
                EndIf
            EndIf

                if $recv <> "" Then
                    $app_text = $recv
                    
                    Select
                        Case $app_text = "start batchprinter"
                            start_batchprinter()
                        Case $app_text = "stop batchprinter"
                            stop_batchprinter()
                        Case $app_text = "config batchprinter"
                            config_batchprinter()
                        Case $app_text = "exit batchprinter"
                            exit_batchprinter()
                        Case $app_text = "load batchprinter"
                            load_batchprinter()
                        Case $app_text = "info batchprinter"
                            info_batchprinter()                             
                    EndSelect
                    
                EndIf

            Sleep(5000)
        Case $msg = $infoitem
            MsgBox (0,"Info","Version: " & FileGetVersion(@AutoItExe))
        Case $msg = $exititem
            ExitLoop
    EndSelect
WEnd

If $ConnectedSocket <> -1 Then TCPCloseSocket($ConnectedSocket)
TCPShutdown()

Exit

Func info_batchprinter()
    If WinActivate($app_to_watch) Then
        $temp[1] = ControlGetText($app_to_watch,"","Edit1");Datum letzter Druck
        $temp[2] = ControlGetText($app_to_watch,"","Edit2");Uhrzeit letzter Druck
        $temp[3] = StatusbarGetText($app_to_watch,""); Statuszeile
        
        $app_text = $crlf
        $app_text = $app_text & "Letztes Druckdatum: " & $temp[1] & $crlf
        $app_text = $app_text & "Letzte Druckzeit: " & $temp[2] & $crlf
        $app_text = $app_text & "Status: " & $temp[3] & $crlf
        $app_text = $app_text & $crlf
        $temp = MemGetStats()
        $app_text = $app_text & "Speicher gesamt: " & $temp[1] & $crlf
        $app_text = $app_text & "Speicher frei: " & $temp[2] & $crlf
        
        Run("net send " & $szIP_Accepted & " " & $app_text)
    Else
        $app_text = $crlf
        $app_text = $app_text & $app_to_watch & " reagiert nicht oder ist nicht gestartet." & $crlf & @extended
        Run("net send " & $szIP_Accepted & " " & $app_text)
    EndIf
EndFunc

Func start_batchprinter()
    $rv = WinActivate($app_to_watch)
    If $rv = 1 Then
        MouseClick("left",20,40,1,100); start
    EndIf
EndFunc

Func stop_batchprinter()
    $rv = WinActivate($app_to_watch)
    If $rv = 1 Then
        MouseClick("left",60,40,1,100); stop
    EndIf
EndFunc

Func config_batchprinter()
    $rv = WinActivate($app_to_watch)
    If $rv = 1 Then
        ControlCommand($app_to_watch,"Verkauf","Button2","Check")
        ControlCommand($app_to_watch,"Einkauf","Button4","Check")
        ControlCommand($app_to_watch,"Produktion","Button5","Check")
        ControlCommand($app_to_watch,"Andere","Button6","Check")

        ControlCommand($app_to_watch,"06:00","Button7","UnCheck")
        ControlCommand($app_to_watch,"09:00","Button8","UnCheck")
        ControlCommand($app_to_watch,"12:00","Button9","UnCheck")
        ControlCommand($app_to_watch,"15:00","Button10","UnCheck")
        ControlCommand($app_to_watch,"18:00","Button11","UnCheck")
        ControlCommand($app_to_watch,"21:00","Button12","UnCheck")

        ControlFocus($app_to_watch,"","Edit3")
        Send("l")
        send("{TAB}")
        
        while ControlGetText($app_to_watch,"","Edit4") <> "8"
            ControlFocus($app_to_watch,"","Edit4")
            If Number(ControlGetText($app_to_watch,"","Edit4")) > 8 Then
                Send("{DOWN}")
            Else
                Send("{UP}")
            EndIf
        WEnd
    EndIf
EndFunc 

Func load_batchprinter()
    If Not WinExists($app_to_watch) Then
        Run("P:\Prod\INERP\GUI\BatchPrinter_D.exe","P:\Prod\INERP\GUI",@SW_MAXIMIZE)
        WinWait("Anmeldung")
        ControlCommand("Anmeldung","OK","Button1","Check")
        WinWaitActive($app_to_watch,"")
        config_batchprinter()
        start_batchprinter()
    EndIf
EndFunc

Func exit_batchprinter()
    $rv = WinActivate($app_to_watch)
    If $rv = 1 Then
        WinClose($app_to_watch)
    EndIf
EndFunc

Func init()
    TCPStartup()
    $MainSocket = TCPListen($szIPADDRESS, $nPORT)
    If $MainSocket = -1 Then
        MsgBox (0,"Fehler","Kommunikation konnte nicht aufgebaut werden.")
        Exit
    EndIf
    
    Opt("TrayMenuMode",1)  ; Default tray menu items (Script Paused/Exit) will not be shown. 
    $exititem      = TrayCreateItem("Exit")
    TrayCreateItem("")
    $infoitem      = TrayCreateItem("Info")
    TraySetState() ; Show the tray icon
    TraySetToolTip("InERP BatchPrint Watcher")
EndFunc

Func SocketToIP($SHOCKET)
    Local $sockaddr, $aRet
    
    $sockaddr = DllStructCreate("short;ushort;uint;char[8]")

    $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
            "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
    If Not @error And $aRet[0] = 0 Then
        $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
        If Not @error Then $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf

    $sockaddr = 0

    Return $aRet
EndFunc  ;==>SocketToIP

Share this post


Link to post
Share on other sites

So check and change the state of the window before hand:

pseudo:

Func _my_WinActivate($h_wnd, $s_text = "")
    If BitAnd(WinGetState($h_wnd, $s_text), 16) Then
        WinSetState($h_wnd, $s_text, @SW_RESTORE)
        Return WinActivate($h_wnd, $s_text)
    EndIf
    Return WinActivate($h_wnd, $s_text)
EndFunc

Edit:

Only had it activating window if it was minimized... ^_^

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Hello,

yes it restore the window, but not give focus to it, even if it´s minimized.

It seems that a window on a desktop with no "focus" (no user using the desktop via rdp, etc.) cannot get focus.

Looks not like an autoit-problem, i have access runtime application that have problem with desktops without "focus" too.

I think some needed response from windows is not given if the desktop has no user.

I could try a workaround and open a rdp-session, but that´s worse solution.

Share this post


Link to post
Share on other sites

Hello,

yes it restore the window, but not give focus to it, even if it´s minimized.

It seems that a window on a desktop with no "focus" (no user using the desktop via rdp, etc.) cannot get focus.

Looks not like an autoit-problem, i have access runtime application that have problem with desktops without "focus" too.

I think some needed response from windows is not given if the desktop has no user.

I could try a workaround and open a rdp-session, but that´s worse solution.

Years ago this problem had been a transient problem for me. I used a work around but I never understood how or why WinActivate failed. Just recently WinActivate became a problem again. WinActivate struggles with Window titles.

Lucky for me WinActivate struggled with a program that I wrote. I renamed the Window title of my program to a small simple word "runme" and just that change alone fixed the problem. No other changes. The former title was much longer and used an ampersand towards the end. I didn't explore beyond that but I wonder what was in that former title that caused problems? Perhaps there is a bug in WinActivate.

Ebbie

Share this post


Link to post
Share on other sites

Using a Windows 7 Pro virtual machine on Oracle VirtualBox 5.0.20.
AutoIt 3.3.14.5

Accessing a program minimized to the TaskBar when no program has focus can cause unusual behavior. If the window is in the restored state or maximized state there is no problem.

Example:

$sWindow_Name = "AutoCAD"
WinActivate($sWindow_Name) 
WinSetState($sWindow_Name,"", @SW_RESTORE )

Both commands work as expected if the main AutoCAD 2000 window is running and not minimized to the TaskBar.

If the main AutoCAD 2000 window is minimized to the TaskBar, either of the above commands can produce undesired results when used individually or in combination (regardless of order). In this case the result was to open an AutoCAD 2000 Text Window when another window did not have focus, This is basically a WinActivate() / WinSetState() failure.

This problem is repeatable when using AutoIt to close a window, then attempt to access a minimized window (see Solution 2 for an example).
 

Solution 1:

The easiest solution in this instance was to change the portion of the window title AutoIt looks for:

$sWindow_Name = "AutoCAD 2002"

This solved the problem, much like ebbie's situation, although the script is now less generic (it works for AutoCAD 2002 but not AutoCAD 2010).

 

Solution 2:

If using AutoIt to close a window (such as AutoCAD 2000 Help) before accessing the AutoCAD 2000 main program window (minimized to the TaskBar), focus is consistently lost. Display a MsgBox before closing the window to give the virtual machine focus:

MsgBox($MB_ICONINFORMATION,@scriptfullpath, 'Closing the help window.')
$iVirtualMachineNeedsFocus = 1
WinClose($sHelp_Window_Name)

Use the mouse to click the OK button (giving VM focus, using the Enter will close the window but not give focus).

Then display a MsgBox before using WinActivate() or WinSetState() to give the virtual machine focus:

; Retrieve the state of focus:
$iWinState = WinGetState($sWindow_Name)

; If the window is not active:
if Not BitAND($iWinState, $WIN_STATE_ACTIVE) Then

    ; Check if the mouse needs to bring focus to the virtual machine:
    If $iVirtualMachineNeedsFocus = 1 Then

        ; if so, display a message box and reset the flag.
        MsgBox($MB_ICONINFORMATION,@scriptfullpath, 'Regaining mouse focus for Virtual Machines.')
        $iVirtualMachineNeedsFocus = 0
    EndIf

    ; Activate the window:
    WinActivate($sWindow_Name)
EndIf
; If the window is not in a windowed state ("restored") (then it must be either minimized or maximized):
if BitAND($iWinState, $WIN_STATE_MINIMIZED) Or BitAND($iWinState, $WIN_STATE_MAXIMIZED ) Then

    ; Check if the mouse needs to bring focus to the virtual machine:
    If $iVirtualMachineNeedsFocus = 1 Then
        
        ; if so, display a message box and reset the flag.
        MsgBox($MB_ICONINFORMATION,@scriptfullpath, 'Regaining mouse focus for Virtual Machines.')
        $iVirtualMachineNeedsFocus = 0
    EndIf
    
    ; Retore the window:
    WinSetState($sWindow_Name,"", @SW_RESTORE )
EndIf

As a note, using Sleep() in various places did not work as it is not a timing issue.

Edited by WIHedgehog

Share this post


Link to post
Share on other sites

@WIHedgehog while the delivery above leaves - pretty much everything - to be desired, it is true that we discourage posting in old topics. Often after so long, the original poster has moved on, or as in this case has not been online in some time. There are plenty of current threads on which you can offer suggestions.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

×
×
  • Create New...