Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 09/27/2025 in all areas

  1. ioa747

    _LinksInspector

    Links Inspector This AutoIt script designed to scan a text-based file (e.g., TXT, HTML, XML, MD) for URLs and check their current HTTP status code. (to see if the link is active) Results can be filtered to show: All links '*' All non-200 codes '!' Specific codes e.g. '404, 503, 301' HTTP response status codes _LinksInspector.au3 ; https://www.autoitscript.com/forum/topic/213221-_linksinspector/ ;---------------------------------------------------------------------------------------- ; Title...........: _LinksInspector.au3 ; Description.....: Searches a file for URLs and checks their status codes. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.4 ; Note............: Testet in Win10 22H2 Date:03/10/2025 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #NoTrayIcon #include <GuiListView.au3> #include <GUIConstants.au3> #include <WinAPIShellEx.au3> ; Constants for Filtering Global Const $LINKS_BROKEN = "0, 404, 500, 501, 502, 503, 504" Global Const $LINKS_NEEDS_REVIEW = "301, 302, 307, 400, 401, 403" ; (Redirections, Unauthorized, Forbidden) ; Constant for WinHttp Options Global Const $WinHttpRequestOption_EnableRedirects = 6 ; Global variable Global $g_hListView, $g_iListIndex = -1 Global $g_ObjErr = ObjEvent("AutoIt.Error", "__ObjAutoItErrorEvent") Global $g_aLastComError[0] ; Global variable to store the last COM error: [Description, Number, Source, ScriptLine] Global $g_oHTTP = ObjCreate("WinHttp.WinHttpRequest.5.1") If Not IsObj($g_oHTTP) Then MsgBox(16, "Error", "Failed to create WinHttp.WinHttpRequest.5.1 COM object.") Exit EndIf ; #FUNCTION# ==================================================================================================================== ; Name...........: _LinksInspector ; Description....: Searches a file for URLs and checks their status codes, filtering based on specified criteria. ; Syntax.........: _LinksInspector($sFilePath [, $sFilter = "*" [, $bAttribOnly = False [, $idProgress = 0]]]) ; Parameters.....: $sFilePath - The path to the file containing the text to be searched. ; $sFilter - [Optional] Filtering mode: ; "*": Show all results (default for full review). ; "!": Show all except 200 (i.e., all errors and redirects). ; "400, 404": Show only the specific comma-separated status codes. ; $bAttribOnly - [Optional] True = Search ONLY for URLs within HTML/XML attributes (e.g., href="..."). (Default = False) ; : $idProgress - [Optional] The control ID of the progress bar to update, if there is a GUI. Default 0 (no update). ; Return values..: Success - Returns a 2D array: [LineNumbers (delimited by ';'), StatusCode, StatusText, URL]. ; Failure - Returns a empty 2D array and sets @error: ; 1 - The specified file path is invalid. ; 2 - No links found in the file content. ; Author ........: ioa747 ; Modified ......: ; Remarks .......: This function it uses the WinHttp.WinHttpRequest.5.1 COM object for efficient and reliable network requests. ; Checks each unique URL only once, regardless of how many times it appears in the file. ; Uses the HEAD method to retrieve status codes without downloading the full page content. ; Automatically follows redirects (3xx codes) to find the final status (e.g., 200 or 404). ; Utilizes ObjEvent to silently capture and log COM errors (like timeouts or DNS failures) as Status Code 0. ; Related .......: __CheckLinkStatus, __ObjAutoItErrorEvent ; Link ..........: https://www.autoitscript.com/forum/topic/213221-_linksinspector/ ; https://learn.microsoft.com/en-us/windows/win32/winhttp/winhttprequest ; https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status ; Example .......: _LinksInspector("C:\example.txt", "400, 404") ; to find and check URLs with specific status codes. ; =============================================================================================================================== Func _LinksInspector($sFilePath, $sFilter = "*", $bAttribOnly = False, $idProgress = 0) Local $aResults[0][4] Local $aUniqueLinks[0][2] ; [URL, Line_Numbers_String (e.g., "12;24")] ; Define Regex Patterns based on the optional flag ; Pattern for ATTRIBUTE SEARCH (Higher precision for HTML/XML): Finds URLs starting after =" or =' Local $sPatternAttrib = '(?i)[=""''](https?:\/\/[^""''\s<>]+)' ; Pattern for FULL SEARCH (Includes Attributes and Plain Text): The original broad pattern Local $sPatternFull = '(?i)(https?:\/\/[^""''\s<>]+)' Local $aFileLines = FileReadToArray($sFilePath) If @error Then MsgBox(16, "Error", "Failed to read file: " & $sFilePath) Return SetError(1, 0, $aResults) EndIf ; Filter Preprocessing (Logic remains the same) $sFilter = StringStripWS($sFilter, 8) Local $bFilterAll = ($sFilter = "*") Local $bFilterExclude200 = ($sFilter = "!") Local $aFilterCodes = 0 If Not $bFilterAll And Not $bFilterExclude200 Then $aFilterCodes = StringSplit($sFilter, ",", 2) EndIf Local $iLineCount = UBound($aFileLines) ; Select the appropriate pattern Local $sPattern = $sPatternFull If $bAttribOnly Then $sPattern = $sPatternAttrib EndIf ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; STAGE 1: Extract all links and record all lines where they appear (Handling Duplicates) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For $i = 0 To $iLineCount - 1 Local $sLine = $aFileLines[$i] Local $iLineNum = $i + 1 ; Use the selected pattern to find links Local $aLinks = StringRegExp($sLine, $sPattern, 3) If Not @error And IsArray($aLinks) Then For $j = 0 To UBound($aLinks) - 1 Local $sCleanURL = StringReplace($aLinks[$j], "&amp;", "&") $sCleanURL = StringRegExpReplace($sCleanURL, '[\)\(\"''<>,\.]$', "") $sCleanURL = StringStripWS($sCleanURL, 3) ; Find if the URL already exists in our unique list Local $iIndex = _ArraySearch($aUniqueLinks, $sCleanURL, 0, 0, 0, 0, 1, 0) If $iIndex = -1 Then ; URL is new, add it to the unique list _ArrayAdd($aUniqueLinks, $sCleanURL & "|" & $iLineNum, "|") Else ; URL already exists, append the current line number to the string $aUniqueLinks[$iIndex][1] = $aUniqueLinks[$iIndex][1] & ";" & $iLineNum EndIf Next EndIf Next If UBound($aUniqueLinks) = 0 Then Return SetError(2, 0, $aResults) ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; STAGE 2: Check the status of each UNIQUE link and apply filter ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local $iUniqueCount = UBound($aUniqueLinks) For $i = 0 To $iUniqueCount - 1 ; *** Update GUI only if a valid Progress Bar ID is given *** If $idProgress <> 0 Then Local $iPercent = Int((($i + 1) / $iUniqueCount) * 100) GUICtrlSetData($idProgress, $iPercent) Sleep(10) ; Short pause for GUI response EndIf Local $sURL = $aUniqueLinks[$i][0] Local $sLineNums = $aUniqueLinks[$i][1] Local $aStatus = __CheckLinkStatus($sURL) Local $iStatusCode = $aStatus[0] ; Filtering Logic Local $bAddResult = False If $bFilterAll Then $bAddResult = True ElseIf $bFilterExclude200 Then If $iStatusCode <> 200 Then $bAddResult = True ElseIf IsArray($aFilterCodes) Then If _ArraySearch($aFilterCodes, $iStatusCode) <> -1 Then $bAddResult = True EndIf If $bAddResult Then _ArrayAdd($aResults, $sLineNums & "|" & $iStatusCode & "|" & $aStatus[1] & "|" & $sURL) EndIf ; for debugging purposes only ConsoleWrite(($bAddResult ? "+ " : "- ") & $sLineNums & " |> " & $aStatus[1] & " |> " & $sURL & @CRLF) Next If UBound($aResults) = 0 Then Return SetError(2, 0, $aResults) Return $aResults EndFunc ;==>_LinksInspector ;--------------------------------------------------------------------------------------- Func __CheckLinkStatus($sURL) Local $iStatusCode = 0 Local $sStatusText = "Failed - Connection/Timeout Error" ; Set timeouts for the current request ; ResolveTimeout: 5 sec ; ConnectTimeout: 5 sec ; SendTimeout: 10 sec ; ReceiveTimeout: 10 sec $g_oHTTP.SetTimeouts(5000, 5000, 10000, 10000) ; *** WinHttp will follow up to 10 redirects to find the final code ($200 or $404). $g_oHTTP.SetOption($WinHttpRequestOption_EnableRedirects, True) ; Clear the global COM error log before the call ReDim $g_aLastComError[0] ; Open and Send the Request $g_oHTTP.Open("HEAD", $sURL, False) $g_oHTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") ; If a COM error occurs here (e.g. DNS fail), it will fill $g_aLastComError, ; but the script flow will continue without a MsgBox. $g_oHTTP.Send() ; Check the global COM error log immediately after the call If UBound($g_aLastComError) > 0 Then ; A COM errors $iStatusCode = 0 $sStatusText = "Failed - COM Error: (" & StringReplace($g_aLastComError[0], @CRLF, " ") & ")" ElseIf @error Then ; AutoIt errors $iStatusCode = 0 $sStatusText = "Failed - AutoIt Error (" & @error & ")" Else ; The call was successful, retrieve the HTTP status $iStatusCode = $g_oHTTP.Status $sStatusText = $g_oHTTP.StatusText EndIf ; Process Status Text for final output Select Case $iStatusCode == 0 ; Status text is already set Case $iStatusCode == 200 $sStatusText = "Alive - OK" Case $iStatusCode >= 300 And $iStatusCode < 400 ; With automatic tracking, 3xx codes will rarely appear here, ; unless 10 redirects are exceeded. $sStatusText = "Redirected (Needs Review)" Case $iStatusCode == 404 $sStatusText = "Not Found" Case $iStatusCode >= 400 And $iStatusCode < 500 $sStatusText = "Client Error" Case $iStatusCode >= 500 And $iStatusCode < 600 $sStatusText = "Server Error" Case Else If StringStripWS($sStatusText, 3) == "" Then $sStatusText = "Unknown Status (" & $iStatusCode & ")" EndSelect Local $aResults = [$iStatusCode, $sStatusText] Return $aResults EndFunc ;==>__CheckLinkStatus ;--------------------------------------------------------------------------------------- Func __ObjAutoItErrorEvent() If IsObj($g_ObjErr) Then ; This filters out false positives with an empty description. If $g_ObjErr.Number <> 0 And StringStripWS($g_ObjErr.Description, 3) <> "" Then ; Store the error details in the global array (instead of showing MsgBox) ReDim $g_aLastComError[4] $g_aLastComError[0] = $g_ObjErr.description $g_aLastComError[1] = Hex($g_ObjErr.Number, 8) ; $g_ObjErr.Number $g_aLastComError[2] = $g_ObjErr.Source $g_aLastComError[3] = $g_ObjErr.ScriptLine ; ConsoleWrite('@@(' & $g_aLastComError[3] & ') :: COM Error Logged: Desc.: "' & StringReplace($g_aLastComError[0], @CRLF, " ") & '"' & @CRLF) EndIf ; Clear the properties of ObjEvent $g_ObjErr.Description = "" $g_ObjErr.Number = 0 EndIf EndFunc ;==>__ObjAutoItErrorEvent ;--------------------------------------------------------------------------------------- Func _LinksInspectorGUI($sFilePath = "") ; Function to create the main graphical user interface _WinAPI_SetCurrentProcessExplicitAppUserModelID(StringTrimRight(@ScriptName, 4)) Local $hGUI = GUICreate("Links Inspector", 700, 500) GUISetIcon(@SystemDir & "\shell32.dll", -136) GUICtrlCreateLabel("File Path:", 10, 15, 50, 20) ; *** Local $idInputFile = GUICtrlCreateInput($sFilePath, 60, 10, 530, 24) Local $idBtnBrowse = GUICtrlCreateButton("Browse", 600, 10, 90, 24) GUICtrlCreateLabel("Filter:", 60, 45, 30, 20) ; *** GUICtrlSetTip(-1, " '*' Show all results" & @CRLF & " '!' Show all except 200" & @CRLF & " '400, 404' Show only the specific status codes.") Local $idInputFilter = GUICtrlCreateInput("*", 90, 40, 200, 24) ; *** GUICtrlSetFont(-1, 12) Local $idCheckboxAttrib = GUICtrlCreateCheckbox("Attribute Search Only", 310, 43, 150, 20) ; *** Local $idBtnInspect = GUICtrlCreateButton("Start Inspection", 600, 40, 90, 24) Local $idBtnSaveReport = GUICtrlCreateButton("Save Report", 500, 40, 90, 24) GUICtrlSetState(-1, $GUI_DISABLE) Local $idIconInfo = GUICtrlCreateIcon("wmploc.dll", -60, 20, 44, 16, 16) $g_hListView = _GUICtrlListView_Create($hGUI, "", 10, 80, 680, 380) Local $iExListViewStyle = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_GRIDLINES, $LVS_EX_DOUBLEBUFFER, $LVS_EX_INFOTIP) _GUICtrlListView_SetExtendedListViewStyle($g_hListView, $iExListViewStyle) Local $idProgress = GUICtrlCreateProgress(10, 470, 680, 20) GUISetState(@SW_SHOW) _GUICtrlListView_RegisterSortCallBack($g_hListView, 0) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ; Add columns to $g_hListView "Line(s)|Code|Status|URL" _GUICtrlListView_AddColumn($g_hListView, "Line(s)", 50) _GUICtrlListView_AddColumn($g_hListView, "Code", 40) _GUICtrlListView_AddColumn($g_hListView, "Status", 80) _GUICtrlListView_AddColumn($g_hListView, "URL", 500) Local $mCODES[] Local $aHTTP_STATUS = _HTTP_STATUS($mCODES) Local $nMsg, $aResults, $iLastStatusID, $sTipTitle, $sTipText, $iLastIndex = -1 While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $idBtnBrowse $sFilePath = FileOpenDialog("Select File to Inspect", @ScriptDir, "All Files (*.*)", 1, GUICtrlRead($idInputFile)) If @error Then ContinueLoop GUICtrlSetData($idInputFile, $sFilePath) _GUICtrlListView_DeleteAllItems($g_hListView) ; Clear Listview GUICtrlSetState($idBtnSaveReport, $GUI_DISABLE) ; disable the Save_Report button $aResults = 0 Case $idBtnInspect ; Reset UI elements _GUICtrlListView_DeleteAllItems($g_hListView) ; Clear Listview GUICtrlSetData($idProgress, 0) GUICtrlSetState($idBtnSaveReport, $GUI_DISABLE) ; disable the Save_Report button $aResults = 0 ; Get user input $sFilePath = GUICtrlRead($idInputFile) Local $sFilter = GUICtrlRead($idInputFilter) Local $bAttribOnly = GUICtrlRead($idCheckboxAttrib) = $GUI_CHECKED ; Input validation If Not FileExists($sFilePath) Then MsgBox(48, "Error", "File not found: " & $sFilePath) ContinueLoop EndIf GUICtrlSetState($idBtnInspect, $GUI_DISABLE) ; Temporarily disable the Inspect button during inspection $aResults = _LinksInspector($sFilePath, $sFilter, $bAttribOnly, $idProgress) ; Handle results If @error = 1 Then ; Error 1 is already handled inside _LinksInspector (FileReadToArray error) ElseIf @error = 2 Then MsgBox(64, "Info", "No links found matching the criteria in the file.") Else ; Add results to Listview _GUICtrlListView_SetItemCount($g_hListView, UBound($aResults)) _GUICtrlListView_AddArray($g_hListView, $aResults) ; MsgBox(64, "Success", "Inspection complete. Found " & $iCount & " results.") EndIf Sleep(500) ; give some time to show the ProgressBar GUICtrlSetData($idProgress, 0) ; Update progress bar to 0% GUICtrlSetState($idBtnInspect, $GUI_ENABLE) ; enable Inspect button If UBound($aResults) > 0 Then GUICtrlSetState($idBtnSaveReport, $GUI_ENABLE) ; enable Save_Report button Case $idBtnSaveReport Local $sReportPath = FileSaveDialog("Save LinksInspector Report", @ScriptDir, _ "Text Files (*.txt)", 1, "LinksInspector Report.txt") If Not @error And $sReportPath <> "" Then If FileExists($sReportPath) Then If MsgBox($MB_YESNO + $MB_ICONWARNING, "File already exists", $sReportPath & @CRLF & _ "Do you want to replace it?") = $IDNO Then ContinueLoop FileDelete($sReportPath) EndIf Local $sReportData = _ArrayToString($aResults) $sReportData = "Line(s)|Code|Status|URL" & @CRLF & $sReportData FileWrite($sReportPath, $sReportData) EndIf EndSwitch ; Update the ToolTip of the info icon If $iLastIndex <> $g_iListIndex Then $iLastIndex = $g_iListIndex ConsoleWrite("$iLastIndex=" & $iLastIndex & @CRLF) $iLastStatusID = Int(_GUICtrlListView_GetItemText($g_hListView, $iLastIndex, 1)) If $iLastStatusID = 0 Then $sTipTitle = "(0) COM Error" $sTipText = _GUICtrlListView_GetItemText($g_hListView, $iLastIndex, 2) Else $sTipTitle = "" $sTipText = "" If MapExists($mCODES, $iLastStatusID) Then $sTipTitle = "(" & $aHTTP_STATUS[$mCODES[$iLastStatusID]][0] & ") " & $aHTTP_STATUS[$mCODES[$iLastStatusID]][1] $sTipText = StringFormat($aHTTP_STATUS[$mCODES[$iLastStatusID]][2]) EndIf EndIf GUICtrlSetTip($idIconInfo, $sTipText, $sTipTitle, $TIP_INFOICON) EndIf WEnd EndFunc ;==>_LinksInspectorGUI ;--------------------------------------------------------------------------------------- Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Local $hWndFrom, $iCode, $tNMHDR, $tInfo, $index, $subitem, $sURL $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom")) $iCode = DllStructGetData($tNMHDR, "Code") Switch $hWndFrom Case $g_hListView Switch $iCode Case $LVN_COLUMNCLICK $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam) ;$index = DllStructGetData($tInfo, "Index") $subitem = DllStructGetData($tInfo, "SubItem") ; Kick off the sort callback _GUICtrlListView_SortItems($hWndFrom, $subitem) ; No return value Case $NM_DBLCLK $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam) $index = DllStructGetData($tInfo, "Index") $subitem = DllStructGetData($tInfo, "SubItem") $g_iListIndex = $index $sURL = _GUICtrlListView_GetItemText($g_hListView, $index, 3) If $subitem = 3 Then ShellExecute($sURL) ; No return value Case $NM_CLICK $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam) $index = DllStructGetData($tInfo, "Index") ;$subitem = DllStructGetData($tInfo, "SubItem") $g_iListIndex = $index ConsoleWrite("$g_iListIndex=" & $g_iListIndex & @CRLF) ; No return value EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ;--------------------------------------------------------------------------------------- Func _HTTP_STATUS(ByRef $mMap) Local $aHTTP_STATUS_CODES[63][3] = [ _ [100, "Continue", "This interim response indicates that the client \nshould continue the request or \nignore the response if the request is already finished."], _ [101, "Switching Protocols", "This code is sent in response to \nan Upgrade request header from the \nclient and indicates the protocol the server is switching to."], _ [102, "Processing Deprecated", "This code was used in WebDAV contexts to indicate \nthat a request has been received by the server, \nbut no status was available at the time of the response."], _ [103, "Early Hints", "This status code is primarily intended to be used with the Link header, \nletting the user agent start preloading resources while the server \nprepares a response or preconnect to an origin from which the page will need resources."], _ [200, "OK", "The request succeeded. The result and meaning of 'success' depends on the HTTP method:\nGET: The resource has been fetched and transmitted in the message body.\nHEAD: Representation headers are included in the response without any message body.\nPUT or POST: The resource describing the result of the action is transmitted in the message body. \nTRACE: The message body contains the request as received by the server."], _ [201, "Created", "The request succeeded, \nand a new resource was created as a result. \nThis is typically the response sent after POST requests, \nor some PUT requests."], _ [202, "Accepted", "The request has been received but not yet acted upon. \nIt is noncommittal, since there is no way in HTTP to later send an \nasynchronous response indicating the outcome of the request. \nIt is intended for cases where another process \nor server handles the request, or for batch processing."], _ [203, "Non-Authoritative Information", "This response code means the returned metadata \nis not exactly the same as is available from the origin server, \nbut is collected from a local or a third-party copy. \nThis is mostly used for mirrors or backups of another resource. \nExcept for that specific case, the 200 OK response is preferred to this status."], _ [204, "No Content", "There is no content to send for this request, but the headers are useful. \nThe user agent may update its cached headers for this resource with the new ones."], _ [205, "Reset Content", "Tells the user agent to reset the document which sent this request."], _ [206, "Partial Content", "This response code is used in response to a range request \nwhen the client has requested a part or parts of a resource."], _ [207, "Multi-Status (WebDAV)", "Conveys information about multiple resources, \nfor situations where multiple status codes might be appropriate."], _ [208, "Already Reported (WebDAV)", "Used inside a <dav:propstat> response element to avoid \nrepeatedly enumerating the internal members of multiple bindings to the same collection."], _ [226, "IM Used (HTTP Delta encoding)", "The server has fulfilled a GET request for the resource, \nand the response is a representation of the result of one or more \ninstance-manipulations applied to the current instance."], _ [300, "Multiple Choices", "In agent-driven content negotiation, \nthe request has more than one possible response and \nthe user agent or user should choose one of them. \nThere is no standardized way for clients to automatically \nchoose one of the responses, so this is rarely used."], _ [301, "Moved Permanently", "The URL of the requested resource has been changed permanently. \nThe new URL is given in the response."], _ [302, "Found", "This response code means that the URI of \nrequested resource has been changed temporarily. \nFurther changes in the URI might be made in the future, \nso the same URI should be used by the client in future requests."], _ [303, "See Other", "The server sent this response to direct the client \nto get the requested resource at another URI with a GET request."], _ [304, "Not Modified", "This is used for caching purposes. \nIt tells the client that the response has not been modified, \nso the client can continue to use the same cached version of the response."], _ [305, "Use Proxy Deprecated", "Defined in a previous version of the HTTP specification \nto indicate that a requested response must be accessed by a proxy. \nIt has been deprecated due to security concerns regarding in-band configuration of a proxy."], _ [306, "unused", "This response code is no longer used; \nbut is reserved. It was used in a previous version of the HTTP/1.1 specification."], _ [307, "Temporary Redirect", "The server sends this response to direct the client to get the requested resource \nat another URI with the same method that was used in the prior request. \nThis has the same semantics as the 302 Found response code, \nwith the exception that the user agent must not change the HTTP method used: \nif a POST was used in the first request, a POST must be used in the redirected request."], _ [308, "Permanent Redirect", "This means that the resource is now permanently located at another URI, \nspecified by the Location response header. \nThis has the same semantics as the 301 Moved Permanently HTTP response code, \nwith the exception that the user agent must not change the HTTP method used: \nif a POST was used in the first request, \na POST must be used in the second request."], _ [400, "Bad Request", "The server cannot or will not process the request due \nto something that is perceived to be a client error \n(e.g., malformed request syntax, invalid request message framing, \nor deceptive request routing)."], _ [401, "Unauthorized", "Although the HTTP standard specifies 'unauthorized', \nsemantically this response means 'unauthenticated'. \nThat is, the client must authenticate itself to get the requested response."], _ [402, "Payment Required", "The initial purpose of this code was for digital payment systems, \nhowever this status code is rarely used and no standard convention exists."], _ [403, "Forbidden", "The client does not have access rights to the content; \nthat is, it is unauthorized, so the server is refusing \nto give the requested resource. \nUnlike 401 Unauthorized, \nthe client's identity is known to the server."], _ [404, "Not Found", "The server cannot find the requested resource. \nIn the browser, this means the URL is not recognized. \nIn an API, this can also mean that the endpoint is valid but the resource itself does not exist. \nServers may also send this response instead of 403 Forbidden \nto hide the existence of a resource from an unauthorized client. \nThis response code is probably the most well known \ndue to its frequent occurrence on the web."], _ [405, "Method Not Allowed", "The request method is known by the server \nbut is not supported by the target resource. \nFor example, an API may not allow DELETE on a resource, \nor the TRACE method entirely."], _ [406, "Not Acceptable", "This response is sent when the web server, \nafter performing server-driven content negotiation, \ndoesn't find any content that conforms to the criteria \ngiven by the user agent."], _ [407, "Proxy Authentication Required", "This is similar to 401 Unauthorized but \nauthentication is needed to be done by a proxy."], _ [408, "Request Timeout", "This response is sent on an idle connection by some servers, \neven without any previous request by the client. \nIt means that the server would like to shut down this unused connection. \nThis response is used much more since some browsers use HTTP pre-connection mechanisms to speed up browsing. \nSome servers may shut down a connection without sending this message."], _ [409, "Conflict", "This response is sent when a request conflicts with the current state of the server. \nIn WebDAV remote web authoring, \n409 responses are errors sent to the client so that a user might be \nable to resolve a conflict and resubmit the request."], _ [410, "Gone", "This response is sent when the requested content has been \npermanently deleted from server, \nwith no forwarding address. \nClients are expected to remove their caches and links to the resource. \nThe HTTP specification intends this status code to be used for 'limited-time, \npromotional services'. \nAPIs should not feel compelled to indicate resources \nthat have been deleted with this status code."], _ [411, "Length Required", "Server rejected the request because \nthe Content-Length header field is not defined and \nthe server requires it."], _ [412, "Precondition Failed", "In conditional requests, \nthe client has indicated preconditions in its headers \nwhich the server does not meet."], _ [413, "Content Too Large", "The request body is larger than limits defined by server. \nThe server might close the connection or \nreturn an Retry-After header field."], _ [414, "URI Too Long", "The URI requested by the client is \nlonger than the server is willing to interpret."], _ [415, "Unsupported Media Type", "The media format of the requested data is not supported by the server, \nso the server is rejecting the request."], _ [416, "Range Not Satisfiable", "The ranges specified by the Range header field in the request cannot be fulfilled. \nIt's possible that the range is outside the size of the target resource's data."], _ [417, "Expectation Failed", "This response code means the expectation indicated by \nthe Expect request header field cannot be met by the server."], _ [418, "I'm a teapot", "The server refuses the attempt to brew coffee with a teapot."], _ [421, "Misdirected Request", "The request was directed at a server that is not able to produce a response. \nThis can be sent by a server that is not configured \nto produce responses for the combination of scheme and \nauthority that are included in the request URI."], _ [422, "Unprocessable Content (WebDAV)", "The request was well-formed but was unable to be followed due to semantic errors."], _ [423, "Locked (WebDAV)", "The resource that is being accessed is locked."], _ [424, "Failed Dependency (WebDAV)", "The request failed due to failure of a previous request."], _ [425, "Too Early Experimental", "Indicates that the server is unwilling to \nrisk processing a request that might be replayed."], _ [426, "Upgrade Required", "The server refuses to perform the request using the current protocol but \nmight be willing to do so after the client upgrades to a different protocol. \nThe server sends an Upgrade header in a 426 response to indicate the required protocol(s)."], _ [428, "Precondition Required", "The origin server requires the request to be conditional. \nThis response is intended to prevent the 'lost update' problem, \nwhere a client GETs a resource's state, \nmodifies it and PUTs it back to the server, \nwhen meanwhile a third party has modified the state on the server, \nleading to a conflict."], _ [429, "Too Many Requests", "The user has sent too many requests in a given amount of time (rate limiting)."], _ [431, "Request Header Fields Too Large", "The server is unwilling to process the request because its header fields are too large. \nThe request may be resubmitted after reducing the size of the request header fields."], _ [451, "Unavailable For Legal Reasons", "The user agent requested a resource that cannot legally be provided, \nsuch as a web page censored by a government."], _ [500, "Internal Server Error", "The server has encountered a situation it does not know how to handle. \nThis error is generic, indicating that the server cannot find \na more appropriate 5XX status code to respond with."], _ [501, "Not Implemented", "The request method is not supported by the server and cannot be handled. \nThe only methods that servers are required to support \n(and therefore that must not return this code) are GET and HEAD."], _ [502, "Bad Gateway", "This error response means that the server, \nwhile working as a gateway to get a response needed to handle the request, \ngot an invalid response."], _ [503, "Service Unavailable", "The server is not ready to handle the request. \nCommon causes are a server that is down for maintenance or that is overloaded. \nNote that together with this response, \na user-friendly page explaining the problem should be sent. \nThis response should be used for temporary conditions and the Retry-After HTTP header should, \nif possible, contain the estimated time before the recovery of the service. \nThe webmaster must also take care about the caching-related headers that are sent along with this response, \nas these temporary condition responses should usually not be cached."], _ [504, "Gateway Timeout", "This error response is given when the server is \nacting as a gateway and cannot get a response in time."], _ [505, "HTTP Version Not Supported", "The HTTP version used in the request is not supported by the server."], _ [506, "Variant Also Negotiates", "The server has an internal configuration error: during content negotiation, \nthe chosen variant is configured to engage in content negotiation itself, \nwhich results in circular references when creating responses."], _ [507, "Insufficient Storage (WebDAV)", "The method could not be performed on the resource because the server is unable \nto store the representation needed to successfully complete the request."], _ [508, "Loop Detected (WebDAV)", "The server detected an infinite loop while processing the request."], _ [510, "Not Extended", "The client request declares an HTTP Extension (RFC 2774) that should be used to process the request, \nbut the extension is not supported."], _ [511, "Network Authentication Required", "Indicates that the client needs to authenticate to gain network access."] _ ] Local $m[] Local $STATUS_CODES For $i = 0 To UBound($aHTTP_STATUS_CODES) - 1 $STATUS_CODES = Int($aHTTP_STATUS_CODES[$i][0]) $m[$STATUS_CODES] = $i Next $mMap = $m Return $aHTTP_STATUS_CODES EndFunc ;==>_HTTP_STATUS ;--------------------------------------------------------------------------------------- ; ##### Example Usage demonstrating filters ##### ;--------------------------------------------------------------------------------------- _Example() Func _Example() Local $sTestFilePath = @ScriptDir & "\links_test.txt" ; With GUI _LinksInspectorGUI($sTestFilePath) ; or just as function Local $aLinks ;~ $aLinks = _LinksInspector($sTestFilePath, "*") ; Show ALL links ;~ $aLinks = _LinksInspector($sTestFilePath, "*", True) ; Show ALL, but ONLY for URLs within HTML/XML attributes (e.g., href="..."). ;~ $aLinks = _LinksInspector($sTestFilePath, "!") ; Show ALL results except 200 ;~ $aLinks = _LinksInspector($sTestFilePath, "400, 404") ; Show ONLY the 400 and 404 ;~ $aLinks = _LinksInspector($sTestFilePath, $LINKS_BROKEN) ; Show $LINKS_BROKEN = "0, 404, 500, 501, 502, 503, 504" ;~ $aLinks = _LinksInspector($sTestFilePath, $LINKS_NEEDS_REVIEW) ; Show $LINKS_NEEDS_REVIEW = "301, 302, 307, 400, 401, 403" _ArrayDisplay($aLinks, "$aLinks", "", 0, Default, "Line(s)|Code|Status|URL") EndFunc ;==>_Example Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
    3 points
  2. Hi @donnyh13, One of the changes in in v1.0.14 is the minimum supported vscode engine, from 1.52.0 to 1.96.0. relevant commit here: https://github.com/loganch/AutoIt-VSCode/commit/ede5ceab464f74149f5f46a2741f6536ae7664d4 I'm pretty sure this is what is preventing you from installing, since version 1.70.3 is the last vscode version that supports windows7. source: https://code.visualstudio.com/updates/v1_70 I would argue that a change in supported vscode engine version should require a release version to bump the major version number, this was released as part of a patch version. Self promotion 😛: my extension should still work, since my vscode engine version is on 1.61.0 as it was since the beginning
    3 points
  3. You're perfectly right. Relevant neurons fixed!
    3 points
  4. I could install Win7 in a VM but am clueless to all VSCode. I don't use it. Would not know what works and what don't. If you don't have a Win7 ISO, go to torrent-land and get an up to date one. I'll retire the day I die. Maybe even after ! I loved WinXP but time moves forward. Win11 ain't bad ( after you tweak the heck out of it ). I install Windows on any language is not because am a polyglot, but because everything is always pretty much the same in the same place, same icons. Remember: Your feet don't stay on the ground because of gravity. The whole planet stick to your feet because of your gravitas 🙇
    3 points
  5. wakillon

    _LinksInspector

    Hi ioa747 I have tried your code with an autoitscript.com xml file sitemap and it works pretty well 😉 https://www.autoitscript.com/site/page-sitemap.xml And we can see some 404 error messages there 😅
    2 points
  6. Regexes can save your a$$ everyday!
    2 points
  7. Func test3() Local $sStr = "a ''' 123 ''' b ''' 234 ''' c" ConsoleWrite(StringRegExpReplace($sStr, "'''([^']+)'''", "*'$1'*") & @CRLF) EndFunc
    2 points
  8. Thanks @genius257, that explains it. I have your extension too. I may have to switch to it, I switched to this because yours didn't support With statements yet and got annoyed with the error, as a function or two in the LibreOffice UDF uses it. But I may get used to the error Thanks for the tip, and your work on the extension. Thanks again everyone! Maybe Microsoft will take a hint and re-support it Edit: Sorry Logan, and all other dev's, for the thread hijack. Thanks for your hard work.
    2 points
  9. Thanks for the reply and the diagnostics. Yes, I bet you are correct. Looking at Logan’s release notes for the version that is no longer compatible, node.js is the only thing there that would make sense as being the problem. 😂 I think this would be fitting! Thanks everyone for the help. off-topic reply------------------- Best regards,
    2 points
  10. Greetings everyone; I was wondering if some familiar with the English language, in the various flavors, could chip in. To me, the following snippets from the help file are using the wrong word, "Loose" instead of "Lose". Is there some reversal of meaning in other dialects with these words? Between American English and European English, etc.? My understanding is as follows: "Loose" = a loose tooth in your mouth, "Lose" = you lose a tooth, (It has fallen out). Help file snippets: Thanks,
    2 points
  11. Fair enough, understood, thanks. Thanks 👌 . 😂 Maybe you should rename yourself to Philosoph'tum 😆 . Best regards Sven
    2 points
  12. SOLVE-SMART

    WebDriver problem

    Hi @quymao2, please open a new thread for your topic. Because this one is related to another question which is not finally discucced. When you open a new thread, please explain a bit more what's your goal by using the CDP (chrome dev protocal) functions. More inforamation for us, more likely that we can suggest and help you well 😀 . Best regards Sven
    2 points
  13. Just PM me or attach the updated LUA file when you have fixes, and I will merge them into my local version for the next upload. 🙂
    2 points
  14. Hi Jos, Not sure if you are wishing for a fix to the comments. But if so: I added to ~Line 105: if string.find(editor:GetLine(Parent_line), "^%s*;") then self:DebugPrint('! Parent Line is a Comment, finding real parent.', "Old Parent line: " .. Parent_line, "New Parent Line: " .. editor.FoldParent[Parent_line]) Parent_line = editor.FoldParent[Parent_line] end And to ~line 228, after: elseif Curr_firstword == "" and Curr_lastword == "" and Parent_line ~= -1 and string.find(',if,do,while,with,for,select,switch,func,volatile,', ',' .. fold_firstword .. ',', nil, true) ~= nil then -- Empty line in a fold, update indent to appropriate parent fold level. editor.LineIndentation[line + 1] = editor.LineIndentation[Parent_line] + editor.Indent self:DebugPrint('- Empty line in a keyword, update indent to Parent + 1 --', editor.LineIndentation[line + 1]) Added the following: elseif (string.find(Curr_firstword, "^;") ~= nil) and Curr_lastword == "" then -- Correct Indent after a comment which may be in the wrong indentation position. if (Parent_line ~= -1) and string.find(',if,do,while,with,for,select,switch,func,volatile,', ',' .. fold_firstword .. ',', nil, true) ~= nil then editor.LineIndentation[line + 1] = editor.LineIndentation[Parent_line] + editor.Indent self:DebugPrint('- New line after a comment, update indent to Parent + 1 --', "New Indent Level: " .. editor.LineIndentation[line + 1]) else editor.LineIndentation[line + 1] = 0 self:DebugPrint('- New line after a comment outside of a fold, update indent to 0 --', "New Indent Level: " .. editor.LineIndentation[line + 1]) end If you're not concerned. You can ignore this. Best regards,
    2 points
  15. ; https://www.autoitscript.com/forum/topic/213213-text-in-gdi-images-loses-transparency/#findComment-1546336 #include <WinAPIConstants.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> _GDIPlus_Startup() Global $iW, $iH, $hImage, $hGUI $hImage = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\cart.png") $iW = _GDIPlus_ImageGetWidth($hImage) $iH = _GDIPlus_ImageGetHeight($hImage) $hGUI = GUICreate("", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_LAYERED)) GUISetState() _add_TEXT_to_IMG($hImage, String(5), 58, 5) ; Convert the MODIFIED GDI+ image to HBITMAP Local $hBitmapToDisplay = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) ; Display the new HBITMAP transparently _WinAPI_BitmapDisplayTransparentInGUI($hBitmapToDisplay, $hGUI) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE ; Cleanup ; _WinAPI_BitmapDisplayTransparentInGUI already deleted $hBitmapToDisplay _GDIPlus_BitmapDispose($hImage) _GDIPlus_Shutdown() GUIDelete() Func _add_TEXT_to_IMG(ByRef $hImage, $sText, $iX = 5, $iY = 70, $sFontName = "Arial", $fSize = 5, $fStyle = 1, $iColor = 0xFFFFFFFF) Local Const $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 4) _GDIPlus_GraphicsSetTextRenderingHint($hGraphic, 3) Local Const $hBrush = _GDIPlus_BrushCreateSolid($iColor) Local Const $hFormat = _GDIPlus_StringFormatCreate() ;~ _GDIPlus_StringFormatSetAlign($hFormat, 1) ; Center text horizontally _GDIPlus_StringFormatSetAlign($hFormat, 0) ; Left Align for better text control Local Const $hFamily = _GDIPlus_FontFamilyCreate($sFontName) Local Const $hFont = _GDIPlus_FontCreate($hFamily, $fSize, $fStyle) Local Const $aDim = _GDIPlus_ImageGetDimension($hImage) ;~ Local Const $tLayout = _GDIPlus_RectFCreate($iX, $iY, $aDim[0], $aDim[1]) Local Const $tLayout = _GDIPlus_RectFCreate($iX, $iY, $aDim[0] - $iX, $aDim[1] - $iY) ; Adjusted layout for better text control _GDIPlus_GraphicsDrawStringEx($hGraphic, $sText, $hFont, $tLayout, $hFormat, $hBrush) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGraphic) EndFunc ;==>_add_TEXT_to_IMG Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True) ; (by @UEZ) If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0) Local $tDim = DllStructCreate($tagBITMAP) If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0) Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) $tSize.X = $tDim.bmWidth $tSize.Y = $tDim.bmHeight $tBlend.Alpha = $iOpacity $tBlend.Format = 1 _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteDC($hMemDC) If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap) Return True EndFunc ;==>_WinAPI_BitmapDisplayTransparentInGUI
    2 points
  16. Biatu

    Calling 7z.dll

    https://github.com/BiatuAutMiahn/DriverMgr2/blob/main/CPP/7zip/UI/Client7z/Client7z.cpp I franeknstein'd Igor's Client7z implementation so that I could read DriverPack archives, and make a driver database. Cleaned that mess up a bit into this: https://github.com/BiatuAutMiahn/7zip/blob/DriverMgr/CPP/7zip/Common/DriverPackMgr.cpp Then I exported the ddb functionality into a standalone utility for the DriverPackDB creation and hardware matching. https://github.com/BiatuAutMiahn/dpdbutil This is part of a driver framework in my WinPE project for work. Figured this was perfect for adding drivers to WinPE instead of mounting the image and injecting drivers, just look for the DDBs and load them.
    2 points
  17. So maybe i just haven't been looking hard enough, but i could not find how to make toast notifications in win8+ from AutoIt. I looked at it on and off, and finally made some progress. Github repository: https://github.com/genius257/au3toast Zip download: https://github.com/genius257/au3toast/archive/52f6eb0c5e6543777e19010a6c64f46e4dbe8fe0.zip I am still working on event support, but would like some feedback from the forum so far Thanks!
    2 points
  18. Hi @genius257, Very cool, I'm not familiar with this stuff, but it looks interesting. You've done a great job implementing it in AutoIt! I tried creating some simple test toasts in XML, but not all the tags work correctly at the moment (for example, the <image> tag doesn't display the image if the "src=" parameter is a URL...). Furthermore, it's mandatory to specify the activationType="background" parameter in the initial <toast...> tag... To generate my test toasts in XML, I installed this app (which also has ready-made templates): https://apps.microsoft.com/detail/9nblggh5xsl1 then, to insert the generated XML code into your example listing in AutoIt, I copy the generated code to the clipboard (select the listing and press Ctrl-C), and immediately run this little script (F5 in SciTE), which adapts it and puts it back in the clipboard. I then paste it into the AutoIt listing. Local $sVarName = "$sToast" Local $aStr = StringSplit(ClipGet(), @CRLF, 1) ; get the clipboard content Local $sListing ; = "Func " & $sFuntionName & "()" & @CRLF $sListing &= 'Local ' & $sVarName & ' = ""' & @CRLF For $i = 1 To $aStr[0] $sListing &= $sVarName & ' &= "' & StringReplace($aStr[$i], '"', '""') & '" ' & @CRLF Next ClipPut($sListing) ConsoleWrite($sListing) This is an example of output (which I later modified a bit) to insert into the example script. Local $sToast = "" $sToast &= "<toast activationType=""background"" launch=""action=viewAlarm&amp;alarmId=3"" scenario=""alarm"">" $sToast &= "" $sToast &= " <visual>" $sToast &= " <binding template=""ToastGeneric"">" $sToast &= " <text>Time to wake up!</text>" $sToast &= " <text>To prove you're awake, select which of the following fruits is yellow...</text>" $sToast &= ' <image placement="appLogoOverride" src="file://' & @TempDir & '\e21cd29c9fb51c3a5b82f009ec33fc997d2edd1ece931e8568f37e205c445778.jpeg" hint-crop="circle"/>' $sToast &= " </binding>" $sToast &= " </visual>" $sToast &= "" $sToast &= " <actions>" $sToast &= "" $sToast &= " <input id=""answer"" type=""selection"" defaultInput=""wrongDefault"">" $sToast &= " <selection id=""wrong"" content=""Orange""/>" $sToast &= " <selection id=""wrongDefault"" content=""Blueberry""/>" $sToast &= " <selection id=""right"" content=""Banana""/>" $sToast &= " <selection id=""wrong"" content=""Avacado""/>" $sToast &= " <selection id=""wrong"" content=""Cherry""/>" $sToast &= " </input>" $sToast &= "" $sToast &= " <action" $sToast &= " activationType=""system""" $sToast &= " arguments=""snooze""" $sToast &= " content=""""/>" $sToast &= "" $sToast &= " <action" $sToast &= " activationType=""background""" $sToast &= " arguments=""dismiss""" $sToast &= " content=""Dismiss""/>" $sToast &= "" $sToast &= " </actions>" $sToast &= ' <audio src=''ms-winsoundevent:Notification.Looping.Alarm'' loop=''false''/>' $sToast &= "</toast>" .. I hope you can implement support for events too... Bye and thanks! P.S. There was a notification "emulator" at this link:: Notifications UDF - Desktop notifications 1.2 (updated Mai 1st) - AutoIt Example Scripts - AutoIt Forums
    2 points
  19. ioa747

    _LinksInspector

    Some improvements were made to the GUI The first post has been updated with version 0.4
    1 point
  20. wakillon

    _LinksInspector

    Your welcome Some includes are not necessary, and I will declare my local variables before a loop
    1 point
  21. "'''([^']+)'''", "*'$1'*" [^'] means: any character except a single quote + means: one or more times So this matches everything between the triple quotes like ''' 123 ''' and replace it with *' 123 '* (using *'$1'*).
    1 point
  22. sorry , i did not got what you said clearly. this my way in your case : Local $sStr = "a ''' 123 ''' b ''' 234 ''' c" $out = StringRegExpReplace($sStr,"\'{3}\s(\d+)\s\'{3}","\*\' $1 \'\*") ConsoleWrite($out)
    1 point
  23. Exit test2() Func test2() ; my solution. ..thanks to @quymao2 for the enlightment =) Local $sStr = "a ''' 123 ''' b ''' 234 ''' c" While StringInStr($sStr, "'''") $sStr = StringReplace($sStr, "'''", "*'", 1) $sStr = StringReplace($sStr, "'''", "'*", 1) WEnd ConsoleWrite(@CRLF & $sStr & @CRLF & @CRLF) ; ' a *' 123 *' b ' EndFunc ; v2 Exit test() Func test() ;~ Local $sStr = "a ''' 123 ''' b" ; a *' 123 '* b ; good Local $sStr = "a ''' 123 ''' b ''' 234 ''' c" ; a *' 123 *' b '* 234 '* c ; =(.... ConsoleWrite(@CRLF & StringReplace(StringLeft($sStr, StringLen($sStr)/2+1), "'''", "*'") & StringReplace(StringRight($sStr, StringLen($sStr)/2), "'''", "'*") & @CRLF & @CRLF) ; ' a *' 123 *' b ' EndFunc yes, but if I want to do a longer string ... @quymao2 gave me "a north" ( as Cubans say ), hence this solution
    1 point
  24. Exit test() Func test() Local $sStr = "a ''' 123 ''' b" ConsoleWrite(@CRLF & StringReplace(StringLeft($sStr, StringLen($sStr)/2+1), "'''", "*'") & StringReplace(StringRight($sStr, StringLen($sStr)/2), "'''", "'*") & @CRLF & @CRLF) ; ' a *' 123 *' b ' EndFunc Not pretty but works 😛
    1 point
  25. Ok. This is your "Program" #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- ; Running the below code works because passing @SW_SHOW to the show flag parameter will launch the application with a visible GUI ; Change "@SW_SHOW" to "@SW_HIDE", and the script no longer works. $enabled = False Run ( "C:\Program Files (x86)\Program\Program.exe", @SystemDir, @SW_SHOW ) WinWait ( "Program", "OK" ) WinActivate ( "Program", "OK" ) WinWaitActive ( "Program", "OK" ) If ControlCommand ( "Program", "OK", "[CLASS:Button; INSTANCE:3]", "IsChecked", "" ) = 0 Then $enabled = False ControlClick ( "Program", "OK", "[CLASS:Button; INSTANCE:3]" ) Else $enabled = True EndIf ControlClick ( "Program", "OK", "[CLASS:Button; INSTANCE:4]" ) #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ;~ HotKeySet("{ESC}", "Terminate") #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Program", 400, 100, 100, 100) $Button1 = GUICtrlCreateButton("OK", 8, 8, 75, 25) $Checkbox1 = GUICtrlCreateCheckbox("HideMe", 100, 10, 95, 17) $Checkbox2 = GUICtrlCreateCheckbox("Bttn3", 200, 10, 95, 17) $Button2 = GUICtrlCreateButton("Close", 300, 8, 75, 25) $Edit1 = GUICtrlCreateEdit("OK" & @CRLF & "You can close this from the tray if you must", 8, 38, 400 - 16, 100 - 38 - 8) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### ToolTip((GUICtrlRead($Checkbox2) = 1 ? "GUI_CHECKED" : "UNCHECKED"), 50, 50, "Program") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $Button2 Terminate() Case $Checkbox2 ToolTip((GUICtrlRead($Checkbox2) = 1 ? "GUI_CHECKED" : "UNCHECKED"), 50, 50, "Program") Case $Checkbox1 WinSetState("Program", "OK", @SW_HIDE) EndSwitch WEnd Func Terminate() GUIDelete() Exit EndFunc ;==>Terminate and this is what is missing from your code Opt("WinDetectHiddenText", 1) And !, thanks for the help file review Edit: do add a timeout If Not WinWait ( "Program", "OK", 5 ) Then Exit 5 ; 5 secs should be enough I guess
    1 point
  26. In your original string you have three ''', but in seaching parameter of String Replace, you put only two '' :)) the correct format is must be ConsoleWrite(@CRLF & StringReplace($sStr, "'''", "*") & @CRLF & @CRLF) ; ' a *' 123 *' b '
    1 point
  27. ..and on related news: "Windows 7 usage is going up! Windows 11 usage went down!" (video)
    1 point
  28. Me too few years ago. That's why I use StringFormat() nowadays to avoid concatination by & between strings and variables. RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $MyPath & 'Open the Angle Finder Program.au3"') ; versus RunWait(StringFormat('"%s" /AutoIt3ExecuteScript "%sOpen the Angle Finder Program.au3"', @AutoItExe, $MyPath)) ; My personal conclusion: ; Always use single quotes instead of double quotes. ; Concat with StringFormat(), especially with large string <==> variable combinations. It might be detrimental to readability at first, but after a short period of getting used to it, it increases it and prevents precisely such errors. Best regards Sven
    1 point
  29. Wizardry

    Use path as a variable

    Many Thanks donnyh13, this solved the problem. I must have looked at it too long to miss those quote marks. Jim
    1 point
  30. Understood, thanks. Alright. I cannot reproduce it, because I don't use Win7 anymore and I also don't want to setup a VM for it. But maybe @argumentum wants to check it on a Win7 machine. I say so, because I believe you (argumentum) often works with VMs and maybe already have a Win7 one processed? Besides that, I think more and more extensions will or already have ended the support for Win7, because it's might be more a matter of the Node.js runtime in the background for VSCode. Anyway, interesting finding - it is surely documented in the VSCode release notes anywhere (I think). -------------- Kind of off-topic, but important anyway: Best regards Sven
    1 point
  31. Yes, I believe so too. I like it for working on. It's predictable and works well for me, so I stick with it. It's nothing important, I just wanted to confirm that it really isn't compatible anymore, and not just a bug on my end. I am getting used to stuff getting advanced past working on W7. One day, it will get retired I suppose . Thanks for the help @SOLVE-SMART. Much appreciated.
    1 point
  32. Hi @donnyh13 👋 , could you please provide more information about your VSCode? Simply open the command palatte and type: "> Help: About". For example my current version on Win10 is: Version: 1.104.2 (user setup) Commit: e3a5acfb517a443235981655413d566533107e92 Date: 2025-09-24T11:21:37.073Z Electron: 37.3.1 ElectronBuildId: 12404162 Chromium: 138.0.7204.235 Node.js: 22.18.0 V8: 13.8.258.31-electron.0 OS: Windows_NT x64 10.0.19045 I think so, yes. To you really want to stick with Win7 or you're talking about a VM? I strongly believe the VSCode AutoIt Extension will not the only one which will lead to problems on such a old system, right 😅 . Best regards Sven
    1 point
  33. bladem2003

    Custom Tabs

    I have been creating my custom tabs with a little help from MattyD I would be happy to receive suggestions for improvement. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/mo #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <Array.au3> #include <Misc.au3> #include <WinAPISysWin.au3> #include <StructureConstants.au3> #include <GuiTab.au3> #include <ListViewConstants.au3> #include <GuiListView.au3> #include <GuiScrollBars.au3> #include <ScrollBarsConstants.au3> Global $aTabBarItems[1][10], $hTabbar $hGui = GUICreate("", 800, 450) GUISetBkColor(0x3f3f3f, $hGui) $hTabbar = _TabInit($hGui, 10, 20, 725, 22, 0x3f3f3f) $hButtonLeftScrollTabs = GUICtrlCreateLabel("<", 720 + 25, 20, 22, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor($hButtonLeftScrollTabs, 0x252525) GUICtrlSetColor(-1, 0xffffff) GUICtrlSetFont(-1, 11, 800) $hButtonRightScrollTabs = GUICtrlCreateLabel(">", 744 + 25, 20, 22, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor(-1, 0x252525) GUICtrlSetColor(-1, 0xffffff) GUICtrlSetFont(-1, 11, 800) $iTab = GUICtrlCreateTab(10, 33, 700, 400) GUICtrlSetState($iTab, $GUI_HIDE) GUICtrlCreateLabel("", 10, 43, 725, 400) GUICtrlSetBkColor(-1, 0x4f4f4f) GUICtrlSetState(-1, $gui_disable) GUISetState(@SW_SHOW, $hGui) GUISetState(@SW_SHOW, $hTabbar) For $t = 1 To 20 _TabAdd($hTabbar, $iTab, "Tab " & $t) Next While 1 Sleep(10) $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit For $t = 1 To $aTabBarItems[0][0] If $t > $aTabBarItems[0][0] Then ExitLoop If $msg = $aTabBarItems[$t][1] Or $msg = $aTabBarItems[$t][2] Then _GuiCtrlTabButtonSetActive($aTabBarItems[$t][1]) _GUICtrlTab_ActivateTab($iTab, $t - 1) EndIf If $msg = $aTabBarItems[$t][4] Then _GuiCtrlTabButtonDelete($aTabBarItems[$t][1]) EndIf Next ;----simple mouse hover----------------------------- $posCusorMenu = GUIGetCursorInfo($hTabbar) $iCtrlIDMenu = $posCusorMenu[4] For $t = 1 To $aTabBarItems[0][0] If $t > $aTabBarItems[0][0] Then ExitLoop If $iCtrlIDMenu = $aTabBarItems[$t][4] And $aTabBarItems[$t][16] = 0 Then GUICtrlSetColor($aTabBarItems[$t][4], 0xC40A0A) $aTabBarItems[$t][16] = 1 ElseIf Not $iCtrlIDMenu = $aTabBarItems[$t][4] Or $iCtrlIDMenu = $aTabBarItems[$t][1] Or $iCtrlIDMenu = $aTabBarItems[$t][2] Then If $aTabBarItems[$t][16] = 1 Then GUICtrlSetColor($aTabBarItems[$t][4], 0xffffff) $aTabBarItems[$t][16] = 0 EndIf EndIf Next ;-------------------------------------------------- If $msg = $hButtonRightScrollTabs Then Sleep(100) If _IsPressed("01") Then While _IsPressed("01") _NextTab($hTabbar) Sleep(100) WEnd Else _NextTab($hTabbar) EndIf EndIf If $msg = $hButtonLeftScrollTabs Then Sleep(100) If _IsPressed("01") Then While _IsPressed("01") _PreviewsTab($hTabbar) Sleep(100) WEnd Else _PreviewsTab($hTabbar) EndIf EndIf WEnd ;----NEW TAB----------------------------------------------------------------------------------------------------------------------------- Func _TabInit($hParent, $iX, $iY, $iW, $ih, $x_BKcolor) $h_Gui_Tab = GUICreate("", $iW, $ih, $iX, $iY, $WS_POPUP, BitOR($WS_EX_TRANSPARENT, $WS_EX_CONTROLPARENT, $WS_EX_MDICHILD), $hParent) GUISetState(@SW_HIDE, $h_Gui_Tab) _GUIScrollBars_Init($h_Gui_Tab, 400) _GUIScrollBars_ShowScrollBar($h_Gui_Tab, $SB_VERT, False) GUISetBkColor($x_BKcolor, $h_Gui_Tab) GUISwitch($hParent) Return $h_Gui_Tab EndFunc ;==>_TabInit Func _TabAdd($h_Tabbar, $i_Tab, $s_txt) GUISwitch($h_Tabbar) Local $iCountTabButtons = $aTabBarItems[0][0], $iWtB = 120, $iMinusCloseX = 10, $iX = 1 ReDim $aTabBarItems[UBound($aTabBarItems) + 1][20] $iRetSize = _GetTextWidth($s_txt, 9, 500) + 10 If $iRetSize > 0 Then $iWtB = $iRetSize EndIf GUISwitch($h_Tabbar) $BG_Color = 0x2E2E2E $LineColorDown = 0x7160E8 If $iCountTabButtons > 0 Then $iX = $aTabBarItems[$iCountTabButtons][10] + $aTabBarItems[$iCountTabButtons][12] + 1 EndIf $i_LabelTabBase = GUICtrlCreateLabel("", $iX, 0, $iWtB + $iMinusCloseX, 22, 0) GUICtrlSetBkColor(-1, 0xff0000) GUICtrlSetBkColor(-1, $BG_Color) GUICtrlSetState(-1, $gui_disable) $i_LabelTabTxt = GUICtrlCreateLabel($s_txt, $iX, 1, $iWtB, 18, BitOR($SS_CENTER, $SS_CENTERIMAGE), 0) GUICtrlSetFont(-1, 9, 500) GUICtrlSetColor(-1, 0xaaaaaa) GUICtrlSetBkColor(-1, 0x00ff00) GUICtrlSetBkColor(-1, $BG_Color) $i_LabelBtnTabBottom = GUICtrlCreateLabel("", $iX, 19, $iWtB + $iMinusCloseX, 3, BitOR($SS_CENTER, $SS_CENTERIMAGE), 0) GUICtrlSetBkColor(-1, $LineColorDown) $i_LabelTabBtnX = GUICtrlCreateLabel('', $iX + $iWtB + 1, 1, $iMinusCloseX - 2, $iMinusCloseX - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE), 0) GUICtrlSetFont($i_LabelTabBtnX, (($iMinusCloseX + 2) / 2), 100, 0, "Segoe MDL2 Assets", 0) GUICtrlSetData($i_LabelTabBtnX, ChrW(0xEF2C)) GUICtrlSetColor(-1, 0xffffff) GUICtrlSetBkColor(-1, $BG_Color) GUISwitch(_WinAPI_GetParent($h_Tabbar)) ;GUISwitch($hGui) $i_TabItem = GUICtrlCreateTabItem("tab " & $iCountTabButtons) GUICtrlCreateLabel($s_txt, 350, 200, 100, 25) GUICtrlSetFont(-1, 16) GUICtrlSetColor(-1, 0xffffff) GUICtrlCreateTabItem("") $iCountTabButtons += 1 $aTabBarItems[0][0] = $iCountTabButtons $aTabBarItems[$iCountTabButtons][0] = $h_Tabbar $aTabBarItems[$iCountTabButtons][1] = $i_LabelTabBase $aTabBarItems[$iCountTabButtons][2] = $i_LabelTabTxt $aTabBarItems[$iCountTabButtons][3] = $i_LabelBtnTabBottom $aTabBarItems[$iCountTabButtons][4] = $i_LabelTabBtnX $aTabBarItems[$iCountTabButtons][5] = $BG_Color $aTabBarItems[$iCountTabButtons][6] = $LineColorDown $aTabBarItems[$iCountTabButtons][7] = 0x3D3D3D ; selected color $aTabBarItems[$iCountTabButtons][10] = $iX $aTabBarItems[$iCountTabButtons][11] = 0 $aTabBarItems[$iCountTabButtons][12] = $iWtB + $iMinusCloseX $aTabBarItems[$iCountTabButtons][13] = 22 $aTabBarItems[$iCountTabButtons][15] = 1 $aTabBarItems[$iCountTabButtons][16] = 0 ; hover $aTabBarItems[$iCountTabButtons][17] = $i_TabItem _GuiCtrlTabButtonSetActive($i_LabelTabBase) _TabSetNewScrollMaxPos($hTabbar) _GoToTabButton($hTabbar, $iCountTabButtons) Return $i_LabelTabBase EndFunc ;==>_TabAdd Func _GuiCtrlTabButtonDelete($i_Button) $iFind = _ArraySearch($aTabBarItems, $i_Button, 0, 0, 0, 2, 1, 1) If @error = 0 Then $iFirstVisible = _GetFirstVisible($hTabbar) _GUIScrollBars_SetScrollInfoPos($aTabBarItems[$iFind][0], $SB_HORZ, 0) ; reset scroll pos !!!! $aPosControlDelete = ControlGetPos($aTabBarItems[$iFind][0], "", $aTabBarItems[$iFind][1]) GUICtrlDelete($aTabBarItems[$iFind][1]) GUICtrlDelete($aTabBarItems[$iFind][2]) GUICtrlDelete($aTabBarItems[$iFind][3]) GUICtrlDelete($aTabBarItems[$iFind][4]) GUICtrlDelete($aTabBarItems[$iFind][17]) _ArrayDelete($aTabBarItems, $iFind) $aTabBarItems[0][0] = UBound($aTabBarItems, 1) - 1 $iNewXPos = $aPosControlDelete[0] For $t = $iFind To $aTabBarItems[0][0] GUICtrlSetPos($aTabBarItems[$t][1], $iNewXPos) GUICtrlSetPos($aTabBarItems[$t][2], $iNewXPos) GUICtrlSetPos($aTabBarItems[$t][3], $iNewXPos) $aPosControl = ControlGetPos($aTabBarItems[$t][0], "", $aTabBarItems[$t][1]) GUICtrlSetPos($aTabBarItems[$t][4], $aPosControl[0] + $aPosControl[2] - 10) $aTabBarItems[$t][10] = _GetGuiScrollStartXpoint($aTabBarItems[$t][0]) + $iNewXPos $iNewXPos = $aPosControl[0] + $aPosControl[2] + 1 Next If $aTabBarItems[0][0] > 0 Then _TabSetNewScrollMaxPos($hTabbar) _GoToTabButton($hTabbar, $iFirstVisible) EndIf EndIf EndFunc ;==>_GuiCtrlTabButtonDelete Func _GuiCtrlTabButtonSetActive($h_TabButton) $iFind = _ArraySearch($aTabBarItems, $h_TabButton, 0, 0, 0, 2, 1, 1) ;, 1) If @error = 0 Then For $h = 1 To $aTabBarItems[0][0] If $aTabBarItems[$h][15] = 1 Then GUICtrlSetBkColor($aTabBarItems[$h][1], $aTabBarItems[$h][5]) GUICtrlSetBkColor($aTabBarItems[$h][2], $aTabBarItems[$h][5]) GUICtrlSetColor($aTabBarItems[$h][2], 0xcccccc) GUICtrlSetBkColor($aTabBarItems[$h][4], $aTabBarItems[$h][5]) GUICtrlSetBkColor($aTabBarItems[$h][3], $aTabBarItems[$h][5]) GUICtrlSetBkColor($aTabBarItems[$h][4], $aTabBarItems[$h][5]) $aTabBarItems[$h][15] = 0 EndIf Next GUICtrlSetBkColor($aTabBarItems[$iFind][1], $aTabBarItems[$iFind][7]) GUICtrlSetBkColor($aTabBarItems[$iFind][2], $aTabBarItems[$iFind][7]) GUICtrlSetColor($aTabBarItems[$iFind][2], 0xffffff) GUICtrlSetBkColor($aTabBarItems[$iFind][3], $aTabBarItems[$iFind][6]) GUICtrlSetBkColor($aTabBarItems[$iFind][4], 0x55555) $aTabBarItems[$iFind][15] = 1 EndIf EndFunc ;==>_GuiCtrlTabButtonSetActive Func _GetTextWidth($s_Text, $i_FontSize, $i_FontWidth) Local $iX, $idListview $h_GuiGetTextWidth = GUICreate("ListView Approximate View Width", 10, 10, -100, 0) $idListview = GUICtrlCreateListView("", 2, 2, 394, 268) GUICtrlSetFont(-1, $i_FontSize, $i_FontWidth) GUISetState(@SW_HIDE) _GUICtrlListView_InsertColumn($idListview, 0, "Column 1", 100) _GUICtrlListView_AddItem($idListview, $s_Text) GUICtrlSendMsg($idListview, $LVM_SETCOLUMNWIDTH, 0, -1) ; $LVSCW_AUTOSIZE $iX = _GUICtrlListView_GetColumnWidth($idListview, 0) GUIDelete($h_GuiGetTextWidth) Return $iX EndFunc ;==>_GetTextWidth Func _TabSetNewScrollMaxPos($hWndScrollGui, $i_ShowWindow = 0) Local $iXpos = 0 ; $iXpos = $aTabBarItems[UBound($aTabBarItems) - 1][10] + $aTabBarItems[UBound($aTabBarItems) - 1][12] + 2 GUISetState(@SW_LOCK, $hWndScrollGui) _GUIScrollBars_SetScrollInfoPos($hWndScrollGui, $SB_HORZ, 0) ; reset scroll pos !!!! $iMaxScrollPos = _GetScrollInfoMax($hWndScrollGui, $iXpos + 2) _GUIScrollBars_SetScrollInfoMax($hWndScrollGui, $SB_HORZ, $iMaxScrollPos) _GUIScrollBars_SetScrollInfoMin($hWndScrollGui, $SB_HORZ, 0) If _GUIScrollBars_GetScrollBarXYLineButton($hWndScrollGui, $OBJID_HSCROLL) > 0 Or _GUIScrollBars_GetScrollBarXYLineButton($hWndScrollGui, $OBJID_VSCROLL) > 0 Then _GUIScrollBars_ShowScrollBar($hWndScrollGui, $SB_HORZ, False) _GUIScrollBars_ShowScrollBar($hWndScrollGui, $SB_VERT, False) EndIf GUISetState(@SW_UNLOCK, $hWndScrollGui) If $i_ShowWindow = 1 Then GUISetState(@SW_SHOWNA, $hWndScrollGui) $aPosTab = WinGetPos($hWndScrollGui) If $iXpos <= $aPosTab[2] Then GUICtrlSetState($hButtonLeftScrollTabs, $GUI_HIDE) GUICtrlSetState($hButtonRightScrollTabs, $GUI_HIDE) Else GUICtrlSetState($hButtonLeftScrollTabs, $GUI_SHOW) GUICtrlSetState($hButtonRightScrollTabs, $GUI_SHOW) EndIf EndFunc ;==>_TabSetNewScrollMaxPos Func _NextTab($hWndScrollGui) $iStartXpoint = _GetGuiScrollStartXpoint($hWndScrollGui) For $t = 1 To $aTabBarItems[0][0] If $iStartXpoint + 10 < $aTabBarItems[$t][10] Then _GoToTabButton($hWndScrollGui, $t) ExitLoop EndIf Next EndFunc ;==>_NextTab Func _PreviewsTab($hWndScrollGui) $iStartXpoint = _GetGuiScrollStartXpoint($hWndScrollGui) If $iStartXpoint <= 0 Then Return For $t = $aTabBarItems[0][0] To 1 Step -1 If $aTabBarItems[$t][10] < $iStartXpoint - 10 Then _GoToTabButton($hWndScrollGui, $t) ExitLoop EndIf Next EndFunc ;==>_PreviewsTab Func _GoToTabButton($hWndScrollGui, $i_Tab) If $i_Tab > $aTabBarItems[0][0] Then Return _GUIScrollBars_SetScrollInfoPos($hWndScrollGui, $SB_HORZ, Floor(($aTabBarItems[$i_Tab][10] / _GetGuiScrollCharWidth($hWndScrollGui)))) EndFunc ;==>_GoToTabButton Func _GetScrollInfoMax($h_Gui, $iWith) Local $aCall = DllCall("user32.dll", "handle", "GetDC", "hwnd", $h_Gui) $hDC = $aCall[0] Local $tTEXTMETRIC = DllStructCreate($tagTEXTMETRIC) DllCall("gdi32.dll", "bool", "GetTextMetricsW", "handle", $hDC, "struct*", $tTEXTMETRIC) Local $iXAmount = DllStructGetData($tTEXTMETRIC, "tmAveCharWidth") Local $iYAmount = DllStructGetData($tTEXTMETRIC, "tmHeight") + DllStructGetData($tTEXTMETRIC, "tmExternalLeading") DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $h_Gui, "handle", $hDC) $iClW = _WinAPI_GetClientWidth($h_Gui) $iFullW = $iWith $iPageW = _GUIScrollBars_GetScrollInfoPage($h_Gui, $SB_HORZ) $iMaxValRng = Round(($iFullW - $iClW) / $iXAmount) $iMaxScrollPos = $iMaxValRng + ($iPageW - 1) If $iMaxScrollPos < 0 Then $iMaxScrollPos = 0 Return $iMaxScrollPos EndFunc ;==>_GetScrollInfoMax Func _GetFirstVisible($hWndScrollGui) $iStartXpoint = _GetGuiScrollStartXpoint($hWndScrollGui) For $t = 1 To $aTabBarItems[0][0] If $iStartXpoint + 10 > $aTabBarItems[$t][10] And $iStartXpoint + 10 < $aTabBarItems[$t][10] + $aTabBarItems[$t][12] Then Return $t ExitLoop EndIf Next EndFunc ;==>_GetFirstVisible Func _GetGuiScrollStartXpoint($hWndScrollGui) $iGetScrollPos = _GUIScrollBars_GetScrollPos($hWndScrollGui, $SB_HORZ) $iH_Scroll_Pos = $iGetScrollPos * _GetGuiScrollCharWidth($hWndScrollGui) Return $iH_Scroll_Pos EndFunc ;==>_GetGuiScrollStartXpoint Func _GetGuiScrollCharWidth($hWndScrollGui) Local $tTEXTMETRIC = DllStructCreate($tagTEXTMETRIC) ; Determine text size Local $hDC = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hWndScrollGui) If Not @error Then $hDC = $hDC[0] DllCall("gdi32.dll", "bool", "GetTextMetricsW", "handle", $hDC, "ptr", DllStructGetPtr($tTEXTMETRIC)) If @error Then $iError = @error $iExtended = @extended DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWndScrollGui, "handle", $hDC) Return SetError($iError, $iExtended, -2) EndIf DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWndScrollGui, "handle", $hDC) Else Return SetError(@error, @extended, -1) EndIf Return DllStructGetData($tTEXTMETRIC, "tmAveCharWidth") EndFunc ;==>_GetGuiScrollCharWidth
    1 point
  34. WildByDesign

    DwmColorBlurMica

    You're welcome. I'm glad it's working. You can apply the mica first before showing the window. But the removal of the caption seems to have to be after showing the window. ; re-apply Mica since it is lost ApplyMica($GUI_WindowContext) GUISetState(@SW_SHOWNORMAL, $GUI_WindowContext) ; removing $WS_CAPTION __WinAPI_Set_Window_Style($GUI_WindowContext, $WS_CAPTION, False, False) This above also works. It might actually be better to prevent any possibility of flicker with the GUI context menu.
    1 point
  35. I did it as an exercise, (learning process), and since it concerns your work, I thought I would share my findings.
    1 point
  36. very good @ioa747, thank you.
    1 point
  37. For me it works. Try GUISetBkColor(0xFFFF00) to see if it really loses transparency! The background should be yellow otherwise transparency lost.
    1 point
  38. I've tried to simply follow the rules that Tidy uses when it comes to indentation. In that case neither is perfect as this is the result with my tidy settings: Func _Test1() ;~ Local $123 ;# ;# ; A Comment ;# ;# EndFunc ;==>_Test1 Func _Test2() ;~ Local $123 ;# ; An inline Comment ;# EndFunc ;==>_Test2
    1 point
  39. installing Japanese too because Greek was too easy 🤣 I think we call those two functions and recreate the user's string from that but as I am right now ( the headache ), I don't know if it makes sense to go that way 🤷‍♂️ Edit: Done | 0 - date and/or time. | 1 - long date, regional settings. | 2 - short date, regional settings. | 3 - time, regional settings. | 4 - time 24-hour (hh:mm). | 5 - time 24-hour (hh:mm:ss). | 6 - time AM/PM (hh:mm tt). | 7 - time AM/PM (hh:mm:ss tt). | 2025/09/28 11:40:29 | 2025年9月28日 | 2025/09/28 | 11:40:29 | 11:40 | 11:40:29 | 11:40 午前 | 11:40:29 午前 | 2025/12/31 11:59:59 | 2025年12月31日 | 2025/12/31 | 11:59:59 | 11:59 | 11:59:59 | 11:59 午前 | 11:59:59 午前 | 2025/12/31 23:59:59 | 2025年12月31日 | 2025/12/31 | 23:59:59 | 23:59 | 23:59:59 | 11:59 午後 | 11:59:59 午後 | 2025/12/31 11:59:59 | 2025年12月31日 | 2025/12/31 | 11:59:59 | 11:59 | 11:59:59 | 11:59 午前 | 11:59:59 午前 | 2025/12/31 23:59:59 | 2025年12月31日 | 2025/12/31 | 23:59:59 | 23:59 | 23:59:59 | 11:59 午後 | 11:59:59 午後 So I guess Japanese has a simple format, I guess. I installed it because MSDN say: "g, gg Period/era string formatted as specified by the CAL_SERASTRING value. The "g" and "gg" format pictures in a date string are ignored if there is no associated era or period string." and Japanese should have these ? "Year represented by a full four or five digits, depending on the calendar used. Thai Buddhist and Korean calendars have five-digit years. The "yyyy" pattern shows five digits for these two calendars, and four digits for all other supported calendars. Calendars that have single-digit or two-digit years, such as for the Japanese Emperor era, are represented differently. A single-digit year is represented with a leading zero, for example, "03". A two-digit year is represented with two digits, for example, "13". No additional leading zeros are displayed." We could use one user from every country to make sure. ..or we'll add it in a next version. I don't know any of these languages and cultures and I'll guess wrong. So I'll stop installing more VMs. "Hindsight is 20/20"
    1 point
  40. The laughter was from surprise that you mentioned "Nominative Case vs. Genitive Case" my other question is (because you are referring to a single string for the date and time) now we get the date from _WinAPI_GetDateFormat($iLcid, $tSystem, 0, $sTempDate) and the time from the time from _WinAPI_GetTimeFormat($iLcid, $tSystem, 0, $sTempTime) so we have two strings $sTempDate, and $sTempTime If we had them in a single string $sTempDateTime, is there a function to give us the date and time? Or would we have to find where to split it , to call _WinAPI_GetDateFormat , and _WinAPI_GetTimeFormat ? Edit: For the headache, I would tell you to take paracetamol, but I heard that it causes autism.
    1 point
  41. ...not really. Say "dddd, d' de 'MMMM' de 'yyyy' a las 'hh:mm tt|am|pm" vs "dddd, d' de 'MMMM' de 'yyyy' a las 'HH:mm tt|am|pm" One is 12 hour and the other 24 hour as per M$: "In the format types, the letters "m", "s", and "t" must be lowercase, and the letter "h" must be lowercase to denote the 12-hour clock or uppercase ("H") to denote the 24-hour clock." So if we follow M$ notation, it can all be resolved with just the custom string, and send the users to read MSDN's date and time rules. $vType would be a number 0 to 7 and if a string ( "dddd, d' de 'MMMM' de 'yyyy' a las 'HH:mm tt|am|pm" ), then we chop that up and rebuild it from the values from the _WinAPI_Get*Format() functions. It makes sense in my head. But I'd have to code it to know that it is possible. Also, I'd have to see for myself the "Σεπτεμβρίου vs. Σεπτέμβριος". See if the OS returns the proper string for "Nominative Case vs. Genitive Case" ( of which am clueless ).
    1 point
  42. ioa747, "I hope I enlightened you..." Yes, yo did! Thank yo very much! Thus far, the updated button-to-menu script appears to be working as it should. I have a few more tests to run and will keep you updated. However, as always, ioa747, your assistance has been - and indeed, is, an invaluable source of to me. Thank you so very much. PS: I will mark your solution(s) as "solved"...again!
    1 point
  43. ⚽ _DateTimeFormatEx_vBeta4a
    1 point
  44. I solved such problems by putting Greek here, and checking it, for UTF https://www.autoitscript.com/forum/topic/212666-perhaps-output-encoding-error-in-au3checkexe/#comment-1540626
    1 point
  45. This happens because, while you declared GUISetOnEvent($GUI_EVENT_CLOSE, "_CloseForm") in the DisplayLabel for the $sDisplayHotKeyOption GUI, you did not put the Event handler in _CloseForm add it, as below, and then it will Close too Func _CloseForm() Switch @GUI_WinHandle Case $hMainGUI Exit Case $sLabelA, $sLabelB, $sDisplayHotKeyOption GUIDelete(@GUI_WinHandle) EndSwitch EndFunc ;==>_CloseForm it's more of a matter of order, and normal flow. When you call WinClose what does it do? it sends a message to the window to close, and the GUI calls $GUI_EVENT_CLOSE, and calls the function you declared in GUISetOnEvent. In our case _CloseForm() In case you had a flow that after calling the GUI, activated another GUI, or a button, you would put them in the _CloseForm() function e.g. Case $sDisplayHotKeyOption GUIDelete($sDisplayHotKeyOption) GUICtrlSetState($sCol1Row1, $GUI_ENABLE) and it would follow the flow With GUIDelete, the flow will change, and you should put them there when you call GUIDelete I hope I enlightened you
    1 point
  46. Come checkout my Metro GUI designer. User Interface Builder
    1 point
×
×
  • Create New...