Jump to content

AutoIt Snippets


Chimaera
 Share

Recommended Posts

1 hour ago, SOLVE-SMART said:

like well defined names for variables, functions (methods), classes etc

yep you're right it makes a world of difference in terms of code readability, especially in conditional statements, especially for someone relatively new to coding (little over a year in). I have a whole bunch of small snippets just for readability:

Func _ArrayEnd(ByRef $thisarray)

    Local $ReturnValue = 0
    
    $ReturnValue = UBound($thisarray) - 1

    Return $ReturnValue

EndFunc

 

Func _ArraySize(ByRef $thisarray)

    Local $ReturnValue = 0
    
    $ReturnValue = UBound($thisarray)

    Return $ReturnValue

EndFunc

 

Func _ArrayDeleteFirstRow(ByRef $thisarray)
    
    _ArrayDelete($thisarray, 0)

EndFunc

 

Func _ArraySearchFound($arraysearchresult)

    Local $ReturnValue = 0
    
    If $arraysearchresult <> -1 Then $ReturnValue = 1
    
    Return $ReturnValue

EndFunc

 

Func _ArraySearchNotFound($arraysearchresult)

    Local $ReturnValue = 0
    
    If $arraysearchresult = -1 Then $ReturnValue = 1
    
    Return $ReturnValue

EndFunc

 

Func _ProcessExists($thisprocessid)

    Local $ReturnValue = 0
    
    If $thisprocessid <> -1 Then $ReturnValue = 1
    
    Return $ReturnValue

EndFunc

 

Func _ProcessDoesntExist($thisprocessid)

    Local $ReturnValue = 0
    
    If $thisprocessid = -1 Then $ReturnValue = 1
    
    Return $ReturnValue

EndFunc

etc etc :)
oh and I know I have those extra lines $ReturnValue = 0 etc that's because I've been forcing myself to remember to use SESE whenever possible :)

Link to comment
Share on other sites

  • 4 weeks later...

Async HTTP Requests

I couldn't find the thread for "Async HTTP requests" and the corresponding code snippet, so I rewrote it.

This code snippet sents Async GET requests to an array of URLs, and returns response code, response headers and response body as an array.

 

#include-once
#include <Array.au3>

Local $HTTP_METHOD = "GET"
Local $ASYNC_REQUEST = True
Local $aURLs = ["https://en.wikipedia.org", "https://en.wikipedia.org/wiki/Forest_raven", "https://en.wikipedia.org/wiki/Stanley_Bruce", "https://en.wikipedia.org/wiki/Beatlemania"]
Local $nTotalThreads = UBound($aURLs)
Local $aRequestHandles[$nTotalThreads]
Local $aThreadStatus[$nTotalThreads]
Local $nCompletedThreads = 0

_ArrayColInsert($aURLs, 1) ; stores response code
_ArrayColInsert($aURLs, 1) ; stores response headers
_ArrayColInsert($aURLs, 1) ; stores response text

For $i = 0 To $nTotalThreads - 1
    $aRequestHandles[$i] = ObjCreate("WinHttp.WinHttpRequest.5.1")
    $aRequestHandles[$i].Open($HTTP_METHOD, $aURLs[$i][0], $ASYNC_REQUEST)
    $aRequestHandles[$i].Send()
Next
Do
    For $i = 0 To $nTotalThreads - 1
        If $aThreadStatus[$i] = 0 And $aRequestHandles[$i].WaitForResponse(0) = True Then
            $aURLs[$i][1] = $aRequestHandles[$i].Status
            $aURLs[$i][2] = $aRequestHandles[$i].GetAllResponseHeaders
            $aURLs[$i][3] = $aRequestHandles[$i].ResponseText
            $aThreadStatus[$i] = 1
            $nCompletedThreads += 1
        EndIf
    Next
Until $nCompletedThreads = $nTotalThreads

_ArrayDisplay($aURLs)

Explanation:

First, we define variables:

$HTTP_METHOD is set to "GET" as the request method.
$ASYNC_REQUEST is set to True for asynchronous processing.
$aURLs is an array of 4 URLs to be requested.
$nTotalThreads is set to the upper bound of $aURLs, which is the number of elements in the array.
$aRequestHandles is an array to store the request handles, with a length of $nTotalThreads.
$aThreadStatus is an array to store the status of each thread, with a length of $nTotalThreads.
$nCompletedThreads is a counter for the completed threads, which is initialized to 0.

The next 3 lines insert 3 new columns in $aURLs to store the response status code, headers, and text.

The next block of code performs a loop from 0 to $nTotalThreads - 1. Inside the loop, an object is created from the "WinHttp.WinHttpRequest.5.1" class and assigned to $aRequestHandles[$i]. The object's Open method is then called, with arguments $HTTP_METHOD, $aURLs[$i][0], and $ASYNC_REQUEST, to initiate the request. The object's Send method is then called to send the request.

The next block of code is a do-until loop that waits until all threads have completed.

Inside the loop, a nested for loop is performed from 0 to $nTotalThreads - 1. If a thread is not yet completed (indicated by $aThreadStatus[$i] being equal to 0) and has received a response (indicated by $aRequestHandles[$i].WaitForResponse(0) being equal to True), then the response status code, headers, and text are stored in $aURLs[$i][1], $aURLs[$i][2], and $aURLs[$i][3] respectively.

The thread status is then set to completed (indicated by $aThreadStatus[$i] being equal to 1) and the $nCompletedThreads counter is incremented.

The last line calls the _ArrayDisplay function with $aURLs as an argument, which displays the contents of the array.

 

Link to comment
Share on other sites

  • 2 weeks later...

I very offen wonders which values gives particular macro. For example: do I should use @AppDataDir or @LocalAppDataDir or @UserProfileDir


Here is my Show_Macro_Values.au3script:

ConsoleWrite('@AppDataCommonDir : ' & @AppDataCommonDir & @CRLF)
ConsoleWrite('@AppDataDir : ' & @AppDataDir & @CRLF)
ConsoleWrite('@AutoItExe : ' & @AutoItExe & @CRLF)
ConsoleWrite('@AutoItPID : ' & @AutoItPID & @CRLF)
ConsoleWrite('@AutoItVersion : ' & @AutoItVersion & @CRLF)
ConsoleWrite('@AutoItX64 : ' & @AutoItX64 & @CRLF)
ConsoleWrite('@CommonFilesDir : ' & @CommonFilesDir & @CRLF)
ConsoleWrite('@Compiled : ' & @Compiled & @CRLF)
ConsoleWrite('@ComputerName : ' & @ComputerName & @CRLF)
ConsoleWrite('@ComSpec : ' & @ComSpec & @CRLF)
ConsoleWrite('@CPUArch : ' & @CPUArch & @CRLF)
ConsoleWrite('@DesktopCommonDir : ' & @DesktopCommonDir & @CRLF)
ConsoleWrite('@DesktopDepth : ' & @DesktopDepth & @CRLF)
ConsoleWrite('@DesktopDir : ' & @DesktopDir & @CRLF)
ConsoleWrite('@DesktopHeight : ' & @DesktopHeight & @CRLF)
ConsoleWrite('@DesktopRefresh : ' & @DesktopRefresh & @CRLF)
ConsoleWrite('@DesktopWidth : ' & @DesktopWidth & @CRLF)
ConsoleWrite('@DocumentsCommonDir : ' & @DocumentsCommonDir & @CRLF)
ConsoleWrite('@FavoritesCommonDir : ' & @FavoritesCommonDir & @CRLF)
ConsoleWrite('@FavoritesDir : ' & @FavoritesDir & @CRLF)
ConsoleWrite('@HomeDrive : ' & @HomeDrive & @CRLF)
ConsoleWrite('@HomePath : ' & @HomePath & @CRLF)
ConsoleWrite('@HomeDrive : ' & @HomeDrive & @CRLF)
ConsoleWrite('@HomeShare : ' & @HomeShare & @CRLF)
ConsoleWrite('@LocalAppDataDir : ' & @LocalAppDataDir & @CRLF)
ConsoleWrite('@LogonDNSDomain : ' & @LogonDNSDomain & @CRLF)
ConsoleWrite('@LogonDomain : ' & @LogonDomain & @CRLF)
ConsoleWrite('@LogonServer : ' & @LogonServer & @CRLF)
ConsoleWrite('@MyDocumentsDir : ' & @MyDocumentsDir & @CRLF)
ConsoleWrite('@OSArch : ' & @OSArch & @CRLF)
ConsoleWrite('@OSBuild : ' & @OSBuild & @CRLF)
ConsoleWrite('@OSLang : ' & @OSLang & @CRLF)
ConsoleWrite('@OSServicePack : ' & @OSServicePack & @CRLF)
ConsoleWrite('@OSType : ' & @OSType & @CRLF)
ConsoleWrite('@OSVersion : ' & @OSVersion & @CRLF)
ConsoleWrite('@ProgramFilesDir : ' & @ProgramFilesDir & @CRLF)
ConsoleWrite('@ProgramsCommonDir : ' & @ProgramsCommonDir & @CRLF)
ConsoleWrite('@ProgramsDir : ' & @ProgramsDir & @CRLF)
ConsoleWrite('@ScriptFullPath : ' & @ScriptFullPath & @CRLF)
ConsoleWrite('@ScriptDir : ' & @ScriptDir & @CRLF)
ConsoleWrite('@ScriptName : ' & @ScriptName & @CRLF)
ConsoleWrite('@ScriptLineNumber : ' & @ScriptLineNumber & @CRLF)
ConsoleWrite('@StartMenuCommonDir : ' & @StartMenuCommonDir & @CRLF)
ConsoleWrite('@StartMenuDir : ' & @StartMenuDir & @CRLF)
ConsoleWrite('@StartupCommonDir : ' & @StartupCommonDir & @CRLF)
ConsoleWrite('@StartupDir : ' & @StartupDir & @CRLF)
ConsoleWrite('@SystemDir : ' & @SystemDir & @CRLF)
ConsoleWrite('@TempDir : ' & @TempDir & @CRLF)
ConsoleWrite('@UserName : ' & @UserName & @CRLF)
ConsoleWrite('@UserProfileDir : ' & @UserProfileDir & @CRLF)
ConsoleWrite('@WindowsDir : ' & @WindowsDir & @CRLF)

 

 

Edited by mLipok

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

@mLipok well done !
Some comments if I may :

* @HomeDrive is found twice in the script.

* @KBLayout, @MUILang could both be added.
After all, you choosed to indicate @OSLang and these 2 are a bit related.

* @WorkingDir should be added.
Of course it may change, but it's also the case with the existing @ScriptDir etc...

* I like your idea, not to follow the alphabetic order for the @Script... macros :
Help file : @ScriptDir, @ScriptFullPath, @ScriptLineNumber, @ScriptName (alphabetically)
mLipok  : @ScriptFullPath, @ScriptDir, @ScriptName, @ScriptLineNumber ("matryoshka dolls way") 

Great job starting this, bravo :thumbsup:

Link to comment
Share on other sites

  • 4 weeks later...

Very often we need to measure execution speed, thus came the idea of  FuncSpeedTest($sExecute)

Func FuncSpeedTest($sExecute)
    Local $hTimer = TimerInit()
    Execute($sExecute)
    ConsoleWrite($sExecute & " processed in: " & Round(TimerDiff($hTimer) / 1000, 3) & " seconds " & @LF)
EndFunc   ;==>FuncSpeedTest

Example1:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

FuncSpeedTest("_IfSingle()")
FuncSpeedTest("_IfMulti()")


;----------------------------------------------------------------------------------------
Func _IfSingle()
    Local $iVariable = 1
    For $i = 1 To 1000000
        If $iVariable Then $iVariable = 1
    Next
EndFunc   ;==>_IfSingle
;----------------------------------------------------------------------------------------
Func _IfMulti()
    Local $iVariable = 1
    For $i = 1 To 1000000
        If $iVariable Then
            $iVariable = 1
        EndIf
    Next
EndFunc   ;==>_IfMulti
;----------------------------------------------------------------------------------------
Func FuncSpeedTest($sExecute)
    Local $hTimer = TimerInit()
    Execute($sExecute)
    ConsoleWrite($sExecute & " processed in: " & Round(TimerDiff($hTimer) / 1000, 3) & " seconds " & @LF)
EndFunc   ;==>FuncSpeedTest
;----------------------------------------------------------------------------------------

from: 133961-if-then-else-single-line

 

Example2:

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include <WinAPISys.au3>

For $i = 1 To 4
    FuncSpeedTest("_test" & $i & "()")
    ConsoleWrite("" & @CRLF)
Next

;----------------------------------------------------------------------------------------
Func _test1()
    For $i = 1 To 1000000
        _WinAPI_GetTickCount64()
    Next
    ConsoleWrite(_WinAPI_GetTickCount64() & @CRLF)
EndFunc   ;==>_test1
;----------------------------------------------------------------------------------------
Func _test2()
    For $i = 1 To 1000000
        DllCall('kernel32.dll', 'uint64', 'GetTickCount64')
    Next
    ConsoleWrite(DllCall('kernel32.dll', 'uint64', 'GetTickCount64')[0] & @CRLF)
EndFunc   ;==>_test2
;----------------------------------------------------------------------------------------
Func _test3()
    Local $dll = DllOpen("kernel32.dll")
    For $i = 1 To 1000000
        DllCall($dll, 'uint64', 'GetTickCount64')
    Next
    ConsoleWrite(DllCall($dll, 'uint64', 'GetTickCount64')[0] & @CRLF)
    DllClose($dll)
EndFunc   ;==>_test3
;----------------------------------------------------------------------------------------
Func _test4()
    Local $hInstance_Kernel32_dll = _WinAPI_GetModuleHandle("kernel32.dll")
    Local $hAddress_Kernel32_dll_GetTickCount64 = _WinAPI_GetProcAddress($hInstance_Kernel32_dll, "GetTickCount64")
    For $i = 1 To 1000000
        DllCallAddress('uint64', $hAddress_Kernel32_dll_GetTickCount64)
    Next
    ConsoleWrite(DllCallAddress('uint64', $hAddress_Kernel32_dll_GetTickCount64)[0] & @CRLF)
EndFunc   ;==>_test4
;----------------------------------------------------------------------------------------
Func FuncSpeedTest($sExecute)
    Local $hTimer = TimerInit()
    Execute($sExecute)
    ConsoleWrite($sExecute & " processed in: " & Round(TimerDiff($hTimer) / 1000, 3) & " seconds " & @LF)
EndFunc   ;==>FuncSpeedTest
;----------------------------------------------------------------------------------------

from: 209984-dllclose-is-still-a-good-idea

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

  • 2 weeks later...

_WorkDay() Returns the date that is the specified number of working days before or after the start date

This is a variation of a function  from this post that implements more features, namely, the function allows 3 parameters:

$StartDate: Date representing the start date of the count. (no check is made on the correctness of the date provided)

$iDays: Number of working days before or after the start_date. A positive value indicates a future date; a negative value indicates a past date; a zero value indicates the start_date itself. (Indicating 0 the departure date is returned even if this corresponds to a non-working day, but in this case the @error flag is set to 1)

$sHolidays: Optional (default 1,7). Indicate the days of the week considered non-working (not to be considered in the count). $sHolidays represents a string with any combination of digits from 1 to 7 (the comma between the digits is optional) which indicates the days of the week to be considered holidays which correspond as follows: 1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday. if you want to consider working all days of the week pass an empty string then. (if, by contradiction, all seven days of the week are indicated as holidays, the day pointed to by $Days is returned anyway, but the @error flag is also set to 1)

I hope there are no bugs.
Have fun.

#include <date.au3>

_Example()

; 1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday
Func _Example()
    Local $Start = _NowCalcDate()
    Local $count = 25
    MsgBox(0, 'example 1', "The " & $count & "th working days past " & $Start & " is " & _WorkDay($Start, $count))

    $count = -9
    MsgBox(0, 'example 2', $count & " workdays ago: " & _WorkDay($Start, $count))

    $Start = "2022/12/31"
    $count = 33
    $NoCountWeekDays = '234567' ; <-- all holidays except Sunday (count only the Sunday)
    MsgBox(0, 'example 3', "The " & $count & "th Sunday of the 2023 is on " & _WorkDay($Start, $count, $NoCountWeekDays))

    $Start = _NowCalcDate()
    $count = -15 ; negative
    $NoCountWeekDays = '134567' ; <-- all holidays except Monday (count only the Monday)
    MsgBox(0, 'example 4', $count & " Mondays ago was " & _WorkDay($Start, $count, $NoCountWeekDays))

EndFunc   ;==>_Example

; #FUNCTION# ====================================================================================================================
; Name ..........: _WorkDay
; Description ...:
; Syntax ........: _WorkDay([$StartDate = _NowCalcDate([, $iDays = 0[, $sHolidays = "17"]]])
; Parameters ....: $StartDate           - Start day.
;                  $iDays               - number of WorkDays to count (positive or negative)
;                  $sHolidays           - a string of digits indicating not working days of week. Default is "17".
; Return values .: Target date
; Author ........: Gianni
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _WorkDay($StartDate = _NowCalcDate(), $iDays = 0, $sHolidays = "17")

    Local $iDirection = 1 * ($iDays < 0 ? -1 : $iDays > 0), $iWeekdays = 0
    Local $iWorkDays = StringRegExpReplace("1234567", "[" & StringRegExpReplace($sHolidays, "[^1234567]", "") & "]", "")

    Local $aYMD = StringSplit($StartDate, "/", 2)
    Local $nJulianDate = _DateToDayValue($aYMD[0], $aYMD[1], $aYMD[2])

    If Not $iDirection Then Return SetError(False = StringInStr($iWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2), 0, $StartDate)
    If $iWorkDays = '' Then Return SetError(1, 0, _DateAdd('D', $iDays, $StartDate))

    $iDays = Abs($iDays)
    Do
        $nJulianDate += $iDirection
        _DayValueToDate($nJulianDate, $aYMD[0], $aYMD[1], $aYMD[2])
        $iWeekdays += (StringInStr($iWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2) ? 1 : 0)
    Until $iWeekdays = $iDays

    Return SetError(0, 0, $aYMD[0] & '/' & $aYMD[1] & '/' & $aYMD[2])
EndFunc   ;==>_WorkDay

 

Edited by Gianni

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

This function has the same functionality as the one in the above post,
The only difference is that the one above counts the days in sequence until it reaches the required number of days (in a kind of brute force), while the latter calculates the target week and then only counts the last few days left. This way it is much faster especially for dates far from the initial one.
(I also changed the function name from _WorkDay() to _DateAddWorkDay)
I copied the calculation from <this post> by @Nine (thanks)
if you find any bugs please report.

#include <date.au3>

; #FUNCTION# ====================================================================================================================
; Name ..........: _DateAddWorkDay
; Description ...: Calculates a new date by adding/subtracting a specified number of Days from an initial date, excluding from the count
;                  those days corresponding to specified weekdays. (By defaul Sundays and Saturdays are excluded from the count).
;                  You can freely choose the days of the week to be considered as non-working days. See the third parameter for this.

; Syntax ........: _DateAddWorkDay([$StartDate = _NowCalcDate([, $iDays = 0[, $sHolidays = "17"]]])
; Parameters ....: $StartDate           - Initial date in the format YYYY/MM/DD
;                                         (no check is made on the correctness of the date provided)
;
;                  $iDays               - Number of business days to add/subtract (use negative number to count back)
;                                         a zero value indicates that the StartDate itself will be returned.
;                                         (Indicating 0 the StartDate is returned even if this corresponds to a non-working day,
;                                         but in this case the @error flag is set to 1. This can be useful if you need to check
;                                         if a specified date is a working or not working day)
;
;                  $sHolidays           - a string of digits indicating not working days of week. Default is "17".
;                                         Indicate the days of the week to be considered as non-working days.
;                                         (not to be considered in the count). $sHolidays represents a string with any combination
;                                         of digits from 1 to 7 (the comma between the digits is optional). Digit correspond as follows:
;                                         1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday.
;                                         if you want to consider working all days of the week pass an empty string.
;                                         (if, by contradiction, all seven days of the week are indicated as holidays, then the day
;                                         pointed to by $Days is returned anyway, but the @error flag is also set to 1)
;
; Return values .: Target date in the "YYYY/MM/DD" format
; Author ........: Gianni
; Modified ......:
;
; Remarks .......:                        It is possible to force the function to return a date even if it belongs to a non-working day.
;                                         This is possible by passing 0 as the second parameter and setting the start date to point to a non working day of the week.
;                                         In this case, even if a holiday, that date is returned but the @error flag is set to 1.
;                                         This could be used to check in one shot if a date belongs or not to a day of the week included in the third parameter.
;                                         (also, by setting all seven days as holidays in the third parameter you will be rturned with the date pointed to by the
;                                         second parameter, even if it's holiday, but also in this case the @error flag is set to 1)
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _DateAddWorkDay($StartDate = _NowCalcDate(), $iDays = 0, $sHolidays = "17")

    Local $iDirection = 1 * ($iDays < 0 ? -1 : $iDays > 0)
    Local $sWorkDays = StringRegExpReplace("1234567", "[" & StringRegExpReplace($sHolidays, "[^1234567]", "") & "]", "")
    Local $iWorkDays = StringLen($sWorkDays)

    If $iWorkDays = 7 Then Return SetError(1, 0, _DateAdd('D', $iDays, $StartDate))

    Local $aYMD = StringSplit($StartDate, "/", 2)
    If Not $iDirection Then Return SetError(False = StringInStr($sWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2), 0, $StartDate)

    Local $iNumWeek = Int(($iDays - $iDirection) / $iWorkDays)
    Local $iDaysRemainder = Mod($iDays - $iDirection, $iWorkDays) + $iDirection
    $iDays -= $iDaysRemainder

    $StartDate = _DateAdd("w", $iNumWeek, $StartDate)
    $aYMD = StringSplit($StartDate, "/", 2)
    Local $nJulianDate = _DateToDayValue($aYMD[0], $aYMD[1], $aYMD[2])

    While $iDaysRemainder
        $nJulianDate += $iDirection
        _DayValueToDate($nJulianDate, $aYMD[0], $aYMD[1], $aYMD[2])
        $iDaysRemainder -= (StringInStr($sWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2) ? 1 : 0) * $iDirection
    WEnd

    Return SetError(0, 0, $aYMD[0] & '/' & $aYMD[1] & '/' & $aYMD[2])
EndFunc   ;==>_DateAddWorkDay

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 2 months later...
ConsoleWrite('- IsDarkMode: ' & IsDarkMode() & @CRLF)
Func IsDarkMode()
    Local $aCall = DllCall("user32.dll", "INT", "GetSysColor", "int", 15) ; $COLOR_3DFACE ; _WinAPI_GetSysColor()
    If @error Then Return SetError(@error, @extended, 0)
    If "0x" & StringMid(Hex($aCall[0], 6), 3, 2) < 0xC0 Then Return 1
EndFunc

Not researched but a guesstimation. Works ok on my PC.

Edit: use the next version bellow. Is better researched.

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

On Windows 11, your function returns false for me, despite having dark mode on and my "custom accent color" set to #404040... though GetSysColor returns 00F0F0F0 🤨

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize has SystemUsesLightTheme and AppsUseLightTheme, which are both set to 0 for me. Perhaps this would be a better check?

Alternately, this works on Win11, not sure about 10 or previous. The theme path comes from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\CurrentTheme

Func AppMode()
    return IniRead(@LocalAppDataDir & "\Microsoft\Windows\Themes\Custom.theme","VisualStyles", "AppMode", "Unknown")
EndFunc

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

4 hours ago, seadoggie01 said:

despite having dark mode

..we use win32 controls ( from Win95 onwards ) on our GUIs.
The code I presented is to be used by other themes ( not quite welcomed by the OS ).
So the declaration of windows itself for it's own use was not my idea, but rather to figure if the current theme as the colors that could be considered as dark, or dark enough. 

Had a battle with a user using these themes and I myself had a go at it without having to patch/alter the OS.

But do thank you for your clarification.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Perhaps then the brightness calculation here (specifically, the IsColorLight function) would be helpful? Essentially (((5 * Green) + (2 * Red) + Blue) > (8 * 128)); I've got no idea why it works, but stumbled on it earlier when I was looking for a "better" way to calculate color since your method didn't work for me :) I think it's a cool idea either way

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

#include-once ; if used as include
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>

ConsoleWrite('- IsDarkMode: ' & IsDarkMode() & @CRLF)
Func IsDarkMode()
    ; https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolor
    Return (PerceivedBrightnessOfColor(_WinAPI_GetSysColor($COLOR_WINDOWTEXT)) _
             > PerceivedBrightnessOfColor(_WinAPI_GetSysColor($COLOR_WINDOW)))
    ; if the text is perceived as brighter than the background then Return True
EndFunc   ;==>IsDarkMode

Func PerceivedBrightnessOfColor($color)
    ; https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/apply-windows-themes#know-when-dark-mode-is-enabled
    ; This function performs a quick calculation of the perceived brightness of a color, and takes into consideration
    ;           ways that different channels in an RGB color value contribute to how bright it looks to the human eye.
    Local $a = StringSplit(Hex($color, 6), ""), $r = 2 * Dec($a[1] & $a[2]), $g = 5 * Dec($a[3] & $a[4]), $b = 1 * Dec($a[5] & $a[6])
    Return ($r + $g + $b)
EndFunc   ;==>PerceivedBrightnessOfColor

..yes. If the perceived color is brighter than the background then it can be said to be in dark mode.
Based on the link you shared, I cooked the above and it makes sense. The 5 + 2 + 1 = 8 makes sense too. All in all the above is a better approach than my 1st attempt at determining dark mode.
Thanks for sharing @seadoggie01  

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

  • 3 weeks later...
On 4/11/2023 at 10:09 PM, Gianni said:

This function has the same functionality as the one in the above post,
The only difference is that the one above counts the days in sequence until it reaches the required number of days (in a kind of brute force), while the latter calculates the target week and then only counts the last few days left. This way it is much faster especially for dates far from the initial one.
(I also changed the function name from _WorkDay() to _DateAddWorkDay)
I copied the calculation from <this post> by @Nine (thanks)
if you find any bugs please report.

#include <date.au3>

; #FUNCTION# ====================================================================================================================
; Name ..........: _DateAddWorkDay
; Description ...: Calculates a new date by adding/subtracting a specified number of Days from an initial date, excluding from the count
;                  those days corresponding to specified weekdays. (By defaul Sundays and Saturdays are excluded from the count).
;                  You can freely choose the days of the week to be considered as non-working days. See the third parameter for this.

; Syntax ........: _DateAddWorkDay([$StartDate = _NowCalcDate([, $iDays = 0[, $sHolidays = "17"]]])
; Parameters ....: $StartDate           - Initial date in the format YYYY/MM/DD
;                                         (no check is made on the correctness of the date provided)
;
;                  $iDays               - Number of business days to add/subtract (use negative number to count back)
;                                         a zero value indicates that the StartDate itself will be returned.
;                                         (Indicating 0 the StartDate is returned even if this corresponds to a non-working day,
;                                         but in this case the @error flag is set to 1. This can be useful if you need to check
;                                         if a specified date is a working or not working day)
;
;                  $sHolidays           - a string of digits indicating not working days of week. Default is "17".
;                                         Indicate the days of the week to be considered as non-working days.
;                                         (not to be considered in the count). $sHolidays represents a string with any combination
;                                         of digits from 1 to 7 (the comma between the digits is optional). Digit correspond as follows:
;                                         1=Sunday, 2 =Monday , 3=Tuesday, 4=Wednesday, 5=Thursday, 6=Friday, 7=Saturday.
;                                         if you want to consider working all days of the week pass an empty string.
;                                         (if, by contradiction, all seven days of the week are indicated as holidays, then the day
;                                         pointed to by $Days is returned anyway, but the @error flag is also set to 1)
;
; Return values .: Target date in the "YYYY/MM/DD" format
; Author ........: Gianni
; Modified ......:
;
; Remarks .......:                        It is possible to force the function to return a date even if it belongs to a non-working day.
;                                         This is possible by passing 0 as the second parameter and setting the start date to point to a non working day of the week.
;                                         In this case, even if a holiday, that date is returned but the @error flag is set to 1.
;                                         This could be used to check in one shot if a date belongs or not to a day of the week included in the third parameter.
;                                         (also, by setting all seven days as holidays in the third parameter you will be rturned with the date pointed to by the
;                                         second parameter, even if it's holiday, but also in this case the @error flag is set to 1)
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _DateAddWorkDay($StartDate = _NowCalcDate(), $iDays = 0, $sHolidays = "17")

    Local $iDirection = 1 * ($iDays < 0 ? -1 : $iDays > 0)
    Local $sWorkDays = StringRegExpReplace("1234567", "[" & StringRegExpReplace($sHolidays, "[^1234567]", "") & "]", "")
    Local $iWorkDays = StringLen($sWorkDays)

    If $iWorkDays = 7 Then Return SetError(1, 0, _DateAdd('D', $iDays, $StartDate))

    Local $aYMD = StringSplit($StartDate, "/", 2)
    If Not $iDirection Then Return SetError(False = StringInStr($sWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2), 0, $StartDate)

    Local $iNumWeek = Int(($iDays - $iDirection) / $iWorkDays)
    Local $iDaysRemainder = Mod($iDays - $iDirection, $iWorkDays) + $iDirection
    $iDays -= $iDaysRemainder

    $StartDate = _DateAdd("w", $iNumWeek, $StartDate)
    $aYMD = StringSplit($StartDate, "/", 2)
    Local $nJulianDate = _DateToDayValue($aYMD[0], $aYMD[1], $aYMD[2])

    While $iDaysRemainder
        $nJulianDate += $iDirection
        _DayValueToDate($nJulianDate, $aYMD[0], $aYMD[1], $aYMD[2])
        $iDaysRemainder -= (StringInStr($sWorkDays, _DateToDayOfWeek($aYMD[0], $aYMD[1], $aYMD[2]), 2) ? 1 : 0) * $iDirection
    WEnd

    Return SetError(0, 0, $aYMD[0] & '/' & $aYMD[1] & '/' & $aYMD[2])
EndFunc   ;==>_DateAddWorkDay

 

Very interesting, I think we can add also national holidays to the count, excluding these days.

To obtain a  list of updated national holidays there are some services online, but for a quick test I asked chatgpt:

20230101,Capodanno
20230106,Epifania
20230409,Domenica di Pasqua
20230416,Lunedì dell'Angelo
20230425,Festa della Liberazione
20230501,Festa dei Lavoratori
20230602,Festa della Repubblica
20230815,Ferragosto
20231101,Ognissanti
20231208,Immacolata Concezione
20231225,Natale

 

I am thinking to work on this...

Link to comment
Share on other sites

  • 2 weeks later...
11 hours ago, TheDcoder said:

@UEZ Aren't these in AutoIt's standard UDFs? If not, maybe you should make a ticket to get those added in :)

Obviously not. 😉

I tested it only on my Win11 notebook. I don't know if the test script will work properly on other operating systems.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

..on my side, I'll be putting something like this:

Spoiler
<removed by user>

  Edit: The code got cleaned up and posted as an example at:
 https://www.autoitscript.com/forum/topic/210613-guictrls_hidpi-udf-in-progress/

 

to simply add water a prefix _HiDpi_GUICtrlCreateSomething() and make it instantly coffee HiDpi ready :)
...unless @TheDcoder jumps the gun and gets it done. It'll take me time to get this functional. But the easier the addendum ( so to call it ), the more testers we'll have to know if it ( @UEZ's code ) works everywhere :gathering:
 

Edited by argumentum
better code

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...