Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/15/2025 in Posts

  1. Check it out! https://github.com/matthewrg/Guiscape
    1 point
  2. First, I pared down the script to the essentials: For $i = 1 To 20 ; create new(!) map, add one element to the string index "c" (which calculated position in the internal list is index 8) Global $m1[] $m1["c"] = 1 ; check if there`s a value at the index 8 (shouldn`t) If $m1[8] Then ConsoleWrite($m1[8] & @CRLF) ; create another map and add value at the same integer index as the one $m1 checked Global $m2[] $m2[8] = 1 Next I made the following observations: 1. It does not occur with all string indexes, but only with some. It is noticeable that each string index has a fixed associated integer index. If you use a different integer index, the phenomenon does not occur. So far, I have found the following combinations in which the phenomenon occurs: | String-Index | Integer-Index | | ------------ | ------------- | | "[" | 0 | | "<" | 1 | | "" | 5 | | "c" | 8 | | "D" | 9 | | "%" | 10 | | "k" | 16 | | "L" | 17 | | "-" | 18 | | "s" | 24 | | "T" | 25 | | "{" | 32 | | "\" | 33 | | "=" | 34 | These relationships can be explained well using hash index collisions. AutoIt uses the DJB2 hash function in its maps. If you use this for the letters and then scale it to the table size using modulo, you get exactly the corresponding integer indices. Only the table size is obviously not fixed, as the index sometimes fits for 32 elements and sometimes for 64. For example: “c” has a DJB2 hash value of 177672. If we assume that the map in AutoIt has 32 elements at that point, the index for “c” is calculated as 177672 % 32 = 8. This also works for the other string indexes. E.g., “D” --> 177641 % 32 = 9 or “” --> 5381 % 32 = 5. Only the size of the hash table is obviously variable, as some fit for a size of 32 elements and some for 64. However, thanks to the bug, we can learn a lot about the internal structure of AutoIt maps. They are DJB2-based hash tables that start with 32 or 64 elements. 2. This behavior only occurs when the map $m2 is created and an element is created with the same integer index as in $m1. If only this index is set, a match is reported very often. If other indexes are also set, the match does not occur as frequently. One possible explanation for this behavior is as follows: A hash table is essentially an array with a specific size. This size is fundamentally independent of the number of elements it contains (resizing makes sense but is not mandatory). In this case, a map is obviously initially populated with either 32 or 64 elements. When a value is added to the hash table, the hash value of the key is calculated and this calculated value is mapped to the array size using modulo. If the key is “c”, for example, the DJB2 hash (the hash algorithm used in AutoIt) is 177672. To obtain an index for our array in the map, we have to reduce this hash value to the range 32 or 64. This is easy to do using the modulo operator. And with 177672 % 32, we get 8 as the result. The value for the key “c” is therefore stored in the internal array at index 8. However, since several keys could end up at index 8, we need to create a way to hold multiple elements there. For each index, a list is created (a “bucket”) that contains all elements whose key matches this index. The key and value of these elements are then simply stored one after the other in the bucket itself. When a value is queried, the index is first calculated and then this bucket is traversed linearly to see if the specific key is contained in it. In AutoIt, these buckets do not necessarily seem to be used only by one map instance. At some point, two maps share a bucket, resulting in a phenomenon like the one we see here. So you would have to take a closer look at the initialization of the map to see exactly where the problem lies.
    1 point
  3. Look at my Fast and simple WCD IPC. It is working well between processes with different levels of privilege.
    1 point
  4. I'm taking the hi word, that's not the same as $hwnd? Let me test it ... :forehead smack: Durrrrr .... thank you!
    1 point
  5. looks like a malformed window handle to me... around about line 70: GUICtrlSendToDummy($dummy, _WinAPI_MakeLong($NC_CLICKED, $hwnd)) so you're sending part of a window handle (the hi word part), and a in the lo work you have $NC_CLICKED.
    1 point
  6. ...If, there are very many distributed workloads and the "master" overwhelmed itself, then you see what you just witnessed. All this is painfully stupid. More bandwidth than brains. Idea: we should offer torrents ( in a throttle ). With a bit of luck they can feed each other the files 🤪
    1 point
  7. @Musashi hello I think OP wants to replace each "%" (preceded with digits & eventual dot) with "\%" while keeping a log of each replacement using _FileWriteToLine . But maybe not all "%" must be processed, as we'll see in the script below. @Delai I tried another approach, because the way you scripted it (by splitting the sentence) makes it hard to find the position you need in the original sentence, when comes the replacement part. Local $sLineIn, $sLineOut, $sPattern, $nMode, $iOffset, $aArray $sLineIn = "This % sign for test (not preceded with digits) . " & _ "En un estudio sobre la presencia de mujeres en las empresas tecnológicas se observa que el 20 % de los operarios, " & _ "el 40 % de los ingenieros y el 30 % de los directivos son mujeres. Se sabe que en estas empresas el 20 % de las plantillas " & _ "son directivos, el 35 % son ingenieros y el resto son operarios. Se elige un trabajador al azar de una de estas empresas." $sPattern = '(?U).*\d*\.?\d+ *(%).*' $nMode = 2 ; $STR_REGEXPARRAYFULLMATCH $iOffset = 1 While 1 $aArray = StringRegExp($sLineIn, $sPattern, $nMode, $iOffset) If @error Then $sLineOut &= StringMid($sLineIn, $iOffset) ExitLoop EndIf $iOffset = @extended $sLineOut &= StringTrimRight($aArray[0], 1) & "\%" ; your _FileWriteToLine here WEnd MsgBox(0, "$sLineOut", $sLineOut) Hope it helps
    1 point
  8. The wrapper I put together ( @trancexx's code ) works just fine in 32 and 64 bit. I have not seen it fail.
    1 point
  9. Nine

    Delayed MouseClick()

    If you're running this script in a loop, then you are not leaving enough time to the last click to complete.
    1 point
  10. After seeing a number of threads talking about how to exchange efficiently messages between processes (Inter Process Communication), I decided to create a framework using Windows Messages WM_COPYDATA. What is new with this UDF you ask ? Well it will depends how familiar you are with IPC. One thing is sure, the simplicity of use and the fabulous speed are amazing. This is based on a Clients-Server approach. You can have an unlimited number of clients talking with a single server. You will have to define the protocol of communication between them, but the code you have to create is incredibly low. The UDF proposes 2 simple message properties of communication. The first (called data) is based on a number. You can decide what value 1,2,3, etc. means between your client and server. Server will react upon the value of the data field. Second, there is a string field where you can inscribe additional information on request, and where the server will respond to client request (if necessary). Here are the functions that I have wrapped around this : Func _WCD_CreateServer Func _WCD_CreateClient Func _WCD_GetServerHandle Func _WCD_IsServerAvailable Func _WCD_Send Func _WCD_WM_COPYDATA_CLIENT_HANDLER Func _WCD_Client_GetResponse Func _WCD_WM_COPYDATA_SERVER_HANDLER Func _WCD_Server_PeekRequest Func _WCD_Server_GetRequest Func _WCD_Server_IsRequestAvail Here an example of the server : #include <Constants.au3> #include <GUIConstants.au3> #include "WCD_IPC.au3" Opt ("MustDeclareVars", 1) $_WCD_Verbose = False ; make it True if you want to follow the convos. False is by default. Local $hServer = _WCD_CreateServer () Local $aReq, $iData While True If _WCD_Server_IsRequestAvail () Then $aReq = _WCD_Server_GetRequest () $iData = @extended Switch $iData Case 1 ; who are you _WCD_Send($hServer, $aReq[0], $iData, @ComputerName) Case 2 Switch Number($aReq[1]) Case 1 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress1) Case 2 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress2) Case 3 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress3) Case 4 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress4) Case Else _WCD_Send($hServer, $aReq[0], $iData, "Invalid parameter") EndSwitch EndSwitch EndIf Sleep (100) WEnd And the client : #include <Constants.au3> #include <GUIConstants.au3> #include "WCD_IPC.au3" Opt ("MustDeclareVars", 1) $_WCD_Verbose = True ; as for the server, you can decide to make client verbose or not Global $hWnd = _WCD_CreateClient ("Test WCD Client") Global $hWndServer = _WCD_GetServerHandle () _WCD_Send($hWnd, $hWndServer, 1) ; simple request - who are you ? Local $sString = WaitForResponse () ConsoleWrite ($sString & @CRLF) _WCD_Send($hWnd, $hWndServer, 2, "5") ; adding text to a more complex request $sString = WaitForResponse () ConsoleWrite ($sString & @CRLF) Func WaitForResponse () Local $sResp While _WCD_IsServerAvailable () $sResp = _WCD_Client_GetResponse () If $sResp <> "" Then Return $sResp Sleep (100) WEnd EndFunc As always, let me know if you got issues, comments, suggestions. I will be glad to answer. Version 2020-06-27 * Allows processes with different levels of privilege to communicate with each other WCD_IPC.au3
    1 point
×
×
  • Create New...