Leaderboard
Popular Content
Showing content with the highest reputation on 09/15/2013 in all areas
-
2 points
-
_GUICtrlMenu_Recent() is for those that enjoy using GUICtrlCreateMenu() and would love to have the ability to have a "Recent" menu list with little to no fuss at all. The UDF contains only 7 functions and due to the design of the UDF, reading the recent menu item that was chosen is very easy indeed. Try the Example provided to get an idea of how it works. Any suggestions or improvements then please post below. Thanks. Example: UDF: #include-once ; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7 ; #INDEX# ======================================================================================================================= ; Title .........: _GUICtrlMenu_Recent_ ; AutoIt Version : v3.3.12.0 or higher ; Language ......: English ; Description ...: Create a recent menu to add previously opened files or other text items to. ; Author(s) .....: guinness ; =============================================================================================================================== ; #INCLUDES# ========================================================================================================= #include <WinAPI.au3> ; #GLOBAL VARIABLES# ================================================================================================= Global Const $RECENTMENU_GUID = '051F0003-4E0A-4E4B-8B1A-113B16972254' Global Const $RECENTMENU = 0 Global Const $RECENTMENU_STARTINDEX = 1 Global Enum $RECENTMENU_CAPACITY, $RECENTMENU_ID, $RECENTMENU_INDEX, $RECENTMENU_MENUID, $RECENTMENU_MAX Global Enum $RECENTMENU_CONTROLID, $RECENTMENU_FILEPATH, $RECENTMENU_SHORTPATH ; #CURRENT# ===================================================================================================================== ; _GUICtrlMenu_RecentAdd: Add an item to the recent menu that was created by _GUICtrlMenu_RecentCreate(). ; _GUICtrlMenu_RecentCapacity: Change the total number of items to be displayed in the recent menu. ; _GUICtrlMenu_RecentCreate: Create a recent menu that is added to an existing menu created by GUICtrlCreateMenu(). ; _GUICtrlMenu_RecentDelete: Delete an item in the recent menu that was created by _GUICtrlMenu_RecentCreate(). ; _GUICtrlMenu_RecentDestroy: Destroy the handle created by _GUICtrlMenu_RecentCreate(). ; _GUICtrlMenu_RecentIsInMenu: Search if a filepath or text is currently in the menu list. ; _GUICtrlMenu_RecentSelected: Retrieve the text of a selected menu item and delete from the menu list. ; =============================================================================================================================== ; #INTERNAL_USE_ONLY#============================================================================================================ ; __GUICtrlMenu_RecentDelete ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentAdd ; Description ...: Add an item to the recent menu that was created by _GUICtrlMenu_RecentCreate(). ; Syntax ........: _GUICtrlMenu_RecentAdd(ByRef $aRecentMenu, $sText) ; Parameters ....: $aRecentMenu - $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] ; $sText - Text to be added to the recent menu. ; $bShortText - [optional] Display the text as short text e.g. 'C:\Example...\Test.au3'. Default is False. ; Return values .: Success - ControlID from GUICtrlCreateMenuItem(). ; Failure - 0 and sets @error to non-zero. ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentAdd(ByRef $aRecentMenu, $sText, $bShortText = False) Local $iError = 1, $iReturn = 0 If __GUICtrlMenu_IsAPI($aRecentMenu) Then _GUICtrlMenu_RecentIsInMenu($aRecentMenu, $sText) __GUICtrlMenu_RecentDelete($aRecentMenu, @extended) If $aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] = $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] Then __GUICtrlMenu_RecentDelete($aRecentMenu, $RECENTMENU_STARTINDEX) EndIf Local $sShortText = $sText If IsBool($bShortText) And $bShortText Then $sShortText = StringRegExpReplace($sText, '(^.{3,11}\\|.{11})(.*)(\\.{6,27}|.{27})$', '\1...\3') ; Thanks to AZJIO for the regular expression. EndIf $aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] += 1 $aRecentMenu[$aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX]][$RECENTMENU_CONTROLID] = GUICtrlCreateMenuItem($sShortText, $aRecentMenu[$RECENTMENU][$RECENTMENU_MENUID], 0) $aRecentMenu[$aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX]][$RECENTMENU_FILEPATH] = $sText $aRecentMenu[$aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX]][$RECENTMENU_SHORTPATH] = $sShortText $iReturn = $aRecentMenu[$aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX]][$RECENTMENU_CONTROLID] $iError = (($iReturn > 0) ? 1 : 0) EndIf Return SetError($iError, 0, $iReturn) EndFunc ;==>_GUICtrlMenu_RecentAdd ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentCapacity ; Description ...: Change the total number of items to be displayed in the recent menu. ; Syntax ........: _GUICtrlMenu_RecentCapacity(ByRef $aRecentMenu, $iCapacity) ; Parameters ....: $aRecentMenu - [in/out] Handle created by _GUICtrlMenu_RecentCreate(). ; $iCapacity - Maximum total number of recent menu items to be displayed. If this is exceeded then old values will be overwritten. ; Return values .: Success - True ; Failure - False ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentCapacity(ByRef $aRecentMenu, $iCapacity) Local $bReturn = False If __GUICtrlMenu_IsAPI($aRecentMenu) Then $iCapacity = Int($iCapacity) If $iCapacity >= $RECENTMENU_STARTINDEX And $iCapacity <> $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] Then $bReturn = True If $iCapacity < $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] Then For $i = $RECENTMENU_STARTINDEX To ($aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] - $iCapacity) GUICtrlDelete($aRecentMenu[$i][$RECENTMENU_CONTROLID]) Next Local $iIndex = ($aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] - $iCapacity) + 1 For $i = $RECENTMENU_STARTINDEX To $iCapacity For $j = 0 To $RECENTMENU_MAX - 1 $aRecentMenu[$i][$j] = $aRecentMenu[$iIndex][$j] Next $iIndex += 1 Next $aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] = $iCapacity EndIf $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] = $iCapacity ReDim $aRecentMenu[$aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] + $RECENTMENU_STARTINDEX][$RECENTMENU_MAX] EndIf EndIf Return $bReturn EndFunc ;==>_GUICtrlMenu_RecentCapacity ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentCreate ; Description ...: Create a recent menu that is added to an existing menu created by GUICtrlCreateMenu(). ; Syntax ........: _GUICtrlMenu_RecentCreate($iCapacity, $iMenu, $sTitle) ; Parameters ....: $iCapacity - Maximum total number of recent menu items to be displayed. If this is exceeded then old values will be overwritten. ; $iMenu - Existing menu id created by GUICtrlCreateMenu(). ; $sTitle - Title of the recent menu. ; Return values .: Success - Handle to be passed to the recent menu functions. ; Failure - None ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentCreate($iCapacity, $iMenu, $sTitle) If $iCapacity = Default Or Int($iCapacity) <= 0 Then $iCapacity = 10 EndIf Local $aRecentMenu[$iCapacity + $RECENTMENU_STARTINDEX][$RECENTMENU_MAX] $aRecentMenu[$RECENTMENU][$RECENTMENU_ID] = $RECENTMENU_GUID $aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] = 0 ; Index of next item. $aRecentMenu[$RECENTMENU][$RECENTMENU_MENUID] = (($iMenu > 0) ? GUICtrlCreateMenu($sTitle, $iMenu) : GUICtrlCreateMenu($sTitle)) $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] = $iCapacity ; Total number of rows. Return $aRecentMenu EndFunc ;==>_GUICtrlMenu_RecentCreate ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentDelete ; Description ...: Delete an item in the recent menu that was created by _GUICtrlMenu_RecentCreate(). ; Syntax ........: _GUICtrlMenu_RecentDelete(ByRef $aRecentMenu, $vIndex) ; Parameters ....: $aRecentMenu - [in/out] Handle created by _GUICtrlMenu_RecentCreate(). ; $vIndex - Value to be deleted. This can either be an integer of the handle index (see _GUICtrlMenu_RecentIsInMenu() and remarks) ; or a string value of the item. ; Return values .: Success - True ; Failure - False ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentDelete(ByRef $aRecentMenu, $vIndex) Local $bReturn = False If __GUICtrlMenu_IsAPI($aRecentMenu) Then If IsString($vIndex) Then _GUICtrlMenu_RecentIsInMenu($aRecentMenu, $vIndex) $vIndex = @extended EndIf $bReturn = __GUICtrlMenu_RecentDelete($aRecentMenu, $vIndex) EndIf Return $bReturn EndFunc ;==>_GUICtrlMenu_RecentDelete ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentDestroy ; Description ...: Destroy the handle created by _GUICtrlMenu_RecentCreate(). ; Syntax ........: _GUICtrlMenu_RecentDestroy(ByRef $aRecentMenu) ; Parameters ....: $aRecentMenu - [in/out] Handle created by _GUICtrlMenu_RecentCreate(). ; Return values .: Success - True ; Failure - False ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentDestroy(ByRef $aRecentMenu) Local $bReturn = False If __GUICtrlMenu_IsAPI($aRecentMenu) Then $bReturn = True For $i = $RECENTMENU_STARTINDEX To $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] GUICtrlDelete($aRecentMenu[$i][$RECENTMENU_CONTROLID]) Next EndIf $aRecentMenu = 0 Return $bReturn EndFunc ;==>_GUICtrlMenu_RecentDestroy ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentIsInMenu ; Description ...: Search if a filepath or text is currently in the menu list. ; Syntax ........: _GUICtrlMenu_RecentIsInMenu(ByRef $aRecentMenu, $sText) ; Parameters ....: $aRecentMenu - [in/out] Handle created by _GUICtrlMenu_RecentCreate(). ; $sText - Text to search for. This is a case-sensitive search. ; Return values .: Success - True and sets @extended to the index position of the text. ; Failure - False and sets @extended to zero. ; Author ........: guinness ; Remarks .......: @extended is set to the index position in the handle. This is useful if using GUICtrlMenu_RecentDelete(). ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentIsInMenu(ByRef $aRecentMenu, $sText) Local $bReturn = False, _ $iExtended = 0 If __GUICtrlMenu_IsAPI($aRecentMenu) Then For $i = $RECENTMENU_STARTINDEX To $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] If ($sText == $aRecentMenu[$i][$RECENTMENU_FILEPATH]) Or ($sText == $aRecentMenu[$i][$RECENTMENU_SHORTPATH]) Then $bReturn = True $iExtended = $i ExitLoop EndIf Next EndIf Return SetExtended($iExtended, $bReturn) EndFunc ;==>_GUICtrlMenu_RecentIsInMenu ; #FUNCTION# ==================================================================================================================== ; Name ..........: _GUICtrlMenu_RecentSelected ; Description ...: Retrieve the text of a selected menu item and delete from the menu list. ; Syntax ........: _GUICtrlMenu_RecentSelected(ByRef $aRecentMenu, $iMsg) ; Parameters ....: $aRecentMenu - [in/out] Handle created by _GUICtrlMenu_RecentCreate().. ; $iMsg - Message id returned by GUIGetMsg(). ; Return values .: Success - Text of the selected menu. ; Failure - Null and sets @error to non-zero. ; Author ........: guinness ; Example .......: Yes ; =============================================================================================================================== Func _GUICtrlMenu_RecentSelected(ByRef $aRecentMenu, $iMsg) Local $iError = 1, _ $sReturn = Null If $iMsg > 0 And __GUICtrlMenu_IsAPI($aRecentMenu) Then For $i = $RECENTMENU_STARTINDEX To $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] If $iMsg = $aRecentMenu[$i][$RECENTMENU_CONTROLID] Then $iError = 0 $sReturn = $aRecentMenu[$i][$RECENTMENU_FILEPATH] __GUICtrlMenu_RecentDelete($aRecentMenu, $i) ExitLoop EndIf Next EndIf Return SetError($iError, 0, $sReturn) EndFunc ;==>_GUICtrlMenu_RecentSelected ; #INTERNAL_USE_ONLY#============================================================================================================ Func __GUICtrlMenu_RecentDelete(ByRef $aRecentMenu, $iIndex) Local $bReturn = False If $iIndex >= $RECENTMENU_STARTINDEX And $iIndex <= $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] And GUICtrlDelete($aRecentMenu[$iIndex][$RECENTMENU_CONTROLID]) Then $bReturn = True Local $iSwap = 0 For $i = $iIndex To $aRecentMenu[$RECENTMENU][$RECENTMENU_CAPACITY] - 1 For $j = 0 To $RECENTMENU_MAX - 1 $iSwap = $i + 1 $aRecentMenu[$i][$j] = $aRecentMenu[$iSwap][$j] $aRecentMenu[$iSwap][$j] = Null Next Next $aRecentMenu[$RECENTMENU][$RECENTMENU_INDEX] -= 1 EndIf Return $bReturn EndFunc ;==>__GUICtrlMenu_RecentDelete Func __GUICtrlMenu_IsAPI(ByRef $aRecentMenu) Return UBound($aRecentMenu, $UBOUND_COLUMNS) = $RECENTMENU_MAX And $aRecentMenu[$RECENTMENU][$RECENTMENU_ID] = $RECENTMENU_GUID EndFunc ;==>__GUICtrlMenu_IsAPI Example 1: #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w 7 #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include '_GUICtrlMenu_Recent.au3' Example() Func Example() Local $hGUI = GUICreate('_GUICtrlMenu_Recent() Example', 300, 200) Local $iFileMenu = GUICtrlCreateMenu('&File') Local $iOpen = GUICtrlCreateMenuItem('Open', $iFileMenu) GUICtrlSetState($iOpen, $GUI_DEFBUTTON) ; Create a recent menu with a maximum of 5 displayed items. Local $hRecentMenu = _GUICtrlMenu_RecentCreate(5, $iFileMenu, 'Recent Files') GUICtrlCreateMenuItem('', $iFileMenu) ; Seperator Line. GUICtrlCreateMenuItem('Save', $iFileMenu) GUICtrlSetState(-1, $GUI_DISABLE) Local $iExit = GUICtrlCreateMenuItem('Exit', $iFileMenu) Local $iOpenFile = GUICtrlCreateButton('Open File', 5, 10, 85, 25) Local $iIncreaseItems = GUICtrlCreateButton('Increase Recent List', 5, 35, 115, 25) GUISetState(@SW_SHOW, $hGUI) ; Add the current script to the recent menu. _GUICtrlMenu_RecentAdd($hRecentMenu, @ScriptFullPath, True) Local $iMsg = 0, _ $sFilePath = '' While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE, $iExit ExitLoop Case $iOpenFile, $iOpen $sFilePath = FileOpenDialog('Choose File...', @ScriptDir, 'All (*.*)') If Not @error Then ; Check whether or not the filepath is currently in the recent menu. If it isn't then add to the recent menu. If Not _GUICtrlMenu_RecentIsInMenu($hRecentMenu, $sFilePath) Then ; If the button or open menu items are selected then add a filepath to the recent menu. _GUICtrlMenu_RecentAdd($hRecentMenu, $sFilePath, True) ; Display the text as short text. EndIf EndIf Case $iIncreaseItems ; Increase the capacity to 20 items instead of the previous 5. If _GUICtrlMenu_RecentCapacity($hRecentMenu, 20) Then MsgBox($MB_SYSTEMMODAL, '', 'The recent menu list was increased to a maximum of 20 items.', 0, $hGUI) Else MsgBox($MB_SYSTEMMODAL, '', 'The recent menu list wasn''t increased to a maximum of 20 items. An error occurred.', 0, $hGUI) EndIf Case Else ; Check if the message id returned by GUIGetMsg() is present in the recent menu list. $sFilePath = _GUICtrlMenu_RecentSelected($hRecentMenu, $iMsg) If Not @error Then MsgBox($MB_SYSTEMMODAL, '', 'The recent menu was selected and the following item was chosen' & @CRLF & _ @CRLF & _ $sFilePath, 0, $hGUI) EndIf EndSwitch WEnd ; Destroy the recent menu. _GUICtrlMenu_RecentDestroy($hRecentMenu) GUIDelete($hGUI) EndFunc ;==>Example All of the above has been included in a ZIP file. GUICtrlMenu_Recent.zip1 point
-
I have been putting together some forensic drive tools for quite some time, off and on for about 2 years. I recently started up on it again and decided that I would rather have a native function to create a VHD footer instead of bundling and calling VhdTool or other apps, so sat down with Microsoft's reference and put this together. This has been GUI-fied for use as a standalone tool as I am still a long way from being happy with the full suite of tools in development. Obviously if you are reading this you should know, but to explain the purpose, if you have made a forensic image of a hard drive and want to mount it or use it as a virtual hard drive in a virtual machine, you can not just use the forensic image as-is. The footer that is needed is 512 bytes appended to the image and contains various items used to verify the image. Some of Microsoft's documentation was pretty poor, but after about 8 hours of poking at it this tool is working great. The only oddity I have noticed is that following the equations given for calculating the drive geometry, the virtual shows up as having slightly less space than the original drive when it was imaged. I seem to not be alone in this as I saw several posts online from the folks who make QEMU discussing the same thing. I have the cylinder count rounding up rather than down to make a tiny correction (seems that VhdTool uses Floor, I use Ceiling) but I didn't want to tamper with things too much with the CHS calculation. Enjoy Ian footer3_gui.au31 point
-
Advice about how to create a WORLD MAP
EKY32 reacted to michaelslamet for a topic
UEZ is the master of GDI1 point -
It seems that you tried to run the code using 3.3.8.1 and not the latest beta. You have to run the code by pressing Alt+F5 in SciTE or from explorer -> Open it with AutoIt v3 beta. Br, UEZ1 point
-
do not bump. maybe this: Local $Input_1 = GUICtrlCreateInput("", 70, 20, 90, 20) Func myfuncer() send("{F4 2}"& GUICtrlRead($Input_1)) send("{F1 2}{4 2}") EndFunc saludos1 point
-
Check out _GDIPlus_PathIsVisiblePoint() example (latest beta) how to check shapes under the mouse. The example with the map of Australia shouldn't be much hard to realize with AutoIt at least with some shapes. When you look to the source code (JS) you see the boundaries are created with pathes... Br, UEZ1 point
-
GUICtrlCreateObj returns: E_NOINTERFACE - No such interface supported - 0x80004002 Looks like you can't do what you want to do with GUICtrlCreateObj.1 point
-
FFXIV: ARR Duty Notifier Question
jaberwacky reacted to TheSaint for a topic
Well, I guess all my time being civil to you and giving you an explanation, where most here wouldn't have bothered, has paid off, as we now know the cut of your jib. Have a good life.1 point -
So I helped you correctly describe your problem. Unfortunately, the answer is not within my knowledge.1 point
-
FFXIV: ARR Duty Notifier Question
jaberwacky reacted to TheSaint for a topic
AutoIt has a reputation to uphold, and issues with Anti-Virus companies, Game/Program manufacturers and Website controllers, etc can, have and do cause problems. As to your question, the key is in the word I said - insinuated. P.S. That also means, don't (like many fools in the past) just change your topic to exclude references that seem Game related. It's essentially too late for that topic and any bearing resemblance. P.S.S. The MODS must be busy elsewhere, being Sunday I guess, as you don't usually get to have this discussion before a topic is closed. Once you qualify for the Chat section, then you can search and find plenty of topics on Game Automation there.1 point -
FFXIV: ARR Duty Notifier Question
jaberwacky reacted to TheSaint for a topic
Anything related to elements that interact with a Game, be it Windows, Dialogs, Colors, etc is still interacting with the Game. We have had many discussions over the years about all this, and now just have a blanket rule. It's never based on your intent or how similar it may be to regular AutoIt use. Once a Game is mentioned or insinuated, that topic is locked and any related topics too.1 point -
FFXIV: ARR Duty Notifier Question
jaberwacky reacted to TheSaint for a topic
Welcome to the forum. You appear to have missed some of the rules on your way in. Please check the section on Game Automation. We do not assist with that at all here ... no exceptions whatsoever. We look forward to other queries from you here, not game related or to this post/topic. A MOD will be along shortly to lock this topic. Cheers! EDIT Just now, read your whole post. Anything to do with Game interaction, is classed as Game automation, sorry! While you might be a genuine good person, the same cannot be said for all who see any code, help, etc. So over the years here, the powers that be have found it best not to allow any exceptions at all.1 point -
can't find a hex of a keyboard key
Alexxander reacted to sahsanu for a topic
In fact BrewManNH beat all of us one hour ago , seems Alexxander thought it should use 0xDE literally _IsPressed("0xDE") instead of _IsPressed("DE") Anyway, as I said, it depends of your keyboard layout, for my spanish keyboard 0xDB is the right one _IsPressed("DB") Virtual-Key Codes Cheers, sahsanu1 point -
can't find a hex of a keyboard key
Alexxander reacted to EKY32 for a topic
Ah yes you got the answer now, <snip> لا ترد على هذا البوست ويصير سياسي Ø£Øسن ما يقلعونا ثنيناتنا من المنتدى1 point -
can't find a hex of a keyboard key
Alexxander reacted to DW1 for a topic
_IsPressed("DE") EDIT: sahsanu beat me to it1 point -
can't find a hex of a keyboard key
Alexxander reacted to sahsanu for a topic
Try one of the VK_OEM_X, it depends of your keyboard layout what is the right one. VK_OEM_1 0xBA VK_OEM_2 0xBF VK_OEM_3 0xC0 VK_OEM_4 0xDB VK_OEM_5 0xDC VK_OEM_6 0xDD VK_OEM_7 0xDE VK_OEM_8 0xDF In US standard keyboards 0xDE should be the right one... in my Spanish Keyboard it is 0xDB Cheers, sahsanu1 point -
Hi. As you may or may not know, the latest version of Lync allows you to use tabbed conversations. That can make it painful to get the conversations' "Window Title" properties. So I'm using the class: $titlesTabbed[$i] = WinGetTitle("[Class:LyncConversationWindowClass; INSTANCE:" & $i + 1 & "]" ) that's working great, I get this info from the 3 chats I have open Instance 1 -> Matt Doe Instance 2 -> Jane Doe Instance 3 -> John Doe But if I close John's tab and open a new tab for say, Jimmy Doe (this is, a new chat window tab), I get something strange... Instance 1-> Jimmy Doe Instance 2-> Jane Doe Instance 3-> Jimmy Doe Matt's tab is there, I see it BUT, it will show in the instances list (I made a simple GUI with a label that updates every 1/2 second) only if I click on it. Meanwhile, Jimmy will appear twice. I manually went for Instance 4 and Instance 0, but no. Can someone point me in the right direction please...? I can't get balder, so I think I'll go Shining-like.1 point
-
Coroutine Multithreading Udf Library
Marcelos reacted to ParoXsitiC for a topic
I fixed some of the errors I've talked about back in 2007 but never published them. Then I wanted to use this UDF again and I forgot which errors I fixed. Lucky for me, I never delete anything and found my old fixes. Long behold, I had to make a few more, but I got it working up to date. ;=============================================================================== ; ; File: Coroutine.au3 ; Description: UDF Library used for coroutine multithreading ; Version: 1.1.1 ; Date: 8/13/07 ; Author: Ben Brightwell ; Credit: ; BrianH (paroxsitic) for updating compliance to the newer StringRegExp, ConsoleRead, and StdoutRead ; ChrisH (darkthorn) for a huge amount of severe bug fixes. ; ChrisL for the base idea of deploying files as child scripts. ; Topic can be found here: ; http://www.autoitscript.com/forum/index.php?showtopic=22048 ; ;=============================================================================== ;=============================================================================== #cs Changelog: [ Patched by ParoXsitiC ] 7/12/10 (1.1.2) - Fixed bug with ConsoleRead and StdoutRead taken in the wrong parameters based on old versions 9/13/07 (1.1.1) * Wrote an alternative to the now obsolete \# option with StringRegExp - Fixed bug with [:space:] by replacing it with \s. note: \s includes Vertical Tab: chr(11) - Updated flag 2 of StringRegExp to flag 0 so that it complies with the updated StringRegExp [ Patched by ParoXsitiC ] [ Patched by Darkthorn ] 7/20/06 (1.1.0) * Wrote _LineIsFunction() to correctly identify the start/end of functions. - Replaced the previous, buggy StringInStr() matches with the above function. This means that your functions will no longer get incorrectly cut off when they contain the words "Func" or "EndFunc" inside the function definition. * Fixed a bug in _CoChangeWorkingDir(), it didn't work before as the variable wasn't being used anywhere. The following changes were made: - Changed _CoChangeWorkingDir() from $workingDir = $sDir to $sWorkingDir = $sDir. - Changed _RandomFileName() from FileGetShortName(@TempDir) to FileGetShortName($sWorkingDir) * The documentation for _CoInclude() says that it returns 1 on success, but it didn't return anything on success, this has been fixed so that it returns 1. * Added documentation for _LineIsFunction(), and added it to the "Miscellaneous Function List". * Fixed an extremely severe bug where the very important FileClose() command was omitted by the _CoInclude() function which appends functions to the output script. This in turn makes AutoIt go crazy and causes it to truncate/jumble the file contents whenever you try to access the file again. Not only that, but any subsequent attempts to reopen the file for writing (such as another call to _CoInclude()), would cause AutoIt to hang since the file would still be locked from before. This fixed two bugs: - Output files are no longer truncated/jumbled when you use _CoInclude() to append functions. - _CoInclude() no longer hangs AutoIt on subsequent calls, since the file is now free to reopen. [ Patched by Darkthorn ] 4/25/06 (1.0.3) - Fixed bug with using variables that contained the word "return" - Fixed bug with StringLower()-ing every line of code in coroutine script, now case is untouched - Fixed the way _CoInclude() works so that included code is placed at the top of the file instead of the bottom - Fixed a bug with passing a simple string to the script an extra dimension indicator was present 4/15/06 (1.0.2) - Truncated version number (Builds are irrelevant) - Added support for expressions in the return statement of a coroutine 3/23/06 (1.0.1.0) - Modified _CoCreate() to handle a function with no parameters - Added "Core Function List" and "Miscellaneous Function List" - Added this Changelog - Changed _CoAddHelper() to _CoInclude() - Fixed a bug in _CoInclude() where the last line of code was not being read into the script file #ce ;=============================================================================== ;=============================================================================== #cs Core Function List: _CoCreate() Create a coroutine script which can be instanced by _CoStart() _CoInclude() Include helper/wrapper functions to compliment the main body created by _CoCreate() _CoStart() Create an instance of a threaded function as created by _CoCreate() _CoYield() NOTE: Only to be used in coroutine scripts Pauses the coroutine and yields a value to the main script, returns any value passed by the corresponding call to _CoResume() _CoStatus() Returns the status of a coroutine _CoSend() Sends a variable into a child script _CoResume() Unpauses a coroutine, optionally sends a value back to the yielded coroutine _CoGetReturn() Retrieves a variable returned by a coroutine _CoKill() Closes a coroutine _CoCleanup() Closes all running coroutines, and deletes their respective temporary script files _CoChangeWorkingDir Changes the working directory for storing the temporary script files. NOTE: Default is @TempDir Miscellaneous Function List: NOTE: These functions are meant to be called internally by Coroutine.au3 _PackVarToStr() Packs a variable into a string for transmission between scripts. _UnpackStrToVar() Unpacks a packed variable-string into its original structure, whether it be a string or array. _LineIsFunction() Classifies the given line as either the start/end of a function, or as a regular line. _RandomFileName() Generates a random unused filename for use with _CoCreate() #ce ;=============================================================================== Local $avCoThreads[1][2] ;[n] == iCoThreadID [n][0] == sFilePath [n][1] == iNumParams $avCoThreads[0][0] = 0 ;Number of Multi-threaded Functions Local $avPIDs[1][2] ;[n][0] == iPID [n][1] == iCoThreadID $avPIDs[0][0] = 0 ;Number of iPID's created Local $sWorkingDir = @TempDir ;=============================================================================== ; ; Function Name: _CoCreate() ; Description: Create a child script for use with _CoStart() ; Parameter(s): $sFuncRawText - A delimited string containing the lines of ; the threaded function. Default delimiter is "|". Example: ; "Func MyFunc($test1)|Return $test1|EndFunc" ; $sDelimiter - A string containing the delimiter used in ; $sFuncRawText (Default = "|") ; Return Value(s): On Success - Returns the CoThreadID associated with the ; created thread. ; On Failure - 0 and @error set to: ; 1 - Invalid delimiter or delimiter not found ; 2 - File could not be created, check working ; directory access permissions ; 3 - Function parameters not formatted ; correctly. Try eliminating white space: ; Ex: Func MyFunc($test1,$test2,$test3) ; 4 - Return line not formatted correctly. ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoCreate($sFuncRawText, $sDelimiter = "|") Local $asFuncLines = StringSplit($sFuncRawText, $sDelimiter) Local $bUnpackStrToVarUsed = 1 ; Determines if source for _UnpackStrToVar() is required in child script Local $bPackVarToStrUsed = 0 ; Determines if source for _PackVarToStr() is required in child script Local $bCoYieldUsed = 0 ; Determines if source for _CoYield() is required in child script Local $hFile = "" ; For writing to the child script file Local $asParams = "" ; Array of parameters pulled from the line: "Func MyFunction($test1, $test2, $test3)" in $sFuncRawText Local $asReturnLine = "" ; Line parsed from $sFuncRawText to contain the value that is passed as "Return $value" If IsArray($asFuncLines) Then ReDim $avCoThreads[$avCoThreads[0][0] + 2][2] $avCoThreads[0][0] += 1 $avCoThreads[$avCoThreads[0][0]][0] = _RandomFileName() $hFile = FileOpen($avCoThreads[$avCoThreads[0][0]][0], 2) If $hFile == -1 Then SetError(2) ; File could not be created, check working directory access permissions Return 0 ; failure EndIf $asParams = StringRegExp($asFuncLines[1] & " ", "(\$.*?)(?:[ ,\\)])", 3) If IsArray($asParams) Then $avCoThreads[$avCoThreads[0][0]][1] = UBound($asParams) If IsArray($asParams) Then FileWriteLine($hFile, 'Local $sParamsInStr = "" ; Used to pass in parameters') FileWriteLine($hFile, 'Local $iNumChrsToRead = 0 ; Used for parameter strings longer than 64Kb') FileWriteLine($hFile, 'Local $sReturnStr = ""') FileWriteLine($hFile, 'While ConsoleRead(true) == 0') FileWriteLine($hFile, ' Sleep(10)') FileWriteLine($hFile, 'WEnd') FileWriteLine($hFile, '$sParamsInStr = ConsoleRead()') FileWriteLine($hFile, '$iNumChrsToRead= StringRegExp($sParamsInStr, "(\d*?)(?:\$\[)", 1)') FileWriteLine($hFile, '$iLen = StringInStr($sParamsInStr, $iNumChrsToRead[0]) + StringLen ( $iNumChrsToRead[0] ) - 1') FileWriteLine($hFile, '$sParamsInStr = StringTrimLeft($sParamsInStr, $iLen)') FileWriteLine($hFile, 'While StringLen($sParamsInStr) < $iNumChrsToRead[0]') FileWriteLine($hFile, ' $sParamsInStr &= ConsoleRead()') FileWriteLine($hFile, 'WEnd') For $i = 0 To UBound($asParams) - 1 FileWriteLine($hFile, $asParams[$i] & " = _UnpackStrToVar($sParamsInStr)") Next EndIf ElseIf Not StringInStr($asFuncLines[1], "$") Then FileWriteLine($hFile, ';No function parameters') Else SetError(3) ; Function parameters not formatted correctly Return 0 ; failure EndIf For $i = 1 To $asFuncLines[0] - 1 If StringInStr($asFuncLines[$i], "return ") And Not StringInStr($asFuncLines[$i], ";") And Not StringInStr($asFuncLines[$i], "=") Then $asReturnLine = StringRegExp($asFuncLines[$i], "(?i:return\s*)(.*)", 1) If IsArray($asReturnLine) Then FileWriteLine($hFile, '$sExpStr = ' &$asReturnLine[0]) FileWriteLine($hFile, '$sExpStr = _PackVarToStr($sExpStr)') FileWriteLine($hFile, 'ConsoleWrite("return" & StringLen($sExpStr) & $sExpStr)') $bPackVarToStrUsed = 1 Else SetError(4) ; Return line not formatted correctly Return 0 ; failure EndIf ElseIf Not _LineIsFunction($asFuncLines[$i]) Then FileWriteLine($hFile, $asFuncLines[$i]) If StringInStr($asFuncLines[$i], "_coyield") Then $bCoYieldUsed = 1 EndIf EndIf Next If $bCoYieldUsed == 1 Then FileWriteLine($hFile, 'Func _CoYield($bPeek, $sVarName = "")') FileWriteLine($hFile, ' If $bPeek == 1 Then') FileWriteLine($hFile, ' If ConsoleRead(true) <> 0 Then') FileWriteLine($hFile, ' $vResumeVar = ConsoleRead()') FileWriteLine($hFile, ' $vResumeVar = _UnpackStrToVar($vResumeVar)') FileWriteLine($hFile, ' SetExtended(1)') FileWriteLine($hFile, ' Return $vResumeVar') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' SetExtended(0)') FileWriteLine($hFile, ' Return ""') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' Local $vVarNameEval = "" ; If $sVarName equates to a declared variable, a copy of it is stored here') FileWriteLine($hFile, ' Local $vResumeVar = "" ; When _CoResume() is called to unpause script, a variable can be passed') FileWriteLine($hFile, ' If StringLeft($sVarName, 1) == "$" Then StringReplace($sVarName, "$", "")') FileWriteLine($hFile, ' If IsDeclared($sVarName) Then') FileWriteLine($hFile, ' $vVarNameEval = Eval($sVarName)') FileWriteLine($hFile, ' $vVarNameEval = _PackVarToStr($vVarNameEval)') FileWriteLine($hFile, ' ConsoleWrite("yield" & StrLen($vVarNameEval) & $vVarNameEval)') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' $vVarName = _PackVarToStr($vVarName)') FileWriteLine($hFile, ' ConsoleWrite("yield" & StrLen($vVarName) & $vVarName') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' While ConsoleRead(true) == 0') FileWriteLine($hFile, ' Sleep(10)') FileWriteLine($hFile, ' WEnd') FileWriteLine($hFile, ' $vResumeVar = ConsoleRead()') FileWriteLine($hFile, ' $vResumeVar = _UnpackStrToVar($vResumeVar)') FileWriteLine($hFile, ' Return $vResumeVar') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, 'EndFunc') EndIf If $bUnpackStrToVarUsed == 1 Then FileWriteLine($hFile, 'Func _UnpackStrToVar(ByRef $sVarStr)') FileWriteLine($hFile, ' Local $aiNumDims = StringRegExp($sVarStr, ''(?:\$\[)(\d*)(?:\]\$)'', 1)') FileWriteLine($hFile, ' Local $aiDimSizes[1] ; To contain the size of each dimension as passed through $sVarStr') FileWriteLine($hFile, ' Local $aiDimSize = "" ; To contain the size of current dimension and string position for stripping') FileWriteLine($hFile, ' Local $avRetArr[1] ; To be redimensioned and have $sVarStr parsed and stored into as an array') FileWriteLine($hFile, ' Local $avElementStr = "" ; To contain each element as a string as it is parsed from $sVarStr') FileWriteLine($hFile, ' If IsArray($aiNumDims) Then') FileWriteLine($hFile, ' $sVarStr = StringTrimLeft($sVarStr, StringInStr($sVarStr, $aiNumDims[0] & "]$") + StringLen ( $aiNumDims[0] & "]$" ) - 1)') FileWriteLine($hFile, ' If $aiNumDims[0] > 0 Then') FileWriteLine($hFile, ' ReDim $aiDimSizes[$aiNumDims[0]]') FileWriteLine($hFile, ' For $iCounter1 = 0 To $aiNumDims[0] - 1') FileWriteLine($hFile, ' $aiDimSize = StringRegExp($sVarStr, ''(?:\$\[)(\d*)(?:\]\$)'', 1)') FileWriteLine($hFile, ' $aiDimSizes[$iCounter1] = $aiDimSize[0]') FileWriteLine($hFile, ' $sVarStr = StringTrimLeft($sVarStr, StringInStr($sVarStr, $aiDimSize[0] & "]$") + StringLen ( $aiDimSize[0] & "]$" ) - 1)') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Select') FileWriteLine($hFile, ' Case $aiNumDims[0] == 0') FileWriteLine($hFile, ' If StringInStr($sVarStr, "$[") Then') FileWriteLine($hFile, ' $avElementStr = StringRegExp($sVarStr, ''(.*?)(?:\$\[)'', 1)') FileWriteLine($hFile, ' $sVarStr = StringTrimLeft($sVarStr, StringInStr($sVarStr, $avElementStr[0]) + StringLen ( $avElementStr[0]) - 1)') FileWriteLine($hFile, ' If $avElementStr[0] <> "<nil>" Then') FileWriteLine($hFile, ' Return $avElementStr[0]') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' Return ""') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' If $sVarStr == "<nil>" Then') FileWriteLine($hFile, ' Return ""') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' Return $sVarStr') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Case $aiNumDims[0] == 1') FileWriteLine($hFile, ' ReDim $avRetArr[$aiDimSizes[0]]') FileWriteLine($hFile, ' For $iCounter1 = 0 To $aiDimSizes[0] - 1') FileWriteLine($hFile, ' $avRetArr[$iCounter1] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive)') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Case $aiNumDims[0] == 2') FileWriteLine($hFile, ' ReDim $avRetArr[$aiDimSizes[0]][$aiDimSizes[1]]') FileWriteLine($hFile, ' For $iCounter1 = 0 To $aiDimSizes[0] - 1') FileWriteLine($hFile, ' For $iCounter2 = 0 To $aiDimSizes[1] - 1') FileWriteLine($hFile, ' $avRetArr[$iCounter1][$iCounter2] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive)') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Case $aiNumDims[0] == 3') FileWriteLine($hFile, ' ReDim $avRetArr[$aiDimSizes[0]][$aiDimSizes[1]][$aiDimSizes[2]]') FileWriteLine($hFile, ' For $iCounter1 = 0 To $aiDimSizes[0] - 1') FileWriteLine($hFile, ' For $iCounter2 = 0 To $aiDimSizes[1] - 1') FileWriteLine($hFile, ' For $iCounter3 = 0 To $aiDimSizes[2] - 1') FileWriteLine($hFile, ' $avRetArr[$iCounter1][$iCounter2][$iCounter3] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive)') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Case $aiNumDims[0] == 4') FileWriteLine($hFile, ' ReDim $avRetArr[$aiDimSizes[0]][$aiDimSizes[1]][$aiDimSizes[2]][$aiDimSizes[3]]') FileWriteLine($hFile, ' For $iCounter1 = 0 To $aiDimSizes[0] - 1') FileWriteLine($hFile, ' For $iCounter2 = 0 To $aiDimSizes[1] - 1') FileWriteLine($hFile, ' For $iCounter3 = 0 To $aiDimSizes[2] - 1') FileWriteLine($hFile, ' For $iCounter4 = 0 To $aiDimSizes[3] - 1') FileWriteLine($hFile, ' $avRetArr[$iCounter1][$iCounter2][$iCounter3][$iCounter4] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive)') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' EndSelect') FileWriteLine($hFile, ' Return $avRetArr') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, 'EndFunc ;==>_UnpackStrToVar') EndIf If $bPackVarToStrUsed == 1 Then FileWriteLine($hFile, 'Func _PackVarToStr(ByRef $vPackVar)') FileWriteLine($hFile, ' Local $iNumDims = UBound($vPackVar, 0) ; Number of dimensions of $vPackVar') FileWriteLine($hFile, ' Local $sVarStr = "$[" & $iNumDims & "]$" ; Return string of packed variable') FileWriteLine($hFile, ' Local $iCounter1 = "" ; Nested Counter') FileWriteLine($hFile, ' Local $iCounter2 = "" ; Nested Counter') FileWriteLine($hFile, ' Local $iCounter3 = "" ; Nested Counter') FileWriteLine($hFile, ' Local $iCounter4 = "" ; Nested Counter') FileWriteLine($hFile, ' For $i = 1 To $iNumDims') FileWriteLine($hFile, ' $sVarStr &= "$[" & UBound($vPackVar, $i) & "]$"') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Select') FileWriteLine($hFile, ' Case $iNumDims == 0') FileWriteLine($hFile, ' If $vPackVar == "" Then') FileWriteLine($hFile, ' $sVarStr &= "<nil>"') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' $sVarStr &= $vPackVar') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Case $iNumDims == 1') FileWriteLine($hFile, ' For $iCounter1 = 0 To UBound($vPackVar, 1) - 1') FileWriteLine($hFile, ' If $vPackVar[$iCounter1] == "" And UBound($vPackVar[$iCounter1], 0) == 0 Then') FileWriteLine($hFile, ' $sVarStr &= "$[0]$<nil>"') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' $sVarStr &= _PackVarToStr($vPackVar[$iCounter1])') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Case $iNumDims == 2') FileWriteLine($hFile, ' For $iCounter1 = 0 To UBound($vPackVar, 1) - 1') FileWriteLine($hFile, ' For $iCounter2 = 0 To UBound($vPackVar, 2) - 1') FileWriteLine($hFile, ' If $vPackVar[$iCounter1][$iCounter2] == "" And UBound($vPackVar[$iCounter1][$iCounter2], 0) == 0 Then') FileWriteLine($hFile, ' $sVarStr &= "$[0]$<nil>"') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' $sVarStr &= _PackVarToStr($vPackVar[$iCounter1][$iCounter2])') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Case $iNumDims == 3') FileWriteLine($hFile, ' For $iCounter1 = 0 To UBound($vPackVar, 1) - 1') FileWriteLine($hFile, ' For $iCounter2 = 0 To UBound($vPackVar, 2) - 1') FileWriteLine($hFile, ' For $iCounter3 = 0 To UBound($vPackVar, 3) - 1') FileWriteLine($hFile, ' If $vPackVar[$iCounter1][$iCounter2][$iCounter3] == "" And UBound($vPackVar[$iCounter1][$iCounter2][$iCounter3], 0) == 0 Then') FileWriteLine($hFile, ' $sVarStr &= "$[0]$<nil>"') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' $sVarStr &= _PackVarToStr($vPackVar[$iCounter1][$iCounter2][$iCounter3])') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Case $iNumDims == 4') FileWriteLine($hFile, ' For $iCounter1 = 0 To UBound($vPackVar, 1) - 1') FileWriteLine($hFile, ' For $iCounter2 = 0 To UBound($vPackVar, 2) - 1') FileWriteLine($hFile, ' For $iCounter3 = 0 To UBound($vPackVar, 3) - 1') FileWriteLine($hFile, ' For $iCounter4 = 0 To UBound($vPackVar, 4) - 1') FileWriteLine($hFile, ' If $vPackVar[$iCounter1][$iCounter2][$iCounter3][$iCounter4] == "" And UBound($vPackVar[$iCounter1][$iCounter2][$iCounter3][$iCounter4], 0) == 0 Then') FileWriteLine($hFile, ' $sVarStr &= "$[0]$<nil>"') FileWriteLine($hFile, ' Else') FileWriteLine($hFile, ' $sVarStr &= _PackVarToStr($vPackVar[$iCounter1][$iCounter2][$iCounter3][$iCounter4])') FileWriteLine($hFile, ' EndIf') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' Next') FileWriteLine($hFile, ' EndSelect') FileWriteLine($hFile, ' Return $sVarStr') FileWriteLine($hFile, 'EndFunc ;==>_PackVarToStr') EndIf FileClose($hFile) Return $avCoThreads[0][0] Else SetError(1) ; Invalid delimiter or delimiter not found Return 0 ; failure EndIf EndFunc ;==>_CoCreate ;=============================================================================== ; ; Function Name: _CoYield() ; Description: Yield a value to the main script and pause the ; coroutine, only usable by the coroutine ; Parameter(s): $sVarName - String containing the name of the variable ; to pass to the main script. If string does not contain ; the name of a declared variable, it is passed as a ; literal string. ; Return Value(s): The variable passed by the corresponding call to _CoResume() ; Author(s): Ben Brightwell ; ;=============================================================================== ;~ Func _CoYield($bPeek, $sVarName = "") ;~ If $bPeek == 1 Then ;~ If ConsoleRead(0,true) <> 0 Then ;~ $vResumeVar = ConsoleRead() ;~ $vResumeVar = _UnpackStrToVar($vResumeVar) ;~ SetExtended(1) ;~ Return $vResumeVar ;~ Else ;~ SetExtended(0) ;~ Return "" ;~ EndIf ;~ Else ;~ Local $vVarNameEval = "" ; If $sVarName equates to a declared variable, a copy of it is stored here ;~ Local $vResumeVar = "" ; When _CoResume() is called to unpause script, a variable can be passed ;~ If StringLeft($sVarName, 1) == "$" Then StringReplace($sVarName, "$", "") ;~ If IsDeclared($sVarName) Then ;~ $vVarNameEval = Eval($sVarName) ;~ $vVarNameEval = _PackVarToStr($vVarNameEval) ;~ ConsoleWrite("yield" & StrLen($vVarNameEval) & $vVarNameEval) ;~ Else ;~ $vVarName = _PackVarToStr($vVarName) ;~ ConsoleWrite("yield" & StrLen($vVarName) & $vVarName ;~ EndIf ;~ While ConsoleRead(0,true) == 0 ;~ Sleep(50) ;~ WEnd ;~ $vResumeVar = ConsoleRead() ;~ $vResumeVar = _UnpackStrToVar($vResumeVar) ;~ Return $vResumeVar ;~ EndIf ;~ EndFunc ;=============================================================================== ; ; Function Name: _CoInclude() ; Description: Include a UDF(s) in the coroutine script. ; NOTE: #include <something.au3> will work in _CoCreate() ; but keep in mind that the "something.au3" file must ; exist on the computer that is running the script. ; Parameter(s): $iCoThreadID - The thread to add the include to ; $sFuncRawText - The function text, delimited by $sDelimiter ; $sDelimiter - Used to delimit $sFuncRawText (Default "|") ; Return Value(s): Success - 1 ; Failure - 0 and @error set to: ; 1 - Invalid iCoThreadID ; 2 - Invalid delimiter or delimiter not found ; 3 - Code formatted incorrectly. Namely mis- ; matched number of "Func ..." and "EndFunc" ; lines. ; 4 - Script file could not be opened. ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoInclude($iCoThreadID, $sFuncRawText, $sDelimiter = "|") Local $asFuncLines = "" ; Array holding the lines of code stripped from $sFuncRawText Local $sFormattedCode = "" ; String to write to the script file Local $iNumFuncs = 0 ; Number of lines that contain "Func ...". Used for minimal codechecking Local $iNumEndFuncs = 0 ; Number of lines that contain "EndFunc". Used for minimal codechecking Local $iFileCheck = 0 ; Used to check if file was written to correctly. Local $sPrevContents = "" ; Used to store contents of original coroutine script. Local $hFile = "" ; Handle for source file If $iCoThreadID <= $avCoThreads[0][0] Then $asFuncLines = StringSplit($sFuncRawText, $sDelimiter) If IsArray($asFuncLines) Then $sFormattedCode &= ';============' & @CRLF $sFormattedCode &= ';Include Code' & @CRLF $sFormattedCode &= ';============' & @CRLF For $i = 1 To $asFuncLines[0] If _LineIsFunction($asFuncLines[$i]) Then If @Error = 1 Then $iNumFuncs += 1 Else ; error is 2 $iNumEndFuncs += 1 EndIf EndIf Next If $iNumFuncs == $iNumEndFuncs Then For $i = 1 To $asFuncLines[0] $sFormattedCode &= $asFuncLines[$i] & @CRLF Next Else SetError(3) ; Code formatted incorrectly Return 0 ; failure EndIf Else SetError(2) ; Delimiter not found in $sFuncRawText Return 0 ; failure EndIf $sPrevContents = FileRead($avCoThreads[$iCoThreadID][0]) ; read old contents $hFile = FileOpen($avCoThreads[$iCoThreadID][0], 2) ; mode 2=overwrite If FileWrite($hFile, $sFormattedCode) == 0 Then ; write header to file SetError(4) ; File could not be written to Return 0 ; failure Else FileClose($hFile) ; close file to reopen in another mode $hFile = FileOpen($avCoThreads[$iCoThreadID][0], 1) ; mode 1=append FileWrite($hFile, $sPrevContents) ; re-add old content FileClose($hFile) ; important: close the file, which you forgot EndIf Else SetError(1) ; Invalid iCoThreadID Return 0 ; failure EndIf Return 1 ; success EndFunc ;=============================================================================== ; ; Function Name: _CoStart() ; Description: Create a coroutine from a thread created by _CoCreate() ; Parameter(s): $iCoThreadID - as returned by _CoCreate() ; $sParamStr - the string you would call a normal function ; with. Example: MyFunc($test1, $test2) ; $sParamStr = "$test1, $test2" ; Return Value(s): On Success - the PID of the created coroutine ; On Failure - -1 and sets @error to: ; 1 - Invalid iCoThreadID ; 2 - Parameter string formatted incorrectly ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoStart($iCoThreadID, $sParamStr = "") Local $sPackedParamStr = "" ; If arrays exist in $sParamStr, then they need to be packed into a string Local $asParams = "" ; Holds individual parameters parsed from $sParamStr Local $sStrippedParam = "" ; Holds a parameter stripped of "$" and "," Local $vParamEval = "" ; If $sStrippedParam is a valid variable, a temporary one is evaluated to this container Local $sParamLiteral = "" ; If a non-variable is passed, it is interpreted as a literal If $iCoThreadID <= $avCoThreads[0][0] And $iCoThreadID <> 0 Then ReDim $avPIDs[$avPIDs[0][0] + 2][2] $avPIDs[0][0] += 1 If $sParamStr <> "" Then If StringRight($sParamStr, 1) <> "," Then $sParamStr &= "," ; Makes $sParamStr easier to parse with StringRegExp EndIf $asParams = StringRegExp($sParamStr, '(".*?".*?,|[^ ]*?[ ]?,)+', 3) If Not IsArray($asParams) Then SetError(2) ; Parameter string not formatted correctly Return -1 ; failure EndIf For $i = 0 To UBound($asParams) - 1 If StringInStr($asParams[$i], "$") Then $sStrippedParam = StringReplace(StringReplace($asParams[$i], "$", ""), ",", "") If IsDeclared($sStrippedParam) Then $vParamEval = Eval($sStrippedParam) $sPackedParamStr &= _PackVarToStr($vParamEval) Else $sParamLiteral = StringTrimRight($asParams[$i], 1) $sPackedParamStr &= _PackVarToStr($sParamLiteral) EndIf Else $sParamLiteral = StringTrimRight($asParams[$i], 1) $sPackedParamStr &= _PackVarToStr($sParamLiteral) EndIf Next EndIf $avPIDs[$avPIDs[0][0]][0] = Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $avCoThreads[$iCoThreadID][0] & '"', "", "", 7) If StringLen($sPackedParamStr) > 0 Then StdinWrite($avPIDs[$avPIDs[0][0]][0], StringLen($sPackedParamStr) & $sPackedParamStr) EndIf $avPIDs[$avPIDs[0][0]][1] = $iCoThreadID Return $avPIDs[$avPIDs[0][0]][0] Else SetError(1) ;Invalid iCoThreadID Return -1 ; failure EndIf EndFunc ;==>_CoStart ;=============================================================================== ; ; Function Name: _CoStatus() ; Description: Determines the status of a PID returned by _CoStart() ; Parameter(s): $iPID - PID as returned by _CoStart() ; Return Value(s): On Success - Returns the status of the coroutine ; Possible values: "yielded" - yielded a value, script paused ; "running" - running ; "returned" - coroutine dead, with a return value ; "dead" - coroutine dead with no return value ; On Failure - Returns empty string ("") and sets error to 1 ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoStatus($iPID) Local $bPIDFound = 0 ; Used to search for a PID created by _CoStart() For $i = 1 To $avPIDs[0][0] If $avPIDs[$i][0] == $iPID Then $bPIDFound = 1 EndIf Next If $bPIDFound == 1 Then Select Case ProcessExists($iPID) <> 0 If StringLeft(StdoutRead($iPID, True), 5) == "yield" Then Return "yielded" ElseIf StringLeft(StdoutRead($iPID, True), 6) == "return" Then Return "returned" ; Coroutine returned, but return string is longer than console buffer Else Return "running" EndIf Case ProcessExists($iPID) == 0 If StringLeft(StdoutRead($iPID, True), 0) <> 0 Then Return "returned" Else Return "dead" EndIf EndSelect Else SetError(1) ;$PID not created with _CoStart() Return "" EndIf EndFunc ;==>_CoStatus ;=============================================================================== ; ; Function Name: _CoSend() ; Description: Sends a variable to the child script. ; Parameter(s): $iPID - PID as returned by _CoStart() ; Return Value(s): On Success - none ; On Failure - Returns empty string ("") and sets error to 1 ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoSend($iPID, $vInVar) If _CoStatus($iPID) <> "dead" And _CoStatus($iPID) <> "returned" And _CoStatus($iPID) <> "yielded" Then StdinWrite($iPID, _PackVarToStr($vInVar)) Else SetError(1) Return "" EndIf EndFunc ;=============================================================================== ; ; Function Name: _CoResume() ; Description: Resumes a paused coroutine and returns the yielded variable ; Parameter(s): $iPID - PID as returned by _CoStart() ; Return Value(s): On Success - Resumes paused coroutine and returns variable ; yielded by _CoYield() ; On Failure - Returns empty string ("") and sets error to 1 ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoResume($iPID, $vInVar = "") Local $sReturnStr = "" ; Contains return string Local $iNumChrsToRead = 0 ; Number of chars to read Local $iTotalChrsRead = 0 ; Total chars currently read If _CoStatus($iPID) == "yielded" Then If StringLeft(StdoutRead($iPID, True), 0) > 5 Then $sReturnStr = StringTrimLeft(StdoutRead($iPID), 5) $iNumChrsToRead = StringRegExp($sReturnStr, "(\d*?)(?:\$\[)", 1) $sReturnStr = StringTrimLeft($sReturnStr, StringInStr($sReturnStr, $iNumChrsToRead[0]) + StringLen ( $iNumChrsToRead[0] ) - 1) While StringLen($sReturnStr) <= $iNumChrsToRead[0] $sReturnStr &= StdoutRead($iPID) WEnd StdinWrite($iPID, _PackVarToStr($vInVar)) Return _UnpackStrToVar($sReturnStr) EndIf Else SetError(1) ;$PID is not yielded Return "" EndIf EndFunc ;==>_CoResume ;=============================================================================== ; ; Function Name: _CoGetReturn() ; Description: Returns the variable returned by a coroutine ; Parameter(s): $iPID - PID as returned by _CoStart() ; Return Value(s): On Success - Returns variable returned by coroutine ; On Failure - Returns empty string ("") and sets error to 1 ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoGetReturn($iPID) Local $sReturnStr = "" ; Contains return string Local $iNumChrsToRead = 0 ; Number of chars to read Local $iTotalChrsRead = 0 ; Total chars currently read If _CoStatus($iPID) == "returned" Then $sReturnStr = StdoutRead($iPID) $iNumChrsToRead = StringRegExp($sReturnStr, "(\d*?)(?:\$\[)", 1) $sReturnStr = StringTrimLeft($sReturnStr, StringInStr($sReturnStr, $iNumChrsToRead[0]) + StringLen ( $iNumChrsToRead[0] ) - 1) While StringLen($sReturnStr) < $iNumChrsToRead[0] $sReturnStr &= StdoutRead($iPID) WEnd Return _UnpackStrToVar($sReturnStr) Else SetError(1) ; $PID not returned Return "" EndIf EndFunc ;==>_CoGetReturn ;=============================================================================== ; ; Function Name: _CoKill() ; Description: Kills a running coroutine ; Parameter(s): $iPID - PID as returned by _CoStart() ; Return Value(s): On Success - Returns 1 ; On Failure - Returns 0 ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoKill($iPID) If ProcessExists($iPID) <> 0 Then ProcessClose($iPID) Return 1 Else Return 0 EndIf EndFunc ;==>_CoKill ;=============================================================================== ; ; Function Name: _CoCleanup() ; Description: Kills all coroutines and deletes their respective temp files ; Parameter(s): none ; Return Value(s): none ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoCleanup() For $i = 1 To $avPIDs[0][0] _CoKill($avPIDs[$i][0]) Next For $i = 1 To $avCoThreads[0][0] FileDelete($avCoThreads[$i][0]) Next EndFunc ;==>_CoCleanup ;=============================================================================== ; ; Function Name: _CoChangeWorkingDir() ; Description: Changes the directory to store coroutine temp files in ; NOTE: does not currently check for proper directory ; structure ; Parameter(s): $sDir = String representing the new working directory ; Return Value(s): none ; Author(s): Ben Brightwell ; ;=============================================================================== Func _CoChangeWorkingDir($sDir) $sWorkingDir = $sDir EndFunc ;==>_CoChangeWorkingDir ;=============================================================================== ; ; Function Name: _UnpackStrToVar() ; Description: Turns a packed variable string back into a variable. ; Parameter(s): $sVarStr = A packed variable string as returned by _PackVarToStr() ; Return Value(s): Variable of type that was passed to _PackVarToStr() ; Author(s): Ben Brightwell ; ;=============================================================================== Func _UnpackStrToVar(ByRef $sVarStr) Local $aiNumDims = StringRegExp($sVarStr, '(?:\$\[)(\d*)(?:\]\$)', 1) Local $aiDimSizes[1] ; To contain the size of each dimension as passed through $sVarStr Local $aiDimSize = "" ; To contain the size of current dimension and string position for stripping Local $avRetArr[1] ; To be redimensioned and have $sVarStr parsed and stored into as an array Local $avElementStr = "" ; To contain each element as a string as it is parsed from $sVarStr If IsArray($aiNumDims) Then $sVarStr = StringTrimLeft($sVarStr, StringInStr($sVarStr, $aiNumDims[0] & "]$") + StringLen ( $aiNumDims[0] & "]$" ) - 1) If $aiNumDims[0] > 0 Then ReDim $aiDimSizes[$aiNumDims[0]] For $iCounter1 = 0 To $aiNumDims[0] - 1 $aiDimSize = StringRegExp($sVarStr, '(?:\$\[)(\d*)(?:\]\$)', 1) $aiDimSizes[$iCounter1] = $aiDimSize[0] $sVarStr = StringTrimLeft($sVarStr, StringInStr($sVarStr, $aiDimSize[0] & "]$") + StringLen ( $aiDimSize[0] & "]$" ) - 1) Next EndIf Select Case $aiNumDims[0] == 0 If StringInStr($sVarStr, "$[") Then $avElementStr = StringRegExp($sVarStr, '(.*?)(?:\$\[)', 1) $sVarStr = StringTrimLeft($sVarStr, StringInStr($sVarStr, $avElementStr[0]) + StringLen ( $avElementStr[0]) - 1) If $avElementStr[0] <> "<nil>" Then Return $avElementStr[0] Else Return "" EndIf Else If $sVarStr == "<nil>" Then Return "" Else Return $sVarStr EndIf EndIf Case $aiNumDims[0] == 1 ReDim $avRetArr[$aiDimSizes[0]] For $iCounter1 = 0 To $aiDimSizes[0] - 1 $avRetArr[$iCounter1] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive) Next Case $aiNumDims[0] == 2 ReDim $avRetArr[$aiDimSizes[0]][$aiDimSizes[1]] For $iCounter1 = 0 To $aiDimSizes[0] - 1 For $iCounter2 = 0 To $aiDimSizes[1] - 1 $avRetArr[$iCounter1][$iCounter2] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive) Next Next Case $aiNumDims[0] == 3 ReDim $avRetArr[$aiDimSizes[0]][$aiDimSizes[1]][$aiDimSizes[2]] For $iCounter1 = 0 To $aiDimSizes[0] - 1 For $iCounter2 = 0 To $aiDimSizes[1] - 1 For $iCounter3 = 0 To $aiDimSizes[2] - 1 $avRetArr[$iCounter1][$iCounter2][$iCounter3] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive) Next Next Next Case $aiNumDims[0] == 4 ReDim $avRetArr[$aiDimSizes[0]][$aiDimSizes[1]][$aiDimSizes[2]][$aiDimSizes[3]] For $iCounter1 = 0 To $aiDimSizes[0] - 1 For $iCounter2 = 0 To $aiDimSizes[1] - 1 For $iCounter3 = 0 To $aiDimSizes[2] - 1 For $iCounter4 = 0 To $aiDimSizes[3] - 1 $avRetArr[$iCounter1][$iCounter2][$iCounter3][$iCounter4] = _UnpackStrToVar($sVarStr) ; In case element holds another array (Recursive) Next Next Next Next EndSelect Return $avRetArr EndIf EndFunc ;==>_UnpackStrToVar ;=============================================================================== ; ; Function Name: _PackVarToStr() ; Description: Packs a variable into a string form for sending to another ; script. Maintains array integrity up to 4 dimensions. ; Also supports nested arrays inside array elements. ; Parameter(s): $vPackVar = Variable to be packed into a string. ; NOTE: Variables of type Object or DllStructs are not yet ; supported. ; Return Value(s): Returns packed string to be unpacked by _UnpackStrToVar() ; Author(s): Ben Brightwell ; ;=============================================================================== Func _PackVarToStr(ByRef $vPackVar) Local $iNumDims = UBound($vPackVar, 0) ; Number of dimensions of $vPackVar Local $sVarStr = "$[" & $iNumDims & "]$" ; Return string of packed variable Local $iCounter1 = "" ; Nested Counter Local $iCounter2 = "" ; Nested Counter Local $iCounter3 = "" ; Nested Counter Local $iCounter4 = "" ; Nested Counter For $i = 1 To $iNumDims $sVarStr &= "$[" & UBound($vPackVar, $i) & "]$" Next Select Case $iNumDims == 0 If $vPackVar == "" Then $sVarStr &= "<nil>" Else $sVarStr &= $vPackVar EndIf Case $iNumDims == 1 For $iCounter1 = 0 To UBound($vPackVar, 1) - 1 If $vPackVar[$iCounter1] == "" And UBound($vPackVar[$iCounter1], 0) == 0 Then $sVarStr &= "$[0]$<nil>" Else $sVarStr &= _PackVarToStr($vPackVar[$iCounter1]) EndIf Next Case $iNumDims == 2 For $iCounter1 = 0 To UBound($vPackVar, 1) - 1 For $iCounter2 = 0 To UBound($vPackVar, 2) - 1 If $vPackVar[$iCounter1][$iCounter2] == "" And UBound($vPackVar[$iCounter1][$iCounter2], 0) == 0 Then $sVarStr &= "$[0]$<nil>" Else $sVarStr &= _PackVarToStr($vPackVar[$iCounter1][$iCounter2]) EndIf Next Next Case $iNumDims == 3 For $iCounter1 = 0 To UBound($vPackVar, 1) - 1 For $iCounter2 = 0 To UBound($vPackVar, 2) - 1 For $iCounter3 = 0 To UBound($vPackVar, 3) - 1 If $vPackVar[$iCounter1][$iCounter2][$iCounter3] == "" And UBound($vPackVar[$iCounter1][$iCounter2][$iCounter3], 0) == 0 Then $sVarStr &= "$[0]$<nil>" Else $sVarStr &= _PackVarToStr($vPackVar[$iCounter1][$iCounter2][$iCounter3]) EndIf Next Next Next Case $iNumDims == 4 For $iCounter1 = 0 To UBound($vPackVar, 1) - 1 For $iCounter2 = 0 To UBound($vPackVar, 2) - 1 For $iCounter3 = 0 To UBound($vPackVar, 3) - 1 For $iCounter4 = 0 To UBound($vPackVar, 4) - 1 If $vPackVar[$iCounter1][$iCounter2][$iCounter3][$iCounter4] == "" And UBound($vPackVar[$iCounter1][$iCounter2][$iCounter3][$iCounter4], 0) == 0 Then $sVarStr &= "$[0]$<nil>" Else $sVarStr &= _PackVarToStr($vPackVar[$iCounter1][$iCounter2][$iCounter3][$iCounter4]) EndIf Next Next Next Next EndSelect Return $sVarStr EndFunc ;==>_PackVarToStr ;=============================================================================== ; ; Function Name: _LineIsFunction() ; Description: Classifies the given line as either the start/end of a function, or as a regular line. ; Uses regular expressions to match every possible scenario. ; Parameter(s): $vLine = The string to be classified. ; Return Value(s): On Success - 1, this line is the start/end of a function. Sets @Error to: ; 1 - Line is the start of a function ; 2 - Line is the end of a function ; On Failure - 0, this line isn't a function. ; Author(s): Chris H. (darkthorn) ; ;=============================================================================== Func _LineIsFunction($vLine) ; Classify the type of line. First check if this line is an EndFunc. If StringRegExp($vLine, "^\s*(?i:EndFunc)", 0) Then ; Success. Pattern Matched. This is the end of a function. SetError(2) ; line is endfunc Return 1 ; success Else ; Failure. Pattern not matched. This is not the end of a function. So let's check if it's the start of a function. If StringRegExp($vLine, "^\s*(?i:Func)\s+\S+\s*\(.*\)", 0) Then ; Success. Pattern Matched. This is the start of a function. SetError(1) ; line is func Return 1 ; success Else ; Failure. Pattern not matched. Since this wasn't the start of a function either, treat it as a normal line. SetError(0) ; line isn't function Return 0 ; failure EndIf EndIf EndFunc ;==>_LineIsFunction ;=============================================================================== ; ; Function Name: _RandomFileName() ; Description: Generates a random file name in the working directory so that ; the a filename is not repeated for up to 10000 coroutine ; scripts per main script. ; Parameter(s): none ; Return Value(s): FileGetShortName-converted string representing the full path ; to the temporary file, including the .au3 extension ; Author(s): Ben Brightwell ; ;=============================================================================== Func _RandomFileName() $name = FileGetShortName($sWorkingDir) & "\" & StringTrimRight(@ScriptName, 4) & Random(0, 10000, 1) & ".au3" $found = 0 For $i = 1 To $avCoThreads[0][0] If $name == $avCoThreads[$i][0] Then $found = 1 EndIf Next While $found == 1 $found = 0 $name = FileGetShortName($sWorkingDir) & "\" & StringTrimRight(@ScriptName, 4) & Random(0, 10000, 1) & ".au3" For $i = 1 To $avCoThreads[0][0] If $name == $avCoThreads[$i][0] Then $found = 1 EndIf Next WEnd Return $name EndFunc ;==>_RandomFileName1 point