Sign in to follow this  
Followers 0
rajeshwaran

How to call a function as a seperate process

12 posts in this topic

#1 ·  Posted (edited)

I am developing a GUI program, to process a file, this file processing will happen in a while loop, for the user to stop or pause the file processing, I want to call a seperate GUI window function __X__() with "Stop" & "Pause" buttons.

How to call a seperate GUI window function __X__() as a new process ?

Help me..

Edited by rajeshwaran

Share this post


Link to post
Share on other sites



If you really want a separate process then you'll have to Run() it.

The single AutoIt process can have as many GUIs simultaneously as you want. Popping a second, or third, GUI is not a problem. You want to get familiar with either GuiOnEventMode, or the advanced option of GuiGetMsg() so you can sort out events from multiple GUIs.

;)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Actually I want to create one more task (thread/process ... whatever)

In AutoIt one or more GUI windows with single while(1) loop (single process) is possible, I want to create (run)one more while(1) loop and process something else not GUI.

Is it possible in AutoIt ?

Share this post


Link to post
Share on other sites

Actually I want to create one more task (thread/process ... whatever)

In AutoIt one or more GUI windows with single while(1) loop (single process) is possible, I want to create (run)one more while(1) loop and process something else not GUI.

Is it possible in AutoIt ?

Share this post


Link to post
Share on other sites

Not in the way you want it, but it should be possible to get the behavior you want while using a single while loop. (Unless you're trying to get increased performance for a cpu heavy program)

If you want to post your code and intended behavior I could try to demonstrate how it could work.

Share this post


Link to post
Share on other sites

I'm wanting to do the same thing. In my case I've written most of a startup manager that launches the programs in an orderly process, but want the user to be able to choose the last program(s) to load. I have written a separate GUI for the user input that I want to marry with the startup process, as well as add in a countdown timer. So, I have a need for simultaneous:

A ) a sequence of Run, WinWaitActive, and sleep commands (last is a 19 second sleep)

B ) a gui that is asking for user input while the other programs are loading

C ) a countdown timer (for...next) during the last 19 second wait

Can all of these somehow be run in the same script? If I have to have 2 or 3 simultaneous scripts going, how do I communicate between them?

Thanks in advance.

Ed

Share this post


Link to post
Share on other sites

Hi Tvern,

Currently I dont have any sample script.

However my requirement is very simple, all basic languages supports multithreading in windows, I am surprising, AutoIt has lot of features, without multithread concept.

If you know, any alternative way please give example to us.

Share this post


Link to post
Share on other sites

If you really need a second process call your own script with a command line option, the below code had a gui which displayed a marquee, it was launched as a separate process because fileinstall used to stop it running until it had completed

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ProgressConstants.au3>
#include <SendMessage.au3>

If $CMDLINE[0] > 0 and $CMDLINE[1] = "Wait" then _PleaseWait()


$iPid = Run('"' & @ScriptFullPath & '" Wait',@scriptDir)
FileInstall("MATRIX-XP_engl_L.avi","C:\MATRIX-XP_engl_L.avi",1)
ProcessClose($iPid)


;Msgbox(0,"","")




Func _PleaseWait()

    GuiCreate("",400,200,-1,-1,-1, BitOr($WS_EX_TOOLWINDOW,$WS_EX_TOPMOST))
    GUICtrlCreateLabel("Please Wait...",60,60,200)
    GuICtrlSetFont(-1,18)
    $progress = GUICtrlCreateProgress(60, 120, 300, 20, $PBS_MARQUEE); marquee works on Win XP and above
    $hProgress = GUICtrlGetHandle($progress)
    _SendMessage($hProgress, $PBM_SETMARQUEE, True, 50); marquee works on Win XP and above

    GuiSetState()

    While 1
        Sleep(100)

    WEnd

EndFunc

Share this post


Link to post
Share on other sites

Hi ChrisL,

The script is not working for me, may be the files *.avi are not there in my C drive, leave it.

The below code confusing me

$iPid = Run('"' & @ScriptFullPath & '" Wait',@scriptDir)

Can you explain in detail.

Share this post


Link to post
Share on other sites

Hi ChrisL,

The script is not working for me, may be the files *.avi are not there in my C drive, leave it.

The below code confusing me

$iPid = Run('"' & @ScriptFullPath & '" Wait',@scriptDir)

Can you explain in detail.

The file install was just an example.

All this does $iPid = Run('"' & @ScriptFullPath & '" Wait',@scriptDir) is calls the main script (itself) with a command line option and the command line option is set to go to a specific function that can do whatever you want it too.

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

The trick is not to use functions that only return once a window is active, but instead just check if that window is active multiple times. Instead of a long sleep you can use multiple short sleeps and a timer.

I made an example based on what EdWilson described.

#include <array.au3>
Local $aPrograms[3] = ["C:\somefolder\SomeProgram1.exe","C:\somefolder\SomeProgram2.exe","C:\somefolder\SomeProgram3.exe"] ;a list of programs to run. Could be loaded from an ini or whatever you like.
Local $iIndex = 0 ;keeps track of the index of the process to Run()

Local $bLoadNext = True ;Imidiately start running the first process on the list
Local $bCountdown = False ;Don't start the countdown yet

Local $hTimer, $iTimeLeft, $iOldTimeLeft ;some variables used by the timer
Local $PID, $hWnd
GUICreate("User Input",200,110) ;A gui for user input.
Local $CtrlButton = GUICtrlCreateButton("add to runlist",10,10) ;a button to add programs to the run list
Local $CtrlLabel = GUICtrlCreateLabel("",10,40,180,30)  ;a label to display the countdown
GUISetState()

While 1
;This is the main loop. It combines:
;1. Running the programs
;2. Checking if the program has loaded (WinExists atleast)
;3. Starting the countdown
;4. Updating the countdown
;5. Checking for user input
    If $iIndex < UBound($aPrograms) Then ;there are more programs to run in the array
    If $bLoadNext Then
    $PID = Run($aPrograms[$iIndex]) ;load a new program
    $bLoadNext = False ;block the next program from loading for now
    Else
    $hWnd = _GetHwndFromPID($PID)
    If $hWnd And WinExists($hWnd) Then ;the last program is loaded.
    ;The window exists, you can make sure it's active here.
    $bLoadNext = True ;allow the next program to load
    $iIndex += 1
    EndIf
    EndIf
    Else ;the last program was reached
    If $bCountdown Then ;update the countdown if active
    $iTimeLeft = Round((19000 - TimerDiff($hTimer))/1000,0)
    If $iTimeLeft < 0 Then
                Exit
            ElseIf $iTimeLeft <> $iOldTimeLeft Then
    GUICtrlSetData($CtrlLabel,"Closing in " & $iTimeLeft & " seconds.")
    $iOldTimeLeft = $iTimeLeft
    EndIf
    Else ;start the countdown if it hasn't started yet
    $bCountdown = True
    $hTimer = TimerInit()
    EndIf
    EndIf

    Switch GUIGetMsg() ;check for user input
    Case -3
    Exit
    Case $CtrlButton
    _ArrayAdd($aPrograms,FileOpenDialog("Choose an executable",@ScriptDir,"Executables (*.exe)"))
;~  $bCountdown = False ;uncomment this line if you want the countdown to go back to 19 seconds after a newly added program is loaded.
    EndSwitch
WEnd

; I found this function on the forum. Don't know the author, but thanks!
Func _GetHwndFromPID($PID)
    Local $hWnd = 0
    Local $stPID = DllStructCreate("int")
    Local $winlist2 = WinList()
    For $i = 1 To $winlist2[0][0]
    If $winlist2[$i][0] <> "" Then
    DllCall("user32.dll", "int", "GetWindowThreadProcessId", "hwnd", $winlist2[$i][1], "ptr", DllStructGetPtr($stPID))
    If DllStructGetData($stPID, 1) = $PID Then
    $hWnd = $winlist2[$i][1]
    ExitLoop
    EndIf
    EndIf
    Next
    Return $hWnd
EndFunc

Edit: Had some undeclared vars.

Edited by Tvern

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0