Uten Posted May 2, 2006 Share Posted May 2, 2006 Multi threaded dll created in freebasic.From time to time people as for multi threading in AutoIt. Although I think it would be cool to have the ability of launching code in a new thread I do not think it will happens before someone steps up and are prepared to practically create a new AutoIt code base. I say this because I have read what better informed people than me are saying about the subject.Anyhow, you have this killer idea whom really needs to be done asynchronously what do you do? You write it in C/C++, VB or you can, do it as done in this sample, write it in freebasic. Why would you do it in two languages rather than one. Probably because AutoIt is pretty nice for what it does best, act as the glue between your code and windows applications. You maybe have experience in creating simple GUI's in AutoIt. And the fileinstall function is probably the simplest way you can have your small utilities wrapped up in one exe. No install hazel.Enough said. Her is a sample multithreaded dll written in freebasic version 0.15. The sample consist of 4 files. 1: The dll code 2: A dll interface definition to be used with freebasic applications. 3: A freebasic test application. 4: A AutoIt v3 Beta 118 applicationYou will also find all files, including compiled dll and freebasic test app, in a attached zip file at the bottom of this post.The dll: thdll.basexpandcollapse popup' FILENAME: thdll.bas ' COMPILE: fbc -dll thdll.bas ' PURPOSE: Demonstrate a multithreaded dll created with freebasic ' Include is not suposed to be used when we compile as dll ??? #include once "thdll.bi" dim shared gState as integer ' Status reflecting the job done in the thread dim shared gRun as integer ' Flag telling the thread to run or quit dim shared gCalls as integer ' Counting call's to this api dim gTH as integer ' Thread handel ID dim gMutexID as integer ' mutex id to be used when shared variables are updated. ' ' PURPOSE: Test calling conventions from application function AddNumbers CDECL(byval operand1 as integer, byval operand2 as integer) as integer export Return (operand1 + operand2) end function ' ' PURPOSE: Function to run in seperate tread. SUB mythread CDECL ( byval mutexID as integer ) ' Do some realy lengthy woork While gRun = 1 mutexlock(mutexID) ' Use mutex to lock memmory before update gState = gState + 1 mutexunlock(mutexID) 'print "gState:="; gState Sleep(1000) Wend END SUB ' ' PURPOSE: Start a thread FUNCTION Startit CDECL () AS INTEGER export gState = 0 gCalls +=1 gRun = 1 gMutexID = mutexcreate() gTH=threadcreate(@mythread, gMutexID) dim ret as integer ret = gTH Startit = ret END FUNCTION ' ' PURPOSE: Stop the thread FUNCTION Stopit CDECL () AS INTEGER export gCalls +=1 gRun = 0 if gTH <> 0 Then threadwait(gTH) mutexdestroy(gMutexID) Endif gTH = 0 Stopit = 1 END FUNCTION ' ' PURPOSE: Get a simple status message regarding the thread FUNCTION Status CDECL () AS INTEGER export Dim ret as integer gCalls +=1 mutexlock(gMutexID) ret = gState mutexunlock(gMutexID) 'print "Status gState:="; gState Status = ret END FUNCTION function Calls CDECL () as integer export Calls = gCalls end functionThe interface file thdll.bi'FILENAME: th.bi 'PURPOSE: Declarations for exported functions in thdll.bas ' 'NOTE: I got weired results before I did it all from scratch and aded on function, on declaration ' testcode in the runer and compiled. Did that until all functions were added. ' So I suspect that you can get in trouble if the function sequence in this file does not follow ' the sequence in the dll file. BUT I'M NOT SERTAN! declare function AddNumbers CDECL lib "thdll" alias "AddNumbers" ( byval operand1 as integer, byval operand2 as integer ) as integer declare FUNCTION Startit CDECL lib "thdll" alias "Startit" () AS INTEGER declare FUNCTION Stopit CDECL lib "thdll" alias "Stopit" () AS INTEGER declare FUNCTION Status CDECL lib "thdll" alias "Status" () AS INTEGER declare FUNCTION Calls CDECL lib "thdll" alias "Calls" () AS INTEGERThe freebasic test application (console): thrun.bas'FILENAME: thrun.bas 'COMPILE: fbc thrun.bas 'PURPOSE: test functionality in thdll.bas 'USAGE: Run in command box. thdll.dll must be in path (same folder) #include "thdll.bi" ' Include file containing dll api interface randomize timer x = rnd * 10 y = rnd * 10 print x; " +"; y; " ="; AddNumbers( x, y ) dim nTh as integer nTh = Startit() 'Starting the thread while n <= 10 'Let it work for a while print "Status:="; Status() sleep(333) Wend nTh = Stopit() 'Stop the thread print "Finished : "; Status(); Calls()The AutoIt test application: thrun.au3expandcollapse popup;FILENAME: thrun.au3 ; ;mutithreaddll runner local $dllfilename = @ScriptDir & "\" & "thdll.dll" local $dll = DllOpen($dllfilename) local $ret if $dll = - 1 then msgbox(16, "ERROR", "Could not load dll " & $dllfilename) Else MsgBox(0,"ADDNUMBERS","Just a dll call test" & @CRLF & "2 + 2 = " & apiAddNubers(2, 2)) apiStartit() while (apiStatus() < 20) ConsoleWrite(apiStatus() & " - ") sleep(900) Wend MsgBox(0,"FINISHED","Loop finished: status():=" & apiStatus()) EndIf exit Func OnAutoitExit() msgbox(0,"TERMINATING", "OnAutoitExit") apiStopit() if $dll <> -1 then DllClose($dll) endif EndFunc Func apiStartit() Local $ret = dllcall($dll, "int","Startit") Local $err = @error if $err <> 0 then DllError($err) EndIf Return $ret[0] EndFunc Func apiStopit() Local $ret = dllcall($dll, "int", "Stopit") Local $err = @error if $err <> 0 then DllError($err) EndIf Return $ret[0] EndFunc Func apiStatus() Local $ret = dllcall($dll, "int", "Status") Local $err = @error if $err <> 0 then DllError($err) EndIf Return $ret[0] EndFunc Func apiAddNubers($arg1, $arg2) Local $ret = dllcall($dll , "int", "AddNumbers", "int", $arg1, "int", $arg2) Local $err = @error if $err <> 0 then DllError($err) $ret = -1 EndIf Return $ret[0] EndFunc Func DllError($err) Local $errMessage switch $err case 1 $errMessage = "Unable to use the DLL file" case 2 $errMessage = "unknown return type" case 3 $errMessage = "function not found in the DLL file" case Else $errMessage = "Unknow error number: " & $err EndSwitch msgbox(16, "DllError", "Error occured" & @CRLF & $errMessage) EndFuncHappy coding, Utenthdll.zip mLipok 1 Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
ptrex Posted May 2, 2006 Share Posted May 2, 2006 @Uten This is very enlightning for those who want to create own written DLL's, and glue into AutoIT. I am not a Freebasic man myself but it looks very inviting More examples are welcome if it expands to possibilities of AutoIT. Very nice !! Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted May 2, 2006 Moderators Share Posted May 2, 2006 @UtenThis is very enlightning for those who want to create own written DLL's, and glue into AutoIT.I am not a Freebasic man myself but it looks very inviting More examples are welcome if it expands to possibilities of AutoIT.Very nice !!Yeah, I poked around in the forum for the first time today (saw a couple of your post too uten ), the syntax looks easy enough to get down (a tad confusing in parts), but the possibility of effortlessly multithreading this way is appealing indeed (finally have a need for it after all this time with 1 of my scripts).I haven't downloaded it yet, I'm going to do some more reading first, but thank you so much for the continued enlightenment and possible solutions for non-existant options at this time! 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. Link to comment Share on other sites More sharing options...
Uten Posted May 2, 2006 Author Share Posted May 2, 2006 I might add that this was my first attempt at doing anything with freebasic. I did some reading about it and in the help files a while ago and thought it would be worth a try. It took me more than the three hours I thought I would have to spend to get it going, but now it is done. The compiler is quite young so I think one should expect hiccups along the way. But it is open source, (and if I recall correctly the current compiler is written in freebasic, so if it does not fit your bill you can do something about it Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
jackyyll Posted May 3, 2006 Share Posted May 3, 2006 Good stuff! ^^ Gonna use this in my next project .. if i ever start it lol Link to comment Share on other sites More sharing options...
themax90 Posted July 28, 2006 Share Posted July 28, 2006 I seriously need AutoIt to support multithreading. Singlethread makes networking near impossible. I would love to hear a method that works. Link to comment Share on other sites More sharing options...
arcker Posted July 30, 2006 Share Posted July 30, 2006 1 -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013Â Get it Here [/list] Link to comment Share on other sites More sharing options...
Uten Posted July 30, 2006 Author Share Posted July 30, 2006 +1???@AutoIt Smith: A search and read session in the forums will explain why AutoIt is not multithreading ready by itselfe (and I'm shure you allready know this.. ). It was not designed for multithreading and the code is not reentrant safe. If we, the userbase, really want it to be multithreaded I think we have to take the provided source and make it thread safe (as a profe of consept) and then hope the developers of AutoIt will accept the changes and let the people whome has doen them make the requiered changes to the rest of the AutoIt code or do it them selfe. If you want to do this remember that size matters both to the community and the developers.It should not be to much hazzle to make a mulithreaded networking component (dll or plugin) in freebasic (or C++) and use it in AutoIt. Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling Link to comment Share on other sites More sharing options...
The Kandie Man Posted November 20, 2006 Share Posted November 20, 2006 (edited) Yes, this should come in quite handy. As you guys probably know i have written a search engine in autoit and right now i am using a FreeBasic dll to do the searching since it is faster than autoit. The only problem is that i need to create another thread so that the search function in the dll doesn't pause the whole program as it searches for files which only take a couple seconds, but the program should never be unresponsive. Thanks Uten. I will probably end up writing this into my searchengine.dll. -The Kandie Man EDIT: Got it to work. Woot! Now all i have to do is some slight modification to my main autoit search engine script. Edited November 20, 2006 by The Kandie Man "So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire Link to comment Share on other sites More sharing options...
wraithdu Posted July 12, 2008 Share Posted July 12, 2008 (edited) I was very impressed by this and wanted to learn FreeBASIC to try and create some shell extensions for AutoIt (not there yet though). So to start learning I expanded on this example a bit to something a bit more AutoIt relevant, and that is threaded Message Boxes. Simple, but a good place to start and illustrate the example. The example script I have demonstrates a few things that can be done. First is the use of mutexes in FreeBASIC to control threads. I've commented out 2 of the Mutex*** lines so all the message boxes pop up at once to demonstrate the threading, but if you put them back in and recompile the DLL then the boxes will come up one at a time, but the threads will be queued, meaning your script is still running and the closing / opening of the boxes is independent. Second is an example of passing an array of information back to AutoIt. The _GetMutex() function passes back a pointer to a 2 element array with the handles of the 2 created mutexes. The values are retrieved by creating a DllStruct at the pointer. Third is an example of properly waiting for all the threads to terminate before closing the AutoIt script. The main message boxes use the _ThreadWait() function in a loop, and the _GetMutex() boxes are stored by the DLL, and use the _WaitFinished() function to wait for them to close. I tried to put this loop in the Destructor so the DLL would wait automatically, but it didn't work. For some reason the DLL cannot see that the threads are closed and so it hangs in the loop. If anyone knows why, please do tell. Oh, it's also got an elementary use of Types. This is the first time I've used one, so it was a good learning experience. I tried to pass a type structure back to AutoIt in the _GetMutex() function, and while AutoIt got the pointer correctly, I could not retrieve the data with the DllStruct like I could with the array. If anyone knows the answer to that one, I'd like to know as well. This could pretty easily be extended for any functions you need to run threaded from an AutoIt script. I hope it's useful! thdll.dll source (thdll.bas) expandcollapse popup#Include Once "windows.bi" Dim Shared As Any Ptr hMutex, tMutex, mutexptr(1) ReDim Shared As Any Ptr mboxwait(0) Type boxinfo hWnd As HWND As String lpText, lpCaption uType As UInteger End Type Dim Shared mbox As boxinfo Sub _onstart Constructor hMutex = MutexCreate() tMutex = MutexCreate() mutexptr(0) = hMutex mutexptr(1) = tMutex End Sub Sub _tMessageBox (mPtr As boxinfo Ptr) Dim info As boxinfo = *mPtr MutexUnlock(tMutex) ' MutexLock(hMutex) MessageBox(info.hWnd, info.lpText, info.lpCaption, info.uType) ' MutexUnLock(hMutex) End Sub Function _MessageBox Cdecl Alias "_MessageBox" (ByVal hWnd As HWND, ByVal lpText As String, ByVal lpCaption As String, ByVal uType As UInteger) As Any Ptr Export Dim hThread As Any Ptr MutexLock(tMutex) mbox.hWnd = hWnd mbox.lpText = lpText mbox.lpCaption = lpCaption mbox.uType = uType hThread = ThreadCreate(Cast(Any Ptr, @_tMessageBox), @mbox) Return hThread End Function Function _GetMutex Cdecl Alias "_GetMutex" () As Any Ptr Export Dim hThread As Any Ptr hThread = _MessageBox(NULL, "Mutex ptr: 0x" & Hex(@mutexptr(0)) & Chr(13) & "hMutex: 0x" & Hex(hMutex) & Chr(13) & "tMutex: 0x" & Hex(tMutex), "INFO", MB_OK Or MB_ICONEXCLAMATION) If mboxwait(UBound(mboxwait)) <> 0 Then ReDim Preserve mboxwait(UBound(mboxwait) + 1) mboxwait(UBound(mboxwait)) = hThread Else mboxwait(UBound(mboxwait)) = hThread EndIf Return @mutexptr(0) End Function Function _WaitThread Cdecl Alias "_WaitThread" (ByVal wThread As Any Ptr) As Integer Export ThreadWait(wThread) Return ERROR_SUCCESS End Function Function _WaitFinished Cdecl Alias "_WaitFinished" () As Integer Export Dim i As Integer For i = 0 To UBound(mboxwait) ThreadWait(mboxwait(i)) Next i Return ERROR_SUCCESS End Function Sub _OnExit Destructor MutexDestroy(hMutex) MutexDestroy(tMutex) End Sub And the example AutoIt script. Watch the console for the output information. NOTE: The DLL must use DllOpen() / DllClose() so the mutex and other information persists across DLL calls. expandcollapse popup$dllname = @ScriptDir & "\thdll.dll" $dll = DllOpen($dllname) For $i = 1 To 3 $ret = DllCall($dll, "ptr:cdecl", "_GetMutex") Next ConsoleWrite("Mutex array ptr: " & $ret[0] & @CRLF) $mutex = DllStructCreate("ptr m1; ptr m2", $ret[0]) ConsoleWrite("Mutex 1: " & DllStructGetData($mutex, "m1") & @CRLF) ConsoleWrite("Mutex 2: " & DllStructGetData($mutex, "m2") & @CRLF & @CRLF) Dim $thread[3] For $i = 1 To 3 $ret = DllCall($dll, "ptr:cdecl", "_MessageBox", _ "hwnd", Chr(0), _ "str", "Message Box " & $i, _ "str", "Thread Test", _ "uint", BitOR(0, 64) _ ) ConsoleWrite("Error: " & @error & @CRLF) ConsoleWrite("Ret: " & $ret[0] & @CRLF) $thread[$i - 1] = $ret[0] Next ConsoleWrite(@CRLF & "-> ** do stuff while message boxes are up **" & @CRLF & @CRLF) For $i = 0 To 2 $ret = DllCall($dll, "int:cdecl", "_WaitThread", "ptr", $thread[$i]) ConsoleWrite("Thread " & $thread[$i] & " done." & @CRLF) ConsoleWrite("Error: " & @error & @CRLF) ConsoleWrite("Ret: " & $ret[0] & @CRLF) Next ConsoleWrite(@CRLF & "-> ** Waiting for _GetMutex() message boxes to close... **" & @CRLF) DllCall($dll, "int:cdecl", "_WaitFinished") ConsoleWrite(@CRLF & "-> ** All threads finished! **" & @CRLF) DllClose($dll) ConsoleWrite("DLL closed." & @CRLF) Edited July 12, 2008 by wraithdu Link to comment Share on other sites More sharing options...
Beege Posted February 11, 2009 Share Posted February 11, 2009 I know this is an old topic but autoit is crashing with this dll now. And any dll i try to make with freebasic for that matter. Any Ideas? >AutoIT3.exe ended.rc:-1073741819 >Exit code: -1073741819 Time: 5.522 Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator Link to comment Share on other sites More sharing options...
ProgAndy Posted February 11, 2009 Share Posted February 11, 2009 (edited) You can create threads with Autoit, so you don't need a DLl to do that. You just mustn't use an AutoIt-Function with DLLCallbackRegister as the Thread-Functions. (The thread runs, but AutoIt crahses after a few secs)So yo have to use just one func in the DLL which wil be the ThreadProc. For Messageboxes you could use the MessageBoxIndirect from user32.dll. Example at the end of script: expandcollapse popupGlobal Const $STATUS_PENDING = 0x103 Global Const $STILL_ACTIVE = $STATUS_PENDING ; ThreadID is @extended ;=============================================================================== ; ; Function Name: _Thread_Create ; Description:: Creates a thread ; Parameter(s): see MSDN (lpThreadId is removed) ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; @extended will be ThreadID ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Create($lpThreadAttributes, $dwStackSize, $lpStartAddress, $lpParameter, $dwCreationFlags) Local $result = DllCall("kernel32.dll","ptr","CreateThread", "ptr", $lpThreadAttributes, "dword", $dwStackSize, "ptr", $lpStartAddress, "ptr", $lpParameter, "dword", $dwCreationFlags, "dword*", 0) Return SetError($result[0]=0,$result[6],$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_Terminate ; Description:: Terminates a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Terminate($hThread,$dwExitCode) Local $result = DllCall("Kernel32.dll","int","TerminateThread","ptr",$hThread,"dword",$dwExitCode) Return SetError($result[0]=0,0,$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_Exits ; Description:: Exits the current thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): none ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Exit($dwExitCode) DllCall("Kernel32.dll","none","ExitThread","dword",$dwExitCode) EndFunc ;=============================================================================== ; ; Function Name: _Thread_GetExitCode ; Description:: retrieves ExitCode of a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_GetExitCode($hThread) Local $result = DllCall("Kernel32.dll","int","GetExitCodeThread","ptr",$hThread,"dword*",0) Return SetError($result[0]=0,0,$result[2]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_GetID ; Description:: retrieves ThreadID of a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_GetID($hThread) Local $result = DllCall("Kernel32.dll","dword","GetThreadId","ptr",$hThread) Return SetError($result[0]=0,0,$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_GetPriority ; Description:: retrieves priority of a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_GetPriority($hThread) Local $result = DllCall("Kernel32.dll","int","GetThreadPriority","ptr",$hThread) Return SetError($result[0]=0,0,$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_SetPriority ; Description:: sets priority of a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_SetPriority($hThread,$nPriority) Local $result = DllCall("Kernel32.dll","int","SetThreadPriority","ptr",$hThread,"int",$nPriority) Return SetError($result[0]=0,0,$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_Suspend ; Description:: suspends a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Suspend($hThread) Local $result = DllCall("Kernel32.dll","int","SuspendThread","ptr",$hThread) Return SetError($result[0]=-1,0,$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_Resume ; Description:: resumes a thread ; Parameter(s): see MSDN ; Requirement(s): minimum Win2000 ; Return Value(s): see MSDN ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Resume($hThread) Local $result = DllCall("Kernel32.dll","int","ResumeThread","ptr",$hThread) Return SetError($result[0]=-1,0,$result[0]) EndFunc ;=============================================================================== ; ; Function Name: _Thread_Wait ; Description:: Waits for a thread to terminate ; Parameter(s): $hThread - Handle of thread ; $nTimeOut - [optional] Timeout (default: 0xFFFFFFFF => INFINTE) ; Requirement(s): minimum Win2000 ; Return Value(s): Success: true ; on TimeOut, @eeor will be set to -1 ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Wait($hThread,$nTimeout=0xFFFFFFFF) Local $result = DllCall("Kernel32.dll", "dword", "WaitForSingleObject", "ptr", $hThread, "int", $nTimeout) If @error Then Return SetError(2,0,0) Switch $result[0] Case -1, 0xFFFFFFFF Return SetError(1,0,0) Case 0x00000102 Return SetError(-1,0,1) Case Else Return 1 EndSwitch EndFunc #include <WinAPI.au3> $tagMSGBOXPARAMS = _ "UINT cbSize;" & _ "HWND hwndOwner;" & _ "ptr hInstance;" & _ "ptr lpszText;" & _ "ptr lpszCaption;" & _ "DWORD dwStyle;" & _ "ptr lpszIcon;" & _ "UINT_PTR dwContextHelpId;" & _ "ptr lpfnMsgBoxCallback;" & _ "DWORD dwLanguageId;" ; creates a struct for an Unicode-String Func _UnicodeStruct($text) ; Prog@ndy Local $s = DllStructCreate("wchar[" & StringLen($text)+1 & "]") DllStructSetData($s,1,$text) Return $s EndFunc ; retrieves Address of a function Func _Thread_GetProcAddress($hModule,$sProcname) ; Prog@ndy Local $result = DllCall("kernel32.dll","ptr","GetProcAddress","hwnd",$hModule,"str",$sProcname) Return $result[0] EndFunc ; Struct to send to the Thread ; in this case the MsgBox-Params $MSGBOXPARAMS = DllStructCreate($tagMSGBOXPARAMS) DllStructSetData($MSGBOXPARAMS,"cbSize",DllStructGetSize($MSGBOXPARAMS)) $stText = _UnicodeStruct("The messageBox in a separate thead!") DllStructSetData($MSGBOXPARAMS,"lpszText",DllStructGetPtr($stText)) $stCaption = _UnicodeStruct("Caption") DllStructSetData($MSGBOXPARAMS,"lpszCaption",DllStructGetPtr($stCaption)) DllStructSetData($MSGBOXPARAMS,"dwStyle",17) ; msgBox-style ; Use MessageBoxIndirect Unicode as ThreadProc ; normal MessageBox doesn't work, since CreateThread just has one possible parameter. Local $hThreadProc = _Thread_GetProcAddress(_WinAPI_GetModuleHandle("user32.dll"),"MessageBoxIndirectW") $hThread = _Thread_Create(0 ,0, $hThreadProc, DllStructGetPtr($MSGBOXPARAMS), 0) $ThreadID = @extended While MsgBox(69, "main", "Main script is not blocked" )=4 WEnd MsgBox(0, "Thread-Info", "Handle: " & $hThread & @CRLF & "Thread-ID: " & $ThreadID) _Thread_Wait($hThread) $code = _Thread_GetExitCode($hThread) MsgBox(0, 'Thread ended', "Threaded MsgBox returned: " & $code) Edited May 21, 2009 by ProgAndy mLipok 1 *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
wraithdu Posted February 11, 2009 Share Posted February 11, 2009 @ProgAndy Nice little example. Is there any reason you don't use _WinAPI_WaitForSingleObject($hThread) in your _Thread_Wait() function? Link to comment Share on other sites More sharing options...
Beege Posted February 11, 2009 Share Posted February 11, 2009 yes that was a great example. Thanks! Im going to play with those. Anyway I figured out the problem regarding freebasic dll. Functions need to be called with cdecl after the return value for this dll. Ex: $ret = dllcall($dll, "int:cdecl","Startit") Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator Link to comment Share on other sites More sharing options...
ProgAndy Posted February 12, 2009 Share Posted February 12, 2009 (edited) @ProgAndy Nice little example. Is there any reason you don't use _WinAPI_WaitForSingleObject($hThread) in your _Thread_Wait() function?There is just one reason: i forgot to use it ... Here it is: ;=============================================================================== ; ; Function Name: _Thread_Wait ; Description:: Waits for a thread to terminate ; Parameter(s): $hThread - Handle of thread ; $nTimeOut - [optional] Timeout (default: 0xFFFFFFFF => INFINTE) ; Requirement(s): minimum Win2000 ; Return Value(s): Success: true ; on TimeOut, @eeor will be set to -1 ; On error, @error will be set to 1 ; Author(s): Prog@ndy ; ;=============================================================================== ; Func _Thread_Wait($hThread,$nTimeout=0xFFFFFFFF) Local $result = DllCall("Kernel32.dll", "dword", "WaitForSingleObject", "ptr", $hThread, "int", $nTimeout) If @error Then Return SetError(2,0,0) Switch $result[0] Case -1, 0xFFFFFFFF Return SetError(1,0,0) Case 0x00000102 Return SetError(-1,0,1) Case Else Return 1 EndSwitch EndFunc Edited February 12, 2009 by ProgAndy *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
rajeshwaran Posted September 6, 2010 Share Posted September 6, 2010 Hi ProgAndy, The implementation is simple, still I cant understand the below line _Thread_GetProcAddress(_WinAPI_GetModuleHandle("user32.dll"),"MessageBoxIndirectW") Can you provide a simple example to just call a user defined function MyFunction() inside the _Thread_Create() function $hThread = _Thread_Create(0 ,0, MyFunction, DllStructGetPtr($MSGBOXPARAMS), 0) Link to comment Share on other sites More sharing options...
ProgAndy Posted September 6, 2010 Share Posted September 6, 2010 What do you mean with user defined function? A function written in AutoIt? That won't work since the AutoIt-interpreter is not threadsafe. What you can do is creating a function in a DLL and use that as a thread: DLLOpen("myThreadFunc.dll") ;<- open DLL $hDLLHandle = _WinAPI_GetModuleHandle("myThreadFunc.dll") ; get address of the loaded DLL $hThreadProc = _Thread_GetProcAddress($hDLLHandle, "MyThreadFunc") ; get address of the function in the dll *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes Link to comment Share on other sites More sharing options...
rajeshwaran Posted September 6, 2010 Share Posted September 6, 2010 Thank you very much for your fast response. If I create a function in DLL then, I cant access AutoIt Script file resoruces (variables/functions). So how to overcome this problem ? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now