Jefrey

AuThread: Multi thread emulation (forking) for AutoIt

27 posts in this topic

#1 ·  Posted (edited)

Hi all!

I've made this small UDF to emulate multithreading for AutoIt3.

As we know, AU3 is singlethread and multithreading is only possible through direct ASM. This UDF provides a multithreading emulation through running multiple instances of your script. It also provides an easy way for sending and receiving messages between threads (temporary files are used).

Example:

Spoiler

 

Start by including the lib onto your script.

#include 'authread.au3'

Now call _AuThread_Startup(). This function is responsible for calling the callback functions if the currently running process is a "thread", or saving important data to temporary files if it's the main thread.

_AuThread_Startup()

Now create your thread function. You can choose any name for it or even create multiple functions (for multiple threads). Note that if you want your thread to last an undetermined time, you must include an infinite loop inside the function.

Func myThreadFunction()
    While True
        ; In this example, we will get a message sent by the main thread (if any)
        $sMsg = _AuThread_GetMessage()
        If $sMsg Then
            ; Message was sent, let's display it
            MsgBox(0, "Message from the main thread to the sub thread", $sMsg)
        EndIf

        MsgBox(0, "Thread example", "Hey, I am a thread!")
        Sleep(1000)
    WEnd
EndFunc

Now start the thread by calling:

$hThread = _AuThread_StartThread("myThreadFunction")

This function returns the PID of the process-thread. You'll use it for sending messages to threads.

You can continue writing your script on the same file:

While True
    MsgBox(0, "", "Hey, I am the main thread!")
    _AuThread_SendMessage($hThread, "Hello, sub thread! How are you?")
    Sleep(1000)
WEnd

By default, Windows API (and therefore AutoIt) allows only 1 MessageBox per thread. However, by running the script we've just written, you'll see that we're capable of running two message boxes at once on the same script.

Also, when you close the main script, all the threads are also closed.

You cannot start a thread directly without opening the main thread.

Final code:

#include 'authread.au3'

_AuThread_Startup()

Func myThreadFunction()
    While True
        ; In this example, we will get a message sent by the main thread (if any)
        $sMsg = _AuThread_GetMessage()
        If $sMsg Then
            ; Message was sent, let's display it
            MsgBox(0, "Message from the main thread to the sub thread", $sMsg)
        EndIf

        MsgBox(0, "Thread example", "Hey, I am a thread!")
        Sleep(1000)
    WEnd
EndFunc

$hThread = _AuThread_StartThread("myThreadFunction")

While True
    MsgBox(0, "", "Hey, I am the main thread!")
    _AuThread_SendMessage($hThread, "Hello, sub thread! How are you?")
    Sleep(1000)
WEnd

 

Example 2:

Spoiler
#include 'authread.au3'

_AuThread_Startup()

$hThread = _AuThread_StartThread("sendalert")

Func sendalert()
    While 1
        $msg = _AuThread_GetMessage()
        If $msg Then
            MsgBox(0, "Alert from thread", $msg)
        EndIf

        ; randomly sends (or not) messages to the main thread
        $rand = Random(1, 10, 1)
        If $rand = 2 Then
            _AuThread_SendMessage(_AuThread_MainThread(), "Hey!")
        EndIf
    WEnd
EndFunc

; main thread
While True
    ; randomly sends (or not) messages to the main thread
    $rand = Random(1, 3, 1)
    TrayTip("Main thread window", "Sorted number: " & $rand, 1)
    If $rand = 2 Then
        _AuThread_SendMessage($hThread, $rand & " was sorted")
    EndIf

    ; get some message sent to the main PID
    $msg = _AuThread_GetMessage()
    If $msg Then
        MsgBox(0, "Wayback message", "The thread sent: " & $msg)
    EndIf
    Sleep(1000)
WEnd

; The line below is just an example,
; as once the main thread is closed or killed, the UDF will automatically close all the started threads
_AuThread_CloseThread($hThread)

 

Docs:

Spoiler

void _AuThread_Startup()

Verifies if the currently running script is a thread being called by a mainthread or if it's the main thread itself. If it's being called by a main thread, it calls the specified callback function. Else, it will just save required data for the UDF.

int _AuThread_MainThread()

This function can be called in both threads and mainthreads. It will always return the PID of the main thread.

int _AuThread_StartThread(string $sCallback [, string $sMsg ] )

Starts a thread and returns the new thread PID. $sCallback must be a callable function name. If $sMsg is specified,_AuThread_SendMessage($sMsg) will be automatically called.

string _AuThread_GetMessage( [ $iPID = @AutoItPID ] )

Gets the last message sent to the current thread (or main thread, if called on it), returns and deletes it. If no message is found, False is returned.

void _AuThread_SendMessage($iPid, $sMessage)

Sends a message to a thread (main or sub). This message can be retrieved through _AuThread_GetMessage().

void _AuThread_CloseThread( [ $iPID = @AutoItPID ] )

Closes a thread or the current thread (if no thread PID is specified).

Download:

Github ZIP

Fork me on Github

Edited by Jefrey
2 people like this

My stuff

Spoiler

My UDFs  _AuThread multithreading emulation for AutoIt · _ExtInputBox an inputbox with multiple inputs and more features · forceUTF8 fix strings encoding without knowing its original charset · JSONgen JSON generator · _TCPServer UDF multi-client and multi-task (run on background) event-based TCP server easy to do · _TCPClient_UDF multi-server and multi-task (runs on background) event-based TCP client easy to do · ParseURL and ParseStr functions ported from PHP · _CmdLine UDF easily parse command line parameters, keys or flags · AutoPHP Create documents (bills, incomes) from HTML by sending variables/arrays from AutoIt to PHP · (Un)Serialize Convert arrays and data into a storable string (PHP compatible) · RTTL Plays and exports to MP3 Nokia-format monophonic ringtones (for very old cellphones) · I18n library Simple and easy to use localization library · Scripting.Dictionary OOP and OOP-like approach · Buffer/stack limit arrays to N items by removing the last one once the limit is reached · NGBioAPI UDF to work with Nitgen fingerprint readers · Serial/Licensing system require license key based on unique machine ID from your users · HTTP a simple WinHTTP library that allows GET, POST and file uploads · Thread true AutoIt threads (under-dev) · RC4 RC4 encryption compatible with PHP and JS Classes _WKHtmlToX uses wkhtmlto* to convert HTML files and webpages into PDF or images (jpg, bmp, gif, png...) Snippets _Word_DocFindReplaceByLongText replace strings using Word UDF with strings longer than 255 characters (MSWord limit) rangeparser parser for printing-like pages interval (e.g.: "1,2,3-5") EnvParser parse strings/paths with environment variables and get full path Random stuff Super Mario beep sound your ears will hurt

 

Share this post


Link to post
Share on other sites



It shouldn't be so hard to use _WinAPI_SetProcessAffinityMask().


When the words fail... music speaks

Share this post


Link to post
Share on other sites
Hi,.

But, use of 'AdlibRegister' is not the true multi threading.

everything from useful.

Good Week!

Share this post


Link to post
Share on other sites
15 hours ago, jaberwacky said:

Does this use multiple cores if one's computer were so equipped?

No, this UDF launches the same executable multiple times to emulate multi-threading, As AutoIt is not able to use Multiple Cores, this UDF does not use them too!

50 minutes ago, JiBe said:

But, use of 'AdlibRegister' is not the true multi threading.

Huh? :huh:, Where did the UDF use Adlib functions?

 


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

@JiBe just because you disagree with what TheDcoder states, is not a reason to report the thread. Think it through next time...


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
4 minutes ago, JLogan3o13 said:

just because you disagree with what TheDcoder states, is not a reason to report the thread.

He reported me? :blink:... First, sorry if I have said anything wrong @JiBe :sweating:, it is not my intention to hurt anyone! (The same is mentioned in my signature)

I would welcome any counter-argument :), but please do it here, not in the report box! :D.

2 people like this

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites
Sorry, just a mistake of using the forum.
I wanted to just posted this:

 

excuse my English, I'm French. but the Autoit Code used in the UDF is very clear. and my interpretation of this code is the use of the Adlibregister. should you detail your assertion.

Share this post


Link to post
Share on other sites
On 14/08/2016 at 2:10 PM, jaberwacky said:

Does this use multiple cores if one's computer were so equipped?

Hi, @jaberwacky! It looks like Andreik and TheDcoder have answered to your question. I've done no tests so far with _WinAPI_SetProcessAffinityMask, tho.

21 hours ago, Andreik said:

It shouldn't be so hard to use _WinAPI_SetProcessAffinityMask().

 

9 hours ago, TheDcoder said:

No, this UDF launches the same executable multiple times to emulate multi-threading, As AutoIt is not able to use Multiple Cores, this UDF does not use them too!

----------------------

10 hours ago, JiBe said:
Hi,.

But, use of 'AdlibRegister' is not the true multi threading.

everything from useful.

Good Week!

Hi, JiBe!

Actually, the AdlibRegister is not the true way it runs the "threads". Truly it really creates new processes and uses Adlib just to check for new messages (from the UDF _AuThread_SendMessage()) or closing signal.

Also, it's really not the true multi threading. It's just an emulation. It's "forking" ;)

----------------------

2 hours ago, argumentum said:

Hi, argumentum!

Yes, this is the right name hehe. It came out of my mind at the time of the creation of this topic. I've added it to the topic title (I chose to keep "multi thread emulation" for helping users who are using the search engine, as some might not know what's forking). Thanks for poiting out :)

---------------

Guys, I've started another project that, according to what my latest tests are poiting, might provide some kind of true multithreading for AutoIt without external processes. It's not fully working yet (so far it works just with basic tasks). This is an example:

#include 'thread.au3'

CreateThread("helloworld")

Func helloworld($h)
    MsgBox(0, "", "Hello from the sub thread")
EndFunc

MsgBox(0, "", "Hello from the main thread")

Exit

If you want to help, here's the repo: https://github.com/jesobreira/thread.au3 :D 

2 people like this

My stuff

Spoiler

My UDFs  _AuThread multithreading emulation for AutoIt · _ExtInputBox an inputbox with multiple inputs and more features · forceUTF8 fix strings encoding without knowing its original charset · JSONgen JSON generator · _TCPServer UDF multi-client and multi-task (run on background) event-based TCP server easy to do · _TCPClient_UDF multi-server and multi-task (runs on background) event-based TCP client easy to do · ParseURL and ParseStr functions ported from PHP · _CmdLine UDF easily parse command line parameters, keys or flags · AutoPHP Create documents (bills, incomes) from HTML by sending variables/arrays from AutoIt to PHP · (Un)Serialize Convert arrays and data into a storable string (PHP compatible) · RTTL Plays and exports to MP3 Nokia-format monophonic ringtones (for very old cellphones) · I18n library Simple and easy to use localization library · Scripting.Dictionary OOP and OOP-like approach · Buffer/stack limit arrays to N items by removing the last one once the limit is reached · NGBioAPI UDF to work with Nitgen fingerprint readers · Serial/Licensing system require license key based on unique machine ID from your users · HTTP a simple WinHTTP library that allows GET, POST and file uploads · Thread true AutoIt threads (under-dev) · RC4 RC4 encryption compatible with PHP and JS Classes _WKHtmlToX uses wkhtmlto* to convert HTML files and webpages into PDF or images (jpg, bmp, gif, png...) Snippets _Word_DocFindReplaceByLongText replace strings using Word UDF with strings longer than 255 characters (MSWord limit) rangeparser parser for printing-like pages interval (e.g.: "1,2,3-5") EnvParser parse strings/paths with environment variables and get full path Random stuff Super Mario beep sound your ears will hurt

 

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

On 8/15/2016 at 2:42 PM, Jefrey said:

I've done no tests so far with _WinAPI_SetProcessAffinityMask, tho.

I did :) 

If Not StringInStr($CmdLineRaw, "/ErrorStdOut") And Not @Compiled Then Exit MsgBox(262144, @ScriptName, "...please run from editor.", 5)

#include <Array.au3>
#include <WinAPI.au3>
#include <WinAPISys.au3>
#include <Process.au3>
#include <WinAPIShPath.au3>

SetProcessAffinityMaskForCurrentProcess(0x05)
; For example, if you pass a mask of 0x05, processors 0 and 2 ( 1st and 3th ) are allowed to run.

Global $aProcessAffinityMask = GetProcessAffinityMask(_WinAPI_PathStripPath(@AutoItExe))
_ArrayDisplay($aProcessAffinityMask, "$aProcessAffinityMask") ; show the affinity masks

Func SetProcessAffinityMaskForCurrentProcess($i = 0)
    Local $hCurrentProcess = _WinAPI_GetCurrentProcess() ; process handle of currrent process
    Local $n = _WinAPI_SetProcessAffinityMask($hCurrentProcess, $i) ; Success: True, Failure: False
    Local $iErr = _WinAPI_GetLastError() ; call _WinAPI_GetLastError() to get extended error information
    Local $affiity = _WinAPI_GetProcessAffinityMask($hCurrentProcess)
    ConsoleWrite("--- > SetProcessAffinityMaskForCurrentProcess( 0x" & Hex($i, 2) & " ) = Success : " & _
            $affiity[0] & @TAB & "Proc Mask : " & $affiity[1] & @TAB & "Sys Mask : " & $affiity[2] & @CRLF)
    Return SetError($iErr, 0, $n)
EndFunc   ;==>SetProcessAffinityMaskForCurrentProcess

Func GetProcessAffinityMask($sProgram = Default)
    Local $a, $n, $m, $hProcess
    If $sProgram Then
        $a = ProcessList($sProgram)
    Else
        $a = ProcessList()
    EndIf
    ReDim $a[UBound($a)][4]
    $a[0][1] = "PID"
    $a[0][2] = "Process affinity cores ( mask )"
    $a[0][3] = "System affinity cores ( mask )"
    For $n = 1 To $a[0][0]
        $a[$n][2] = "failed"
        $a[$n][3] = "_WinAPI_OpenProcess"
        If _WinAPI_GetVersion() >= 6.0 Then
            $hProcess = _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, 0, $a[$n][1]) ; process handle of external process
        Else
            $hProcess = _WinAPI_OpenProcess($PROCESS_QUERY_INFORMATION, 0, $a[$n][1]) ; process handle of external process
        EndIf
        If @error Then ContinueLoop
        $a[$n][3] = "_WinAPI_GetProcessAffinityMask"
        $b = _WinAPI_GetProcessAffinityMask($hProcess)
        If @error Then ContinueLoop
        For $m = 1 To 2 ; I only have 8 cores, adjust to your needs. You may need hex 8, this is just a demo.
            $a[$n][1 + $m] = AffinityMaskToCores($b[$m]) & " ( 0x" & Hex($b[$m], 2) & " )"
        Next
    Next
    Return $a
EndFunc   ;==>GetProcessAffinityMask

Func AffinityMaskToCores($i)
    Local $s = "", $n = 1, $c = 0 ; processors are "hardware", therefore start at 0 ( zero )
    Do
        If BitAND($i, $n) Then $s &= "," & $c
        $n += $n
        $c += 1
    Until $n > $i
    Return StringTrimLeft($s, 1)
EndFunc   ;==>AffinityMaskToCores

So here is a nice help to show how to set the process affinity and how to get it.

... on the other hand, 

#NoTrayIcon

Global $g_UniqueInAWay = "Wasted away again in Margaritaville"
If $CmdLine[0] Then
    f_WasteAway()
    Exit
EndIf
Func exitInAMinuteJustInCase()
    Exit
EndFunc   ;==>exitInAMinuteJustInCase
Func f_WasteAway()
    AutoItWinSetTitle($g_UniqueInAWay)
    AdlibRegister("exitInAMinuteJustInCase", 60000)
    Local $watever
    Do
        $watever = 123 * 123 * 123 * 123 * 123 * 123 * 123 * 123 * 123 * 123
    Until 1 = 2
EndFunc   ;==>f_WasteAway

main()
Func main()
    Local $nop = Int(EnvGet("NUMBER_OF_PROCESSORS"))
    For $n = 1 To $nop ; or more, or less, windows will handle it.
        If @Compiled Then
            Run('"' & @ScriptFullPath & '" /wasteAway')
        Else
            Run('"' & @AutoItExe & '" "' & @ScriptFullPath & '" /wasteAway')
        EndIf
    Next
    MsgBox(262144, @ScriptName, "you've got " & $nop & " running processes" & @CR & _
            "as you can see in task manager > performance" & @CR & _
            "windows handle the cpu core assignation quite well" & @CR & @CR & "press ok to stop them.", 60)
    While WinExists($g_UniqueInAWay)
        WinClose($g_UniqueInAWay)
    WEnd
EndFunc   ;==>main

that is not needed.

Edited by argumentum
changed the example a bit

Share this post


Link to post
Share on other sites
11 hours ago, Jefrey said:

Guys, I've started another project that, according to what my latest tests are poiting, might provide some kind of true multithreading for AutoIt without external processes.

Ooohhhh :o, I will be following the changes on GitHub :D.

1 person likes this

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

hmmm, to fork or to thread, this is a good read even if meant for linux.
In AutoIt3 forking is stable, threading is not.
Working with threads is not a holy grail, loading a script ( compiled or not ) in my PC takes less than 10 mSec., memory nowadays is abundant, so forking is not a burden. Ingenuity is the key here.
Using MailSlots for IPC, is sequential, the message can be of unlimited* size and will not be overwritten, no great semaphore brainstorming needed. Forks can be pre-loaded and put to work when needed, and would even allow for distributed processing ( meaning that with this technique, you are not even limited to a single PC, forking is distributed processing ).
ok, café cubano time.

PS: I modified an example from another thread to kind of showcase what I mean.

Edited by argumentum
expand on my point

Share this post


Link to post
Share on other sites

Exactly. And never forget that threads are evil. I mean here that multithreading "Hello World!" is one thing, but multithreading a non-trivial task is completely another one, especially with a high-level language which is explicitely not designed to cope with any drop of multithreading.

Unless you gamble blindly about what AutoIt is doing under your feet when you invoke complex or high-level functions deeply interacting with the OS, you'd better stay away from MT in serious code, else you unduly multiply the risks of potential disaster.

1 person likes this

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites

Hi (sorry for english errors i'm french)

Is it not better to use mailslot or other communication udf ? Imagine i got a

100mb memory use script ( the main script)

and one

1mb memory use (update or other function script)

 

if i use your udf my script will use 200 mb memory 

 

if i use a communication udf it will use 101 mb 

 

why is it better to use forking ? in wich situations ? 

(in a hard-protected computer it can be cool no ? you just need to bypass one app in the antivirus / firewall and all the script will work) 

i'm really interessed by your udf for some projects i'm already testing it.

Good bye and thanks for this useful udf 

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

@ultimateheadcenter: MailSlot payload on localhost is restricted to slightly less than 64KB (I'm using 65,507 as upper bound in my Pool UDF); across a LAN, the maximum MailSlot size is a datagram (424 bytes; same as for UDP); for TCP it's 1,472 bytes per packet. So sending a 100MB MailSlot msg is out of the question.

Also, if you're going to be using MailSlots, please be aware that some antivirus software (e.g., Sophos) can block MailSlot messages.

Edited by RTFC
AV caveat
1 person likes this

Share this post


Link to post
Share on other sites

lol, for the past week i have been working on a similar project, using STDIO. my goal is to create a modular include system. 
Im working on tailoring it like the apt-get system in linux where dependencies and versioning is tracked.
So far i have a working demo, and it work as follows:
ur code starts up with my script as an include, on start modules are detected, then called for identity, then once you load the module, it is initialized and I have an array if info for each module, along with nested arrays for each STD[IN|ERR|OUT] everything is queued in an adlib timer
 


What is what? What is what.

Share this post


Link to post
Share on other sites

Hey @Jefrey,

I believe you'd see significant performance improvement if you spawned the multiple instances using the Run function with STDIO enabled and passing commands through that method. I have an example around my computer somewhere with a sample AV program that uses this method to separate the scanning process from it to allow interacting with the GUI while scanning.


My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

MY PROJECTS


Active: IRC UDF, WindowEx UDF
Discontinued: GithubBubbleSort UDF

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

@WormIT This one is different, it does not use multiple processes! Genuine threads are created by calling the Windows API, have a look at the code: https://github.com/jesobreira/authread/blob/master/authread.au3

Oops :>, I just realized that this is another UDF, The UDF which I was talking about is this:
https://github.com/jesobreira/thread.au3

Edited by TheDcoder
Oops

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

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

  • Similar Content

    • ur
      By ur
      Is there anyway to check whether the script is launched already and wait till the other instance is closed and continue after that.
       
    • Miliardsto
      By Miliardsto
      Im creating a tab
      Global $Tab1 = GUICtrlCreateTab(30, 30, 600, 420, $TCS_BUTTONS, -1) And what we see in the function reference:
      https://www.autoitscript.com/autoit3/docs/functions/GUICtrlCreateTab.htm
      GUICtrlCreateTab ( left, top [, width [, height [, style = -1 [, exStyle = -1]]]] ) ok in 5 arg I got $TCS_BUTTONS
      But How can I use multiple args like this below
      Global $Tab1 = GUICtrlCreateTab(30, 30, 600, 420, [$TCS_BUTTONS, $TCS_MULTILINE], -1)  
    • XinYoung
      By XinYoung
      Hello all,
      I've been working on 4 standalone scripts. They each have their own GUI and are now independent .exe's. But instead of having 4 separate icons on my computer, is it possible to put them all together into one .exe?
      What I want is one interface with tabs. Each script's GUI would be on their own respective tab. Is this possible?
      The different scripts don't need to communicate with one another. I just want them all in one .exe.
      I can't find this anywhere... Any help would be greatly appreciated. Thank you!
    • kawliga751
      By kawliga751
      I am trying to script the opening of multiple tabs in IE with each tab having a separate login/password. I have been able to make a successful script that will open 3 separate IE sessions with the correct webpage and login or a script that will open 3 tabs in one session (which I want) but will not login. I have tried _IECreate, IEAttach etc. This is the script I am currently using . 
      #include <IE.au3> Const $navOpenInNewTab = 0x0800 Dim $oIE = _IECreate('http://asag.xxxxxxx.com/AAAA/index.htm') ;$o_IE.Navigate2('http://asag.xxxxxxx.com/apps/yyyyyyy/LogInSAG/login.asp', $navOpenInNewTab) ;$o_IE.Navigate2('http://asag.xxxxxxx.com/apps/yyyyyyy/LogInSAG/login.asp', $navOpenInNewTab) Call ("YYYYYYYSignIn") Func YYYYYYYSignIn () Local $username = _IEGetObjByName ($oIE,"uname") Local $password = _IEGetObjByName ($oIE,"pword") $oIE.Navigate2('http://asag.xxxxxxx.com/apps/xxxxxxx/LogInSAG/login.asp',2048) _IEFormElementSetValue ($username, "xxxxxxx") _IEFormElementSetValue ($password, "xxxxxxx") Send('{Enter}') EndFunc Call ("xxxxxxxSignIn") Func xxxxxxxSignIn () __IENavigate($oIE, "https://soa1gui.xxxxxxx.biz/gateway/NFServlet;jsessionid=1E3B8F6520DE0A1EC914A8ABB7E86341?NFH_MessageId=&NFH_Page=%2fpages%2fsearch%2fsearch.jsp", 1, 0x800) Local $domain = _IEGetObjByName ($oIE,"NF_CustomerID") Local $User_Name = _IEGetObjByName ($oIE,"NF_UserName") Local $Password = _IEGetObjByName ($oIE,"NF_Password") _IEFormElementSetValue ($domain, xxxxxxx") _IEFormElementSetValue ($User_Name, "xxxxxxx") _IEFormElementSetValue ($Password, "xxxxxxx") ;Send('{Enter}') EndFunc  
    • Phoenixx177
      By Phoenixx177
      I've tried to wrap my head around it but just can't imagine how to embed 2 IE browsers in the same GUI.
      Here's what I'm doing so far.
       
      #include <GuiConstantsEx.au3> #include <windowsconstants.au3> #include <IE.au3> Global $oIE = _IECreateEmbedded() ; Create a simple GUI for our output Global $hGUI = GUICreate("Embedded Web control Test", 1280, 580, (@DesktopWidth - 1280) / 2, (@DesktopHeight - 580) / 2, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN, $WS_MAXIMIZEBOX)) Global $GUIActiveX = GUICtrlCreateObj($oIE, 10, 40, 1100, 500) _IENavigate($oIE, "http://xxxxxxxxxx.com") Global $o_doc = _IEDocGetObj($oIE) $o_doc.DocumentElement.ScrollTop = 140 $o_doc.DocumentElement.ScrollLeft = 170 GUISetState() While GUIGetMsg() <> -3 WEnd