D3STROY3R Posted November 26, 2011 Posted November 26, 2011 Hi, I want to create a last in first out event callback system or a first in first out currently my problem is when i receive an event it executes a function, during that functions NO OTHER EVENT is accepted instead of missing other potential events, I would rather those events be logged so that after the current event is done the next one can be executed I am using a GUI with OnEventMode Side question: does GuiGetMsg (the polling mode) stack events? like if i am in the loop executing some function due to a GuiGetmsg... what happens if another event is fired?
water Posted November 26, 2011 Posted November 26, 2011 (edited) My understanding is that events aren't stacked by AutoIt, they are stacked by Windows. GUIGetMsg simply an event from the event queue. Edited November 26, 2011 by water My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
D3STROY3R Posted November 26, 2011 Author Posted November 26, 2011 My understanding is that events aren't stacked by AutoIt, they are stacked by Windows. GUIGetMsg simply an event from the event queue.Okay, if I understand this correctly, then there is a distinct difference between GUIOnEventMode and GUIGetMsg pollingExample: 2 events are requested to your GUI within the same 250 ms frameIn GUIOnEventMode: The first event is captured, appropriate function is called, however, since the main script is paused, the 2nd event is ignored.In GUIGetMsg: The first event is retrieved from the event queue, then it is processed, then the 2nd event is retrieved from the event queue... so onDistinction: GUIOnEventMode can miss events, GUIGetMsg mode will process all events in the order they exist in the event queue.Please let me know if my assumption is correct.
water Posted November 26, 2011 Posted November 26, 2011 A good description how this two modes work can be found here and here. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki
Moderators Melba23 Posted November 26, 2011 Moderators Posted November 26, 2011 D3STROY3R,I take it you are looking to detect events from your own AutoIt GUI. If that is so then take a look at the Interrupting a running function tutorial in the Wiki. You will see a number of ways to detect controls on your GUI being actioned even though the script is in a long function - in both OnEvent and MessageLoop modes. In your case you could add the detected event to a list for later actioning rather than interrupting the current function - but the basic principle is the same. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
D3STROY3R Posted November 26, 2011 Author Posted November 26, 2011 (edited) Thanks for your responses, I have read that wiki and the other links posted several times but I can't seem to address my problem. Basically I have an Autoit GUI and a separate application lets call it "AppA" AppA uses sendCopyData to send a message to the Autoit GUI example: update a spot on a listview item In response, the Autoit GUI (which currently uses GUIRegisterMsg($WM_COPYDATA, "funcitonname")) pauses the main script and then runs the function then unpauses the main script However, while its running "functionname" it blocks all other $WM_COPYDATA requests so my problem is I am having "dropped" events because i have more than 1 "AppA" instances that are concurrently sending copydata requests to the GUI to update a listview item but since they are being dropped the listview is not being updated as it should My attempt at a solution: create a buffer to hold copydata requests and handle them in the main loop instead of using GUIRegisterMsg My question is how can I create an event queue for Windows message just like how GUIGetMsg() works because in the wiki, you can press button 1 many times and then 2 and it will actually execute all the buttons in the order pressed (not necessarily at the time pressed) but for me my copydata only processes the current copydata and will drop the other ones that came in during the busy time i tried something like this: $hGUI = GUICreate("Test", 500, 500) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit case $WM_COPYDATA msgbox("","CopydataRecieved","") EndSwitch WEnd But, it seems like GUIGetMsg() does not hold Windows Message events, those have to be done using GUIRegisterMsg which does not hold all requests in a queue like GUIGetMsg() Edited November 26, 2011 by D3STROY3R
Moderators Melba23 Posted November 26, 2011 Moderators Posted November 26, 2011 D3STROY3R,Take a look at trancexx's MailSlot UDF. If you were to use that rather than $WM_COPYDATA you can easily read the stacked requests. I realise you might well be limited in how "AppA" communicates with your AutoIt GUI but this could be a possible solution. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
D3STROY3R Posted November 26, 2011 Author Posted November 26, 2011 (edited) D3STROY3R, Take a look at trancexx's MailSlot UDF. If you were to use that rather than $WM_COPYDATA you can easily read the stacked requests. I realise you might well be limited in how "AppA" communicates with your AutoIt GUI but this could be a possible solution. M23 Yes, I looked at the _MailSlot UDF as well and it would work as I would want it to however just as you said, "AppA" does not have the ability to to utilize the mailslot system. The only methods to communicate for "AppA" are dde server or windows message copydata Thanks for your help. Edited November 26, 2011 by D3STROY3R
Moderators Melba23 Posted November 26, 2011 Moderators Posted November 26, 2011 D3STROY3R,"AppA" does not have the ability to to utilize the mailslot systemI feared as much - life can be very annoying at times! Last suggestion - how about an intermediate AutoIt script to intercept the $WM_COPYDATA messages from AppA which then uses the MailSlot UDF to communicate with the original AutoIt script? I realise we are adding another layer here, but at the end of a long and rather busy day I can think of nothing else. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
D3STROY3R Posted November 26, 2011 Author Posted November 26, 2011 (edited) D3STROY3R,I feared as much - life can be very annoying at times! Last suggestion - how about an intermediate AutoIt script to intercept the $WM_COPYDATA messages from AppA which then uses the MailSlot UDF to communicate with the original AutoIt script? I realise we are adding another layer here, but at the end of a long and rather busy day I can think of nothing else. M23I think this /might/ have the potential to work however, I have been searching for what the internal delay of GUIRegisterMsg call isbecause as far as I can tell, my functions are minimal and are NON-Blocking (they should take less than 1 ms to complete and return...)However, I think GUIRegisterMsg has a internal delay that only allows it to register a certain number of requests per secondI can't seem to find documentation on what this delay is or if there is a way to adjust it.Summary: if the internal delay of GUIRegisterMsg is smaller then the rate at which requests are being received an intermediary script will workD3STROY3R,Stick around, I will ask a Dev to pop in and take a look. M23Edit: Done - stand by for incoming! Appreciate the Help , ty. Edited November 26, 2011 by D3STROY3R
Moderators Melba23 Posted November 26, 2011 Moderators Posted November 26, 2011 (edited) D3STROY3R, Stick around, I will ask a Dev to pop in and take a look. M23 Edit: Done - stand by for incoming! Edited November 26, 2011 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
D3STROY3R Posted November 27, 2011 Author Posted November 27, 2011 Alright, so I have dealt with my problem Application side Here is the real problem: Any function that is more than changing a few variables (like loops) /may/ cause blocking when multiple clients are sending messages to an autoit script. Solution: Keep sending the message from your client until autoit returns a 1. When autoit "drops" the message, it automatically returns a 0. So instead of creating a buffer to hold all requests, I just keep requesting until I receive a correct response from autoit, Thanks for your help, but I will no longer be implementing a buffer style holder for this purpose.
Valik Posted November 27, 2011 Posted November 27, 2011 AutoIt shouldn't be dropping messages at all. AutoIt polls the message queue like any other application and if there is a message it puts it into another queue which the script handles (or not depending on what events are registered). If you are seeing dropped messages that normally come through then you either found a bug in AutoIt, I'm missing something obvious or you have some really odd code. Keep in mind that long-running code should never be placed in a callback function or it will block. It could be that your code takes a bit to process and the blocking fills up some internal buffer and subsequent messages are discarded. This would likely be an issue with your script, though, and not AutoIt unless you demonstrate it happens in non-blocking situations.
D3STROY3R Posted November 27, 2011 Author Posted November 27, 2011 (edited) AutoIt shouldn't be dropping messages at all. AutoIt polls the message queue like any other application and if there is a message it puts it into another queue which the script handles (or not depending on what events are registered). If you are seeing dropped messages that normally come through then you either found a bug in AutoIt, I'm missing something obvious or you have some really odd code. Keep in mind that long-running code should never be placed in a callback function or it will block. It could be that your code takes a bit to process and the blocking fills up some internal buffer and subsequent messages are discarded. This would likely be an issue with your script, though, and not AutoIt unless you demonstrate it happens in non-blocking situations. then I think there may be an error with the autoit core with how the internal buffer operates my update function calls approximately 4 lines of code 3 lines of codes are compare statements (comparing 2 array locations) 1 line of code that updates a listview item using setitem total execution should be very minimal This is how I performed my testing: Launch 2x application clients that repeatedly use windows SendMessage function (which does not timeout) they concurrently send n number of sendmessage to autoit gui in very short amount of time (like ~200 within 1 second) If my autoit handler function has no operations, all messages are registered and handled properly If I add a 100 ms delay in my autoit handler function, my application prints out "0" for the return from sendcopydata function that I am using (meaning they are not being handled) I believe this is caused by the fact that autoit pauses the main script while the handler function is performing, while the handler function is performing the event queue is blocked and new event requests are not taken in. In GUIGetMsg mode (which works for all alerts OTHER THAN WINDOWS MESSAGE) this problem does not exist, because GUIGetMsg mode uses polling thus main script is never paused, GUIGetMsg is basically a wrapper for the windows function GetMessage which properly handles an event queue which GUIGetMsg retrieves from. However, GUIRegisterMessage does not work the same way, when using a registered message autoit actively checks for an interrupt flag and when it is set the proper function is called but the main script is paused allowing it not to check for subsequent interrupt flags... Also I think there maybe a problem when multiple handles send autoit msgs, usually when I run with 1 client my error rate is significantly lower It might be that multiple handles sending autoit msgs is not handled in the internal queue properly, regardless, I think there is an error with the RegisterMessage handling protocol This is my application side code that I used to test (note 2 clients ran this simultaneously): function main() { var send; addEventListener("keydown", function (key) { if (key === 45) { // insert send = true; } } ); while (1) { if (send) { doSomething( ); send = false; } delay(100); } } function doSomething() { for( var i = 0; i < 25; i++ ) { var data = sendCopyData(null, title, 0, message); if(data) return true; else return print(data); } } Edited November 27, 2011 by D3STROY3R
Shaggi Posted November 27, 2011 Posted November 27, 2011 Another way would be to intercept the autoit window proc, and install yours before, that checks for $wm_copydate. you can just call autoits after, and since your client code uses sendmessage, you are avoiding the getmessage queue. Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG
KaFu Posted November 27, 2011 Posted November 27, 2011 (edited) I'm currently implementing a command-line interface for AMT. My approach is that when an instance of AMT is already running that the new process sends the $CmdLineRaw via WM_COPYDATA to the first instance and exits. The first instance adds the data received to a scripting.dictionary object. When AMT becomes idle again I check the object for data (FIFO) to process. Edited November 27, 2011 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
guinness Posted November 27, 2011 Posted November 27, 2011 That's what I've done with my applications too ... UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018
D3STROY3R Posted November 27, 2011 Author Posted November 27, 2011 So from what I understand... basically take any received messages and reroute them to a "dummy" (which is hopefully not blocking) so that it is registered as a guigetmsg and then handle it using the guigetmsg queue?
KaFu Posted November 27, 2011 Posted November 27, 2011 (edited) Give this one a try... expandcollapse popup#NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=test.exe #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $hwnd_AutoIt = _EnforceSingleInstance('e15ff08b-84ac-472a-89bf-5f92db683165') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx Opt("TrayIconHide", 1) Global $oDict_ProcessingBuffer = ObjCreate('Scripting.Dictionary'), $iDict_ProcessingBuffer = 0 If Not IsObj($oDict_ProcessingBuffer) Then If MsgBox(4 + 16 + 262144, "Startup Error!", "Creating a ""Scripting.Dictionary"" object failed." & @CRLF & @CRLF & "If you are running XP without SP3, it might be necessary to install the Microsoft ""Windows Script"" for Windows XP redistributable." & @CRLF & @CRLF & "Do you want to search Google for the download?") = 6 Then ShellExecute("http://www.google.com/search?q=%22Windows+Script%22+download+microsoft") EndIf Exit EndIf Run(@ComSpec,@ScriptDir) $hGUI = GUICreate("My GUI " & $hwnd_AutoIt, 300, 300, Default, Default,Default,$WS_EX_TOPMOST) ; will create a dialog box that when displayed is centered $label = GUICtrlCreateLabel($CmdLineRaw, 10, 10, 300, 100) GUISetState(@SW_SHOW) ; will display an empty dialog box ControlSetText($hwnd_AutoIt, '', ControlGetHandle($hwnd_AutoIt, '', 'Edit1'), $hGUI) ; to pass hWnd of main GUI to AutoIt default GUI GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA") _CMDLine_Add2Buffer($CmdLineRaw) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch if $iDict_ProcessingBuffer Then GUICtrlSetData($label,TimerInit() & @TAB & _CMDLine_Process()) WEnd _CMDLine_Flush_Queue() GUIDelete() Exit Func _EnforceSingleInstance($GUID_Program = "") If $GUID_Program = "" Then Return $hwnd = WinGetHandle($GUID_Program) If IsHWnd($hwnd) Then $hwnd_Target = ControlGetText($hwnd, '', ControlGetHandle($hwnd, '', 'Edit1')) WM_COPYDATA_SendData(HWnd($hwnd_Target), $CmdLineRaw) Exit EndIf AutoItWinSetTitle($GUID_Program) Return WinGetHandle($GUID_Program) EndFunc ;==>_EnforceSingleInstance Func WM_COPYDATA($hwnd, $MsgID, $wParam, $lParam) ; http://www.autoitscript.com/forum/index....?showtopic=105861&view=findpos ; Melba23, based on code from Yashied Local $tCOPYDATA = DllStructCreate("ulong_ptr;dword;ptr", $lParam) Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3)) Local $s_Buffer = DllStructGetData($tMsg, 1) $s_Buffer = _UTF8toUCS2($s_Buffer) _CMDLine_Add2Buffer($s_Buffer) Return 0 EndFunc ;==>WM_COPYDATA Func WM_COPYDATA_SendData($hwnd, $sData) If Not IsHWnd($hwnd) Then Return 0 If $sData = "" Then $sData = " " $sData = _UCS2toUTF8($sData) Local $tCOPYDATA, $tMsg $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]") DllStructSetData($tMsg, 1, $sData) $tCOPYDATA = DllStructCreate("ulong_ptr;dword;ptr") DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1) DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg)) $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hwnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA)) If (@error) Or ($Ret[0] = -1) Then Return 0 Return 1 EndFunc ;==>WM_COPYDATA_SendData Func _UCS2toUTF8($sString = "", $iFlag = 1) ; Convert UTF8 to ANSI to insert into DB ; http://www.autoitscript.com/forum/index.php?showtopic=85496&view=findpost&p=614497 ; ProgAndy ; Make ANSI-string representation out of UTF-8 ; $iFlag Local Const $SF_ANSI = 1 Local Const $SF_UTF16_LE = 2 Local Const $SF_UTF16_BE = 3 Local Const $SF_UTF8 = 4 Return BinaryToString(StringToBinary($sString, $SF_UTF8), $iFlag) EndFunc ;==>_UCS2toUTF8 Func _UTF8toUCS2($sString = "", $iFlag = 4) ; Extract ANSI and convert to UTF8 to display ; http://www.autoitscript.com/forum/index.php?showtopic=85496&view=findpost&p=614497 ; ProgAndy ; convert ANSI-UTF8 representation to ANSI/Unicode Local Const $SF_ANSI = 1 Local Const $SF_UTF16_LE = 2 Local Const $SF_UTF16_BE = 3 Local Const $SF_UTF8 = 4 Return BinaryToString(StringToBinary($sString, $SF_ANSI), $iFlag) EndFunc ;==>_UTF8toUCS2 Func _CMDLine_Add2Buffer($sString) if not StringLen($sString) then Return $oDict_ProcessingBuffer.Add(TimerInit(),$sString) $iDict_ProcessingBuffer += 1 EndFunc ;==>_CMDLine_Add2Buffer Func _CMDLine_Flush_Queue() $oDict_ProcessingBuffer.RemoveAll() $iDict_ProcessingBuffer = 0 EndFunc Func _CMDLine_Process() If Not $iDict_ProcessingBuffer Then Return Local $sReturn For $s_ProcessingBuffer_Key In $oDict_ProcessingBuffer.Keys() $sReturn = $oDict_ProcessingBuffer.Item($s_ProcessingBuffer_Key) $oDict_ProcessingBuffer.Remove($s_ProcessingBuffer_Key) $iDict_ProcessingBuffer -= 1 ExitLoop Next Return $s_ProcessingBuffer_Key & "|" & $sReturn EndFunc Edited November 27, 2011 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16)
D3STROY3R Posted November 27, 2011 Author Posted November 27, 2011 Give this one a try... expandcollapse popup#NoTrayIcon #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=test.exe #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> $hwnd_AutoIt = _EnforceSingleInstance('e15ff08b-84ac-472a-89bf-5f92db683165') ; any 'unique' string; created with http://www.guidgen.com/Index.aspx Opt("TrayIconHide", 1) Global $oDict_ProcessingBuffer = ObjCreate('Scripting.Dictionary'), $iDict_ProcessingBuffer = 0 If Not IsObj($oDict_ProcessingBuffer) Then If MsgBox(4 + 16 + 262144, "Startup Error!", "Creating a ""Scripting.Dictionary"" object failed." & @CRLF & @CRLF & "If you are running XP without SP3, it might be necessary to install the Microsoft ""Windows Script"" for Windows XP redistributable." & @CRLF & @CRLF & "Do you want to search Google for the download?") = 6 Then ShellExecute("http://www.google.com/search?q=%22Windows+Script%22+download+microsoft") EndIf Exit EndIf Run(@ComSpec,@ScriptDir) $hGUI = GUICreate("My GUI " & $hwnd_AutoIt, 300, 300, Default, Default,Default,$WS_EX_TOPMOST) ; will create a dialog box that when displayed is centered $label = GUICtrlCreateLabel($CmdLineRaw, 10, 10, 300, 100) GUISetState(@SW_SHOW) ; will display an empty dialog box ControlSetText($hwnd_AutoIt, '', ControlGetHandle($hwnd_AutoIt, '', 'Edit1'), $hGUI) ; to pass hWnd of main GUI to AutoIt default GUI GUIRegisterMsg($WM_COPYDATA, "WM_COPYDATA") _CMDLine_Add2Buffer($CmdLineRaw) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch if $iDict_ProcessingBuffer Then GUICtrlSetData($label,TimerInit() & @TAB & _CMDLine_Process()) WEnd _CMDLine_Flush_Queue() GUIDelete() Exit Func _EnforceSingleInstance($GUID_Program = "") If $GUID_Program = "" Then Return $hwnd = WinGetHandle($GUID_Program) If IsHWnd($hwnd) Then $hwnd_Target = ControlGetText($hwnd, '', ControlGetHandle($hwnd, '', 'Edit1')) WM_COPYDATA_SendData(HWnd($hwnd_Target), $CmdLineRaw) Exit EndIf AutoItWinSetTitle($GUID_Program) Return WinGetHandle($GUID_Program) EndFunc ;==>_EnforceSingleInstance Func WM_COPYDATA($hwnd, $MsgID, $wParam, $lParam) ; http://www.autoitscript.com/forum/index....?showtopic=105861&view=findpos ; Melba23, based on code from Yashied Local $tCOPYDATA = DllStructCreate("ulong_ptr;dword;ptr", $lParam) Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3)) Local $s_Buffer = DllStructGetData($tMsg, 1) $s_Buffer = _UTF8toUCS2($s_Buffer) _CMDLine_Add2Buffer($s_Buffer) Return 0 EndFunc ;==>WM_COPYDATA Func WM_COPYDATA_SendData($hwnd, $sData) If Not IsHWnd($hwnd) Then Return 0 If $sData = "" Then $sData = " " $sData = _UCS2toUTF8($sData) Local $tCOPYDATA, $tMsg $tMsg = DllStructCreate("char[" & StringLen($sData) + 1 & "]") DllStructSetData($tMsg, 1, $sData) $tCOPYDATA = DllStructCreate("ulong_ptr;dword;ptr") DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1) DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg)) $Ret = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hwnd, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA)) If (@error) Or ($Ret[0] = -1) Then Return 0 Return 1 EndFunc ;==>WM_COPYDATA_SendData Func _UCS2toUTF8($sString = "", $iFlag = 1) ; Convert UTF8 to ANSI to insert into DB ; http://www.autoitscript.com/forum/index.php?showtopic=85496&view=findpost&p=614497 ; ProgAndy ; Make ANSI-string representation out of UTF-8 ; $iFlag Local Const $SF_ANSI = 1 Local Const $SF_UTF16_LE = 2 Local Const $SF_UTF16_BE = 3 Local Const $SF_UTF8 = 4 Return BinaryToString(StringToBinary($sString, $SF_UTF8), $iFlag) EndFunc ;==>_UCS2toUTF8 Func _UTF8toUCS2($sString = "", $iFlag = 4) ; Extract ANSI and convert to UTF8 to display ; http://www.autoitscript.com/forum/index.php?showtopic=85496&view=findpost&p=614497 ; ProgAndy ; convert ANSI-UTF8 representation to ANSI/Unicode Local Const $SF_ANSI = 1 Local Const $SF_UTF16_LE = 2 Local Const $SF_UTF16_BE = 3 Local Const $SF_UTF8 = 4 Return BinaryToString(StringToBinary($sString, $SF_ANSI), $iFlag) EndFunc ;==>_UTF8toUCS2 Func _CMDLine_Add2Buffer($sString) if not StringLen($sString) then Return $oDict_ProcessingBuffer.Add(TimerInit(),$sString) $iDict_ProcessingBuffer += 1 EndFunc ;==>_CMDLine_Add2Buffer Func _CMDLine_Flush_Queue() $oDict_ProcessingBuffer.RemoveAll() $iDict_ProcessingBuffer = 0 EndFunc Func _CMDLine_Process() If Not $iDict_ProcessingBuffer Then Return Local $sReturn For $s_ProcessingBuffer_Key In $oDict_ProcessingBuffer.Keys() $sReturn = $oDict_ProcessingBuffer.Item($s_ProcessingBuffer_Key) $oDict_ProcessingBuffer.Remove($s_ProcessingBuffer_Key) $iDict_ProcessingBuffer -= 1 ExitLoop Next Return $s_ProcessingBuffer_Key & "|" & $sReturn EndFunc thanks for your post, just by looking at it, yes that would work (given that your _CMDLine_Add2Buffer() actually gets to execute) as long as _CMDLine_Add2Buffer() is non blocking it would work and for me with 2 clients it will probably also work but for n client's I don't know if it will work I think there is still a design problem with how autoit is retrieving from windows message queue... your method is basically the same thing i was suggesting in terms of creating a dummy window... and triggering it as a GUIGetMsg and let GUIGetMsg handle the push/pop method you implemented with the Buffer += 1 and when retrieved Buffer -= 1
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