Leaderboard
Popular Content
Showing content with the highest reputation since 03/26/2025 in all areas
-
I was wondering how to create an Application Bar that would be recognized by the system. Searching on the forum here revealed that there was a few attempts of doing so but none was successful. So here a working example of how to perform it. Notice how maximized windows are shrunk by the application bar. 😎 #NoTrayIcon ;#AutoIt3Wrapper_UseX64=y #include <GUIConstants.au3> #include <StructureConstants.au3> #include <WindowsConstants.au3> #include <TrayConstants.au3> ; #SHAppBarMessage# ============================================================================================================= ; Name ..........: SHAppBarMessage.AU3 ; Description ...: Create an Application Bar recognized by the system ; Author ........: Nine ; Created .......: 2025-04-04 ; Modified ......: ; Remarks .......: ; Example .......: Yes ; =============================================================================================================================== Opt("MustDeclareVars", True) Opt("GUICloseOnESC", False) Opt("TrayMenuMode", 1) Opt("TrayAutoPause", 0) Global Enum $ABM_NEW, $ABM_REMOVE, $ABM_QUERYPOS, $ABM_SETPOS, $ABM_GETSTATE, $ABM_GETTASKBARPOS, $ABM_ACTIVATE, $ABM_GETAUTOHIDEBAR, _ $ABM_SETAUTOHIDEBAR, $ABM_WINDOWPOSCHANGED, $ABM_SETSTATE Global Enum $ABS_ONTOP, $ABS_AUTOHIDE, $ABS_ALWAYSONTOP Global Enum $ABE_LEFT, $ABE_TOP, $ABE_RIGHT, $ABE_BOTTOM Global Enum $ABN_STATECHANGE, $ABN_POSCHANGED, $ABN_FULLSCREENAPP, $ABN_WINDOWARRANGE Global Const $CALLBACK = $WM_USER + 0x10 Global Const $tagAPPBARDATA = "dword cbSize;hwnd hWnd;uint uCallbackMessage;uint uEdge;" & $tagRECT & ";lparam lParam" Global $idDummy Example() Func Example() Local $tAppBarData = DllStructCreate($tagAPPBARDATA) $tAppBarData.cbSize = DllStructGetSize($tAppBarData) Local $hGUI = GUICreate("", 80, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST) GUISetBkColor(0x202020) GUISetFont(11, 0, 0, "Comic Sans MS") Local $idHide = GUICtrlCreateButton(" Hide", 5, 5, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 200, 0) Local $idTask = GUICtrlCreateButton(" Task", 5, 40, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 16739, 0) Local $idDo = GUICtrlCreateButton(" Do", 5, 75, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 16802, 0) Local $idDont = GUICtrlCreateButton(" Don't", 5, 110, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 240, 0) Local $idExit = GUICtrlCreateButton(" Exit", 5, 300, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 290, 0) $tAppBarData.hWnd = $hGUI $tAppBarData.uCallbackMessage = $CALLBACK DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_NEW, "struct*", $tAppBarData) AppBarSetPos($tAppBarData) GUIRegisterMsg($CALLBACK, AppBarProc) GUISetState() $idDummy = GUICtrlCreateDummy() While True Switch GUIGetMsg() Case $idExit ExitLoop Case $idDummy AppBarSetPos($tAppBarData) Case $idHide GUISetState(@SW_HIDE) DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_REMOVE, "struct*", $tAppBarData) TraySetIcon("shell32.dll", 255) TraySetState($TRAY_ICONSTATE_SHOW) TraySetToolTip("Left click to restore" & @CRLF & "Right click to Exit") Case $idTask ToggleTaskBar() EndSwitch Switch TrayGetMsg() Case $TRAY_EVENT_PRIMARYDOWN GUISetState(@SW_SHOW) DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_NEW, "struct*", $tAppBarData) AppBarSetPos($tAppBarData) TraySetState($TRAY_ICONSTATE_HIDE) Case $TRAY_EVENT_SECONDARYUP Exit EndSwitch WEnd DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_REMOVE, "struct*", $tAppBarData) EndFunc ;==>Example Func AppBarSetPos(ByRef $tAppBar) $tAppBar.uEdge = $ABE_LEFT $tAppBar.left = 0 $tAppBar.top = 0 $tAppBar.Right = 80 $tAppBar.Bottom = @DesktopHeight DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_QUERYPOS, "struct*", $tAppBar) DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_SETPOS, "struct*", $tAppBar) WinMove($tAppBar.hWnd, "", $tAppBar.Left, $tAppBar.Top, $tAppBar.Right, $tAppBar.Bottom) EndFunc ;==>AppBarSetPos Func ToggleTaskBar() Local $tAppBar = DllStructCreate($tagAPPBARDATA) $tAppBar.cbSize = DllStructGetSize($tAppBar) Local $iState = DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_GETSTATE, "struct*", $tAppBar)[0] $tAppBar.lParam = $iState = $ABS_AUTOHIDE ? $ABS_ALWAYSONTOP : $ABS_AUTOHIDE DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_SETSTATE, "struct*", $tAppBar) EndFunc ;==>ToggleTaskBar Func AppBarProc($hWnd, $iMsg, $wParam, $lParam) If $wParam = $ABN_POSCHANGED Then GUICtrlSendToDummy($idDummy, $wParam) Return $GUI_RUNDEFMSG EndFunc ;==>AppBarProc8 points
-
JSON UDF using JSON-C
Musashi and 5 others reacted to seangriffin for a topic
I created this UDF for JSON using JSON-C because I needed high performance parsing of JSON data in my script. I needed to query large data arrays of several thousand entries and other UDFs were taking many seconds to do so. With this UDF a query of 5,000 array entries takes me about 600ms (see Example2.au3). This UDF executes JSON functions through a JSON-C DLL to achieve better performance. The JSON-C project is https://github.com/json-c/json-c. To download this UDF please visit https://github.com/seanhaydongriffin/JsonC-UDF. Two examples are provided (Example1.au3 and Example2.au3) that demonstrate all the functions.6 points -
Although I think the best way to use WebView2 in AutoIt would be to complete and use the work started by @LarsJ in this other @mLipok's topic, now it is possible to use WebView2 in AutoIt in a much simpler way. This is possible thanks to this ocx control and thanks to @Danyfirex for his decisive contribution. Now we can easily start embedding one or more WebView2 controls in our GUI in AutoIt. What we need is: the OrdoWebView2.ocx control and the \OrdoRC6 folder. These two are installed together with other programs (in the C:\Program Files (x86)\OrdoWebView2Control folder) by running the OrdoWebView2ActiveXControl.2.0.9.exe program downloadable from this link: https://freeware.ordoconcept.net/OrdoWebview2.php by clicking on "Download OrdoWebView2 SDK" at the bottom of the screen. Or, more simply, you can find them directly attached to this post by @Danyfirex. As explained in this post on VBForums (https://www.vbforums.com/showthread.php?899415-OrdoWebview2-ActiveX-WebView2-Browser-Control-(Replacement-of-the-MS-browser-control)&p=5651133&viewfull=1#post5651133): "On the latest versions of Windows 10 and Windows 11, only the following components are needed: OrdoWebView2.ocx OrdoRC6 folder and its contents, in the same directory as OrdoWebView2.ocx Finally, you need to register OrdoWebView2.ocx with regsvr32.exe OrdoWebView2.ocx". Also: Our AutoIt script and the OrdoWebView2.au3 must also be in the same directory along with the above. I have extracted the essential parts needed to create the WebView2 object from the DanyFirex's original example and grouped them into the OrdoWebView2.au3 UDF so that it can be easily included into a program. This is just a quick draft to get you started, but it can definitely be improved. Suggestions are welcome. Here are the basic UDF and a very basic example script: Embed 4 WebView2 controls in an AutoIt GUI More scripts to follow to test the functionality and interaction between OrdoWebView2 and AutoIt. See you later. P.S. Here is a reference link to the OrdoWebView2.ocx help (https://freeware.ordoconcept.net/Help/OrdoWebView2/) OrdoWebView2.au3 ; From the following POST By DanyFirex: ; https://www.autoitscript.com/forum/topic/204362-microsoft-edge-webview2-embed-web-code-in-your-native-application/page/9/#findComment-1542694 ; ... first draft to be continue ... #include <WinAPI.au3> Global Const $gATL = DllOpen("ATL.DLL") Global Const $gOleaut32 = DllOpen("oleaut32.dll") _WinAPI_CoInitialize($COINIT_APARTMENTTHREADED) AtlAxWinInit() Global $pProgID = SysAllocString('OrdoWebView2.OrdoWebView') Func webview2_GUI_Create($w, $h, $x, $y, $hMain, _ $sEventsPrefix = '', _ ; ......................... The prefix of the functions you define to handle receiving events. The prefix is appended by the Objects event name. $sLang = "", _ ; ................................. Language defined by the 2-letter code from ISO 639. If omitted, the chosen language will be that of the user's system. $bIsPrivateNavigation = False, _ ; ............... if TRUE the browser goes into private browsing mode. Default value is False $sBrowserInstallPath = "", _ ; ................... sets the installation directory of the WebView2 fixed version. Only considered if UseEdgeFixedVersion is TRUE. $sUserDataFolder = "", _ ; ....................... defines the user's browsing data directory. If empty, use default user assignment directory. Ignored if IsPrivateNavigation is true $sAdditionalBrowserArguments = "", _ ; ........... Allows passing parameters to the Chromium WebView2 browser through command line switches. You can find a list of Chromium Command Line Switches here $iAllowSingleSignOnUsingOSPrimaryAccount = 0) ; .. Determines whether to enable single sign on with Azure Active Directory Local $hGUI_1 = GUICreate('', $w, $h, $x, $y, $WS_POPUPWINDOW) ; BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN)) Local $hResult = AtlAxCreateControl($pProgID, $hGUI_1) ; _SysFreeString($pProgID) Local $pIUnkown = AtlAxGetControl($hGUI_1) ; ConsoleWrite("AtlAxGetControl: " & $pIUnkown & @CRLF) _WinAPI_SetParent($hGUI_1, $hMain) ; trap this child gui within the main gu GUISetState(@SW_SHOW, $hGUI_1) Local $oOrdoWebView2 = ObjCreateInterface($pIUnkown, "{E54909AA-1705-44A9-8235-B24F74366B3F}") Local $oOrdoWebViewEvents = ObjEvent($oOrdoWebView2, $sEventsPrefix, "__OrdoWebView") ; ConsoleWrite("$oOrdoWebView2: " & IsObj($oOrdoWebView2) & @CRLF) ; ConsoleWrite($oOrdoWebView2.GetWebView2Version() & @CRLF) ; ConsoleWrite($oOrdoWebView2.GetMostRecentInstallPath() & @CRLF) #cs $oOrdoWebView2.Anchor = True $oOrdoWebView2.Search_URL = "https://search.yahoo.com/search?p=%1" $oOrdoWebView2.HomeURL = "http://www.google.com" $oOrdoWebView2.SearchEngine = 2 $oOrdoWebView2.SearchAuto = True #ce $oOrdoWebView2.UseEdgeFixedVersion = False $oOrdoWebView2.InitEx($sLang, $bIsPrivateNavigation, $sBrowserInstallPath, $sUserDataFolder, $sAdditionalBrowserArguments, $iAllowSingleSignOnUsingOSPrimaryAccount) While Not $oOrdoWebView2.IsWebViewInit() ;wait initialization otherwise Navigate will fail Sleep(100) WEnd Local $aReturn = [$oOrdoWebView2, $hGUI_1] Return $aReturn ; $oOrdoWebView2 EndFunc ;==>webview2_GUI_Create Func AtlAxCreateControl($pProgID, $HWND) Local $aCall = DllCall($gATL, "long", "AtlAxCreateControl", "ptr", $pProgID, "handle", $HWND, "ptr", 0, "ptr", 0) If @error Then Return SetError(1, 0, -1) Return $aCall[0] EndFunc ;==>AtlAxCreateControl Func AtlAxGetControl($HWND) Local $aCall = DllCall($gATL, "long", "AtlAxGetControl", "handle", $HWND, "ptr*", 0) If @error Then Return SetError(1, 0, -1) Return $aCall[2] EndFunc ;==>AtlAxGetControl Func AtlAxWinInit() Local $aCall = DllCall($gATL, "bool", "AtlAxWinInit") If @error Then Return SetError(1, 0, -1) Return $aCall[0] EndFunc ;==>AtlAxWinInit Func _SysFreeString($pBSTR) ; Author: Prog@ndy If Not $pBSTR Then Return SetError(2, 0, 0) DllCall($gOleaut32, "none", "SysFreeString", "ptr", $pBSTR) If @error Then Return SetError(1, 0, 0) EndFunc ;==>_SysFreeString Func SysAllocString($str) ; Author: monoceres Local $aCall = DllCall($gOleaut32, "ptr", "SysAllocString", "wstr", $str) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ;==>SysAllocString OrdoWebView2_Demo.au3 #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include "OrdoWebView2.au3" Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") _TestOrdoWebView() Func _TestOrdoWebView() Local $hMain_GUI = GUICreate("Main GUI", 990, 810, -1, -1, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN)) GUISetState(@SW_SHOW, $hMain_GUI) Local $hAutoIt_Button_1 = GUICtrlCreateButton("test", 10, 785) ; Create 4 controls Local $aWebView1 = webview2_GUI_Create(480, 380, 10, 10, $hMain_GUI) Local $aWebView2 = webview2_GUI_Create(480, 380, 500, 10, $hMain_GUI) Local $aWebView3 = webview2_GUI_Create(480, 380, 10, 400, $hMain_GUI) Local $aWebView4 = webview2_GUI_Create(480, 380, 500, 400, $hMain_GUI) ; Navigate to web pages $aWebView1[0].Navigate("https://www.kevs3d.co.uk/dev/js1kdragons/") ; "http://www.3quarks.com/en/SegmentDisplay/" $aWebView2[0].Navigate("https://gridstackjs.com/demo/anijs.html") ; "https://retejs.org/") $aWebView3[0].Navigate("https://www.youtube.com/watch?v=ojBYW3ycVTE") $aWebView4[0].Navigate("https://freeware.ordoconcept.net/OrdoWebview2.php") ; "https://freeware.ordoconcept.net/Help/OrdoWebView2/" While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $hAutoIt_Button_1 MsgBox(0, 'AutoIt', 'Hi') EndSwitch WEnd _SysFreeString($pProgID) GUIDelete($aWebView1[1]) GUIDelete($aWebView2[1]) GUIDelete($aWebView3[1]) GUIDelete($aWebView4[1]) GUIDelete($hMain_GUI) EndFunc ;==>_TestOrdoWebView ; User's COM error function. Will be called if COM error occurs Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc5 points
-
This is a spin off the thread from here. I've moved this out of the collab space so I don't feel guilty about making sweeping changes when the mood hits me. But I'm still more than happy for this to be a community project at heart. Just a quick comment about the code: for this API, it looks like we need to construct some objects internally, which is a bit of a learning curve - but hopefully this example will provide a bit of background as to whats happening there... Original Attempt: Updated example 20/4 - Load media file, progress/seek bar. PlayerDemo 1.1.zip5 points
-
Hello friends, I haven't used AutoIt for a long time, but I always like these challenges, and I never forget you. Apparently there is some bug in how GUICtrlCreateObj works and I don't have time to look internally at the bug. This way I was able to create the instance of the object. #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global Const $gATL = DllOpen("ATL.DLL") Global Const $gOleaut32 = DllOpen("oleaut32.dll") Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") _TestOrdoWebView() Func _TestOrdoWebView() ConsoleWrite("AtlAxWinInit: " & AtlAxWinInit() & @CRLF) Local $pProgID = SysAllocString('OrdoWebView2.OrdoWebView') ConsoleWrite("SysAllocString('OrdoWebView2.OrdoWebView'): " & $pProgID & @CRLF) Local $hGUI = GUICreate("OrdoWebView2.OrdoWebView Test", (@DesktopWidth) / 1.2, (@DesktopHeight) / 1.2, Default, Default, BitOR($WS_OVERLAPPEDWINDOW, $WS_CLIPSIBLINGS, $WS_CLIPCHILDREN)) Local $hResult = AtlAxCreateControl($pProgID, $hGUI) _SysFreeString($pProgID) Local $pIUnkown = AtlAxGetControl($hGUI) ConsoleWrite("AtlAxGetControl: " & $pIUnkown & @CRLF) GUISetState() Local $oOrdoWebView2 = ObjCreateInterface($pIUnkown, "{E54909AA-1705-44A9-8235-B24F74366B3F}") Local $oOrdoWebViewEvents = ObjEvent($oOrdoWebView2, "_OrdoWebView_", "__OrdoWebView") ConsoleWrite("$oOrdoWebView2: " & IsObj($oOrdoWebView2) & @CRLF) ConsoleWrite($oOrdoWebView2.GetWebView2Version() & @CRLF) ConsoleWrite($oOrdoWebView2.GetMostRecentInstallPath() & @CRLF) $oOrdoWebView2.Anchor = True $oOrdoWebView2.Search_URL = "https://search.yahoo.com/search?p=%1" $oOrdoWebView2.HomeURL = "http://www.google.com" $oOrdoWebView2.SearchEngine = 2 $oOrdoWebView2.SearchAuto = True $oOrdoWebView2.Init() While Not $oOrdoWebView2.IsWebViewInit() ;wait initialization otherwise Navigate will fail Sleep(100) WEnd $oOrdoWebView2.Navigate("https://www.autoitscript.com/forum/topic/204362-microsoft-edge-webview2-embed-web-code-in-your-native-application/page/9/#findComment-1542505") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>_TestOrdoWebView Func _OrdoWebView_InitComplete($oIEpDisp) ConsoleWrite("_OrdoWebView_InitComplete" & @CRLF) EndFunc ;==>_OrdoWebView_InitComplete Func AtlAxCreateControl($pProgID, $HWND) Local $aCall = DllCall($gATL, "long", "AtlAxCreateControl", "ptr", $pProgID, "handle", $HWND, "ptr", 0, "ptr", 0) If @error Then Return SetError(1, 0, -1) Return $aCall[0] EndFunc ;==>AtlAxCreateControl Func AtlAxGetControl($HWND) Local $aCall = DllCall($gATL, "long", "AtlAxGetControl", "handle", $HWND, "ptr*", 0) If @error Then Return SetError(1, 0, -1) Return $aCall[2] EndFunc ;==>AtlAxGetControl Func AtlAxWinInit() Local $aCall = DllCall($gATL, "bool", "AtlAxWinInit") If @error Then Return SetError(1, 0, -1) Return $aCall[0] EndFunc ;==>AtlAxWinInit Func _SysFreeString($pBSTR) ; Author: Prog@ndy If Not $pBSTR Then Return SetError(2, 0, 0) DllCall($gOleaut32, "none", "SysFreeString", "ptr", $pBSTR) If @error Then Return SetError(1, 0, 0) EndFunc ;==>_SysFreeString Func SysAllocString($str) ; Author: monoceres Local $aCall = DllCall($gOleaut32, "ptr", "SysAllocString", "wstr", $str) If @error Then Return SetError(1, 0, 0) Return $aCall[0] EndFunc ;==>SysAllocString ; User's COM error function. Will be called if COM error occurs Func _ErrFunc($oError) ; Do anything here. ConsoleWrite(@ScriptName & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _ @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _ @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _ @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _ @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _ @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _ @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _ @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _ @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _ @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF) EndFunc ;==>_ErrFunc Saludos5 points
-
I have been creating few controls with round corners for awhile for my own needs and I felt it was time to make an UDF and share it with the community. The idea behind this UDF is to use essentially simple basic AutoIt GUI functions. I did not want to embark in GDI+ to create the controls. I wanted to be easy to use with enough features that it would answer most requirements. The functions contained in the UDF : _RGUI_RoundLabel _RGUI_RoundButton _RGUI_RoundInput _RGUI_RoundEdit _RGUI_RoundGroup _RGUI_RoundScrollBar _RGUI_ScrollBarSet _RGUI_ScrollBarDestroy _RGUI_RoundRect _RGUI_DrawLine _RGUI_ButtonPress _RGUI_ButtonReset Version 2025-04-06 * Solved an issue where scroll bar and control are not in the same GUI child * Added 4th example on how to use scrollbar with ListView over a background generated by GDI+ Version 2025-03-28 * Added support to auto-size label and button controls (by passing -1 for width and/or height) * Removed the requirement to pass handle of the GUI to _RGUI_RoundGroup * Added 3rd example on how to use scrollbar with RichEdit Version 2025-03-21 * Added support of round corner scrollbar * Added a 2nd example on how to use scrollbar with ListBox Version 2025-03-15 * Basic framework for the UDF Here an example of what could be done with the UDF : If you feel there should be new controls, I will consider adding them to the UDF. RoundGUI.zip5 points
-
Ok we're back with a new stuff in post #1. You'll first need to compile "playerDemo_engine.au3", then run "playerDemo.au3". We're still using a modal to block execution in the engine script - wish we could do something nicer, but I guess it'll have to do for now. For comms between processes we're using windows messages (thanks nine for the inspiration!). Look for the $WM_ME* values in the constants file. The WM codes are the same values as those generated by the mediaengine, combined with WM_APP. There's one totally "made up" code - its for MediaEngine to send through its window handle to the UI process ($WM_ME_PLAYBACKWINDOW). Also with the WMs, there's a bit of jiggery pokey in order to pass floating point values over wparam and lparam. I found if you send values as a float or double, they pop out as an integer on the other end - so you lose everything after the decimal point. But sending the values as binary solves this. We just need to ensure we convert our "doubles" to "floats" for x86 so the values fit within wparam/lparam. One last thing... you can still crash the engine by flooding it with messages from the UI, but that's where we're at for now. We could probably fix this by only check incoming messages from within the event handler... Then the problem is the engine won't be contactable when its paused, so you'd need to flick between two modes of checking for messages. And it would also require a total rethink of how to pass comms from the UI back to the engine!4 points
-
JSON UDF using JSON-C
argumentum and 3 others reacted to TheXman for a topic
4 points -
Just uploaded SciTEx86.zip & SciTEx64.zip which contain the Latest SciTE 5.5.6 versions released April 2, 2025, for those that like to use the latest version of SciTE Full. This will also be part of the final update of SciTE4AutoIt3.4 points
-
Resizable status bar without SBARS_SIZEGRIP
ioa747 and 2 others reacted to pixelsearch for a topic
Hellooo @jpm thanks for your answer, it's always nice to hear from you. So I did well not opening a trac ticket Done and done, without label, thanks to @Andreik and @argumentum for the inspiration. The status bar doesn't reach the right side of the window, because a function named _MyGUICtrlStatusBar_SetParts is called, with this result : If someone wants the status bar to reach the right side of the window, then just call (twice) the original function _GUICtrlStatusBar_SetParts instead, with the little artefact display found in the preceding pics, no big deal. [edit 5 hours after : this has been simplified and amended with the new code below] #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <StaticConstants.au3> #include <WinAPIGdi.au3> #include <WinAPIRes.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) Global $g_hGui, $g_hSizebox, $g_hOldProc, $g_hBrush, $g_hStatus, $g_iHeight, $g_aText, $g_aRatioW, $g_iBkColor, $g_iTextColor, $g_hDots Example() ;============================================== Func Example() _GDIPlus_Startup() Local Const $SBS_SIZEBOX = 0x08, $SBS_SIZEGRIP = 0x10 Local $iW = 300, $iH = 100 Dim $g_iBkColor = 0x383838, $g_iTextColor = 0xFFFFFF $g_hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor($g_iBkColor) ;----------------- ; Create a sizebox window (Scrollbar class) BEFORE creating the StatusBar control $g_hSizebox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, _ 0, 0, 0, 0, $g_hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP ; Subclass the sizebox (by changing the window procedure associated with the Scrollbar class) Local $hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam') $g_hOldProc = _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, DllCallbackGetPtr($hProc)) Local $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZENWSE) _WinAPI_SetClassLongEx($g_hSizebox, -12, $hCursor) ; $GCL_HCURSOR = -12 $g_hBrush = _WinAPI_CreateSolidBrush($g_iBkColor) ;----------------- $g_hStatus = _GUICtrlStatusBar_Create($g_hGui, -1, "", $WS_CLIPSIBLINGS) ; ClipSiblings style +++ Local $aParts[3] = [90, 180, 280] If $aParts[Ubound($aParts) - 1] = -1 Then $aParts[Ubound($aParts) - 1] = $iW ; client width size _MyGUICtrlStatusBar_SetParts($g_hStatus, $aParts) Dim $g_aText[Ubound($aParts)] = ["Part 0", "Part 1", "Part 2"] Dim $g_aRatioW[Ubound($aParts)] For $i = 0 To UBound($g_aText) - 1 _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW) ; _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW + $SBT_NOBORDERS) ; interesting ? $g_aRatioW[$i] = $aParts[$i] / $iW Next Local $idChangeText = GUICtrlCreateLabel("Change Text", 110, 25, 80, 30, $SS_CENTER + $SS_CENTERIMAGE), $iInc GUICtrlSetColor(-1, 0xFFFF00) ; yellow ; to allow the setting of StatusBar BkColor at least under Windows 10 _WinAPI_SetWindowTheme($g_hStatus, "", "") ; Set status bar background color _GUICtrlStatusBar_SetBkColor($g_hStatus, $g_iBkColor) $g_iHeight = _GUICtrlStatusBar_GetHeight($g_hStatus) + 3 ; change the constant (+3) if necessary $g_hDots = CreateDots($g_iHeight, $g_iHeight, 0xFF000000 + $g_iBkColor, 0xFF000000 + $g_iTextColor) GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_MOVE, "WM_MOVE") GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idChangeText $iInc += 1 For $i = 0 To UBound($g_aText) - 1 $g_aText[$i] = "Part " & $i & " : Inc " & $iInc Next _WinAPI_RedrawWindow($g_hStatus) EndSwitch WEnd _GDIPlus_BitmapDispose($g_hDots) _GUICtrlStatusBar_Destroy($g_hStatus) _WinAPI_DestroyCursor($hCursor) _WinAPI_DeleteObject($g_hBrush) _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, $g_hOldProc) DllCallbackFree($hProc) _GDIPlus_Shutdown() EndFunc ;==>Example ;============================================== Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam) ; Andreik If $hWnd = $g_hSizebox And $iMsg = $WM_PAINT Then Local $tPAINTSTRUCT Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT) Local $iWidth = DllStructGetData($tPAINTSTRUCT, 'rPaint', 3) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 1) Local $iHeight = DllStructGetData($tPAINTSTRUCT, 'rPaint', 4) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 2) Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC) _GDIPlus_GraphicsDrawImageRect($hGraphics, $g_hDots, 0, 0, $iWidth, $iHeight) _GDIPlus_GraphicsDispose($hGraphics) _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT) Return 0 EndIf Return _WinAPI_CallWindowProc($g_hOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>ScrollbarProc ;============================================== Func CreateDots($iWidth, $iHeight, $iBackgroundColor, $iDotsColor) ; Andreik Local $iDotSize = Int($iHeight / 10) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) Local $hBrush = _GDIPlus_BrushCreateSolid($iDotsColor) _GDIPlus_GraphicsClear($hGraphics, $iBackgroundColor) Local $a[6][2] = [[2,6], [2,4], [2,2], [4,4], [4,2], [6,2]] For $i = 0 To UBound($a) - 1 _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - $iDotSize * $a[$i][0], $iHeight - $iDotSize * $a[$i][1], $iDotSize, $iDotSize, $hBrush) Next _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGraphics) Return $hBitmap EndFunc ;==>CreateDots ;============================================== Func _MyGUICtrlStatusBar_SetParts($hWnd, $aPartEdge) ; Pixelsearch If Not IsArray($aPartEdge) Then Return False Local $iParts = UBound($aPartEdge) Local $tParts = DllStructCreate("int[" & $iParts & "]") For $i = 0 To $iParts - 1 DllStructSetData($tParts, 1, $aPartEdge[$i], $i + 1) Next DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", $SB_SETPARTS, "wparam", $iParts, "struct*", $tParts) _GUICtrlStatusBar_Resize($hWnd) Return True EndFunc ;==>_MyGUICtrlStatusBar_SetParts ;============================================== Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) ; Pixelsearch #forceref $iMsg, $wParam, $lParam If $hWnd = $g_hGUI Then Local Static $bIsSizeBoxShown = True Local $aSize = WinGetClientSize($g_hGui) Local $aGetParts = _GUICtrlStatusBar_GetParts($g_hStatus) Local $aParts[$aGetParts[0]] For $i = 0 To $aGetParts[0] - 1 $aParts[$i] = Int($aSize[0] * $g_aRatioW[$i]) Next If BitAND(WinGetState($g_hGui), $WIN_STATE_MAXIMIZED) Then _GUICtrlStatusBar_SetParts($g_hStatus, $aParts) ; set parts until GUI right border _WinAPI_ShowWindow($g_hSizebox, @SW_HIDE) $bIsSizeBoxShown = False Else _MyGUICtrlStatusBar_SetParts($g_hStatus, $aParts) ; set parts as user scripted them WinMove($g_hSizebox, "", $aSize[0] - $g_iHeight, $aSize[1] - $g_iHeight, $g_iHeight, $g_iHeight) If Not $bIsSizeBoxShown Then _WinAPI_ShowWindow($g_hSizebox, @SW_SHOW) $bIsSizeBoxShown = True EndIf EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_SIZE ;============================================== Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam, $lParam If $hWnd = $g_hGUI Then _WinAPI_RedrawWindow($g_hSizebox) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_MOVE ;============================================== Func WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam) ; Kafu #forceref $hWnd, $iMsg, $wParam Local Static $tagDRAWITEM = "uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;handle hDC;long rcItem[4];ulong_ptr itemData" Local $tDRAWITEM = DllStructCreate($tagDRAWITEM, $lParam) If $tDRAWITEM.hwndItem <> $g_hStatus Then Return $GUI_RUNDEFMSG ; only process the statusbar Local $itemID = $tDRAWITEM.itemID ; status bar part number (0, 1, ...) Local $hDC = $tDRAWITEM.hDC Local $tRect = DllStructCreate("long left;long top;long right;long bottom", DllStructGetPtr($tDRAWITEM, "rcItem")) _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $g_hBrush) ; backgound color _WinAPI_SetTextColor($hDC, $g_iTextColor) ; text color _WinAPI_SetBkMode($hDC, $TRANSPARENT) DllStructSetData($tRect, "top", $tRect.top + 1) DllStructSetData($tRect, "left", $tRect.left + 1) _WinAPI_DrawText($hDC, $g_aText[$itemID], $tRect, $DT_LEFT) Return $GUI_RUNDEFMSG EndFunc ;==>WM_DRAWITEM3 points -
Resizable status bar without SBARS_SIZEGRIP
WildByDesign and 2 others reacted to argumentum for a topic
3 points -
Resizable status bar without SBARS_SIZEGRIP
pixelsearch and 2 others reacted to WildByDesign for a topic
3 points -
App Control Tray & Policy Manager (App Control for Business)
ioa747 and 2 others reacted to WildByDesign for a topic
App Control Tray & Policy Manager (WildByDesign/WDACTrayTool: System Tray Tool for WDAC) This is likely my most powerful and featured creation with AutoIt. As always, I want to share and give back anything that I create in case it may benefit others. Features: system tray tool for managing App Control for Business (WDAC) policies GUI for managing App Control for Business (WDAC) policies scheduled tasks notifications auto dark-light mode for GUI and system tray built on GitHub Actions Screenshots: Includes: DarkMode UDF originally by @NoNameCode, updated by @argumentum libNotif by @matwachich ExtMsgBox by @Melba23 GUIListViewEx by @Melba23 TaskScheduler by @water XML by mLipok, Eltorro, Weaponx, drlava, Lukasz Suleja, oblique, Mike Rerick, Tom Hohmann, guinness, GMK3 points -
Please help with Run PowerShell Command 'quotes"
Trong and 2 others reacted to AspirinJunkie for a topic
Yes, the escaping of the quotation marks within the commands can be quite annoying. So you have to escape the quotation marks in the command. This is a bit easier if you swap the double quotation marks with the single ones. Something like this: Local $command_r = 'PowerShell -Command "' & StringReplace($powerShellCommand, '"', '\"') & '"' Why you are using @ComSpec (i.e. the cmd.exe) although you want to call the powershell instead is not clear to me. I have written the following function myself. Maybe it will help you here: #include <WinAPIConv.au3> ; Get the list of running processes and filter for processes named "notepad" Local $commandToRun = "Get-Process | Where-Object {$_.ProcessName -eq 'notepad'} | Format-List Name, Id, MainWindowTitle" Local $powerShellResult = _prc_runPS($commandToRun) If @error Then MsgBox(16, "Error", "Could not get results from PowerShell.") Else If $powerShellResult Then MsgBox(64, "PowerShell Result", "Result returned from PowerShell: " & $powerShellResult) Else MsgBox(64, "Information", "No processes match the criteria.") EndIf EndIf ; Another example: Get the PowerShell version Local $versionCommand = "$PSVersionTable.PSVersion" Local $powerShellVersion = _prc_runPS($versionCommand) If Not @error Then MsgBox(64, "PowerShell Version", "PowerShell Version: " & $powerShellVersion) EndIf ; #FUNCTION# ====================================================================================== ; Name ..........: _prc_runPS() ; Description ...: Executes a Powershell command and returns its output as a string ; Syntax ........: _prc_runPS($sCmd, [$nFlags = 0x8, [$sWorkDir = '', [$sOptions = '-NoProfile -ExecutionPolicy Bypass', [$nTimeOut = 0, $bLoopRead = False]]]]]) ; Parameters ....: $sCmd - the powershell command to be executed as you would use it directly in the powershell ; you can also use line breaks ; $nFlags - [optional] flags that control the handling of the two streams stdout and stderr: ; 0x2: [Default] Return a string with the content of stdout ; 0x4: [Default] Return a string with the content of stderr ; 0x6: Return a array with the content of stdout in $Array[0] and stderr in $Array[1] ; 0x8: Return a string with the combined content of stdout and stderr ; $sWorkDir - [optional] the working directory like in Run() ; $sOptions - [String] additional parameters to be passed to powershell.exe ; $nTimeOut - [optional] the maximum time to wait for the process to be completed (see @error return) ; default = 0: infinite; every other number: wait time in seconds ; $bLoopRead - if true: stdout and stderr are read in a loop; if false: they are read in one go ; Return values .: Success: String with powershell output or if $nFlags = 0x6: array with cmdline outputs and set ; @extended = return code of the process ; Failure: "" and set @error to: ; | 1: error during run; @extended = @error of Run() ; | 2: ProcessWaitClose reaches timeout before completion ; | 3: content written in stderr - indicates error messages of the program (not a real error) ; Author ........: AspirinJunkie ; Modified ......: 2025-03-10 ; Related .......: _WinAPI_OemToChar() ; Example .......: Yes ; $x = _prc_runPS('$obj = New-Object -ComObject "Shell.Application"' & @CRLF & _ ; '$obj | Get-Member') ; ConsoleWrite($x & @CRLF) ; ================================================================================================= Func _prc_runPS($sCmd, $nFlags = 0x8, $sWorkDir = '', $sOptions = '-NoProfile -ExecutionPolicy Bypass', $nTimeOut = 0, $bLoopRead = False) ; handling Default keyword word for the parameters If IsKeyWord($nFlags) = 1 Then $nFlags = 0x8 If IsKeyWord($sWorkDir) = 1 Then $sWorkDir = "" If IsKeyWord($sOptions) = 1 Then $sOptions = '-NoProfile -ExecutionPolicy Bypass' ; format command as call parameter, passed to powershell.exe $sCmd = StringFormat('powershell.exe %s -Command "%s"', $sOptions, StringReplace($sCmd, '"', '\"',0,1)) ; start the cmd/process Local $iPID = Run($sCmd, $sWorkDir, @SW_Hide, $nFlags) If @error Then Return SetError(1, @error, "") Local $iExit, $sStdOut = "", $sStdErr = "" If $bLoopRead Then ; fill stdout and/or stderr over a loop Do If BitAND($nFlags, 0x4) Then $sStdErr &= StderrRead($iPID) $sStdOut &= StdoutRead($iPID) If @error Then ExitLoop Until 0 ; determine the exit code $iExit = ProcessWaitClose($iPID, 0) ElseIf ProcessWaitClose($iPID, $nTimeOut) = 0 Then ; wait until process ends Return SetError(2, 0, "") Else ; read out the process results in one go $iExit = @extended $sStdOut = StdoutRead($iPID) $sStdErr = BitAND($nFlags, 0x4) ? StderrRead($iPID) : "" EndIf ; return only stderr If $nFlags = 0x4 Then Return SetExtended($iExit, _WinAPI_OemToChar($sStdErr)) ; return array if stdout and stderr should be read separately ElseIf $nFlags = 0x6 Then Local $aRet[2] = [_WinAPI_OemToChar($sStdOut), _WinAPI_OemToChar($sStdErr)] Return SetError($sStdErr = "" ? 0 : 3, $iExit, $aRet) EndIf ; return a string Return SetExtended($iExit, _WinAPI_OemToChar($sStdOut)) EndFunc3 points -
MiniMark (a minimalistic rtf editor)
Skeletor and 2 others reacted to TheAutomator for a topic
To test as intended: see read me! file in zip This program is still under development, but feel free to make this code better with suggestions and better code There are some (closed) tickets for bugs in _GUICtrlRichEdit_StreamToFile and _GUICtrlRichEdit_GetZoom so the script uses workarounds until the next AutoIt update: https://www.autoitscript.com/trac/AutoIt/ticket/4038#ticket https://www.autoitscript.com/trac/AutoIt/ticket/4040#ticket Wanna take a look at the code? Here you go: #cs name: MiniMark function: a minimalistic editor for custom rtf files version: 4 made by: TheAutomator project: https://www.autoitscript.com/forum/topic/212763-minimark-a-minimalistic-rtf-editor todo: • make user level install possible (requested by argumentum) • allow dropping files to gui • consider sort lines, remove duplicate lines, remove whitespace button • add file changed indicator • add right click menu on edit • check if programfiles exist when opened • look into embedding images and sounds into compiled exe • make variable names better (AutoIt rules) • make tab behave correctly • handle double click behaviour on controls • figure out how to deal with saving zoom amount bug • $ws_clipsiblings needed for overlapping? bugs in AutoIt rich edit functions: https://www.autoitscript.com/trac/AutoIt/ticket/4038#ticket https://www.autoitscript.com/trac/AutoIt/ticket/4040#ticket should be fixed in the next AutoIt version! remarks: to install and test MiniMark as intended: • compile minimark to exe (with options) • compile setup to exe (with options) • use the setup to install MiniMark • restart computer (if things don't update directly) • rightclick to create a new mnm file • double click it and tadaaaah! hystory: version 1 + added some changes inspired by Werty + code revised + added functionality like opening files with a window, noticed by Argumentum + added sounds version 2 + scrolling is now possible thanks to Pixelsearch + scroll code was revised by Nine - changed some code to prevent a sound to be played twice + added "return $gui_rundefmsg" to "func wm_command" version 3 + made an installer/uninstaller (needs install path choice) - removed unnecessary guictrlcreatedummy code + undo buffer is set to empty when file loaded + added search function with custom gui (work in progress) + added scroll bar (that is buggy AF) version 4 (still in beta) + code revised again + made find and replace work better + better custom scrollbar (based on cursor position in edit) + added "save as" shortcut + added option to silence sounds + added option to save zoom amount (bug -> see ticket) + new search gui + added settings gui + added ini file to save settings + added custom popups in same style as MiniMark + added about button with link to forum + added per-monitor v2 dpi awareness (requires windows 10 creators update or later) + added better way to create controls on the fly (not as many images needed) + added checkmarks + added upper and lower case hotkeys + added incert date and time hotkey + scroll bar major update (special thanks to Pixelsearch for all the help with the code!) #ce #Region au3 #autoit3wrapper_icon=setup\icon.ico #autoit3wrapper_outfile_x64=MiniMark\MiniMark.exe #autoit3wrapper_usex64=y #NoTrayIcon #include <guirichedit.au3> #include <guiconstants.au3> #include <winapisyswin.au3> #include <array.au3> #include <date.au3> #EndRegion au3 #Region MiniMark constants ; colors Const $color_text_white = 0x00ffffff Const $color_text_gray = 0x00c0c0c0 Const $color_element_gray = 0x606060 Const $color_control_gray = 0x404040 Const $color_border_gray = 0x202020 Const $color_text_red = 0x006600ff Const $color_text_green = 0x0000ff66 Const $color_text_blue = 0x00ff6600 Const $color_transparent_background = 0xff00ff ; font names Const $font_handel_gothic_bt = 'handelgothic bt' Const $font_lucida_console = 'lucida console' ; sound effects Const $sound_start = @ScriptDir & '\sounds\start.wav' Const $sound_click = @ScriptDir & '\sounds\click.wav' Const $sound_alert = @ScriptDir & '\sounds\alert.wav' Const $sound_stop = @ScriptDir & '\sounds\stop.wav' ; user interface images Const $image_alert = @ScriptDir & '\images\alert.bmp' Const $image_button = @ScriptDir & '\images\button.bmp' Const $image_MiniMark = @ScriptDir & '\images\MiniMark.bmp' Const $image_scroll = @ScriptDir & '\images\scroll.bmp' Const $image_scroll_down = @ScriptDir & '\images\scroll_down.bmp' Const $image_scroll_up = @ScriptDir & '\images\scroll_up.bmp' Const $image_search = @ScriptDir & '\images\search.bmp' Const $image_settings = @ScriptDir & '\images\settings.bmp' Const $image_size_down = @ScriptDir & '\images\size_down.bmp' Const $image_size_up = @ScriptDir & '\images\size_up.bmp' Const $image_tick_on = @ScriptDir & '\images\tick_on.bmp' Const $image_tick_off = @ScriptDir & '\images\tick_off.bmp' ; files Const $file_intro = @ScriptDir & '\data\MiniMark.mnm' Const $file_settings = @ScriptDir & '\data\settings.ini' #EndRegion MiniMark constants #Region custom gui create functions ; create titles. Func title_create($title, $w) Local $title_handle = GUICtrlCreateLabel($title, 5, 5, $w, 20, BitOR($ss_centerimage, $ss_center), $gui_ws_ex_parentdrag) ; use label to drag form GUICtrlSetFont(Default, 12, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $gui_bkcolor_transparent) Return $title_handle EndFunc ;==>title_create ; create buttons. Func button_create($text, $tip, $sub, $x, $y) Local $button_handle = GUICtrlCreatePic($image_button, $x, $y, 70, 20) GUICtrlSetTip(Default, $tip, $sub) Local $button_label = GUICtrlCreateLabel($text, $x, $y, 70, 20, BitOR($ss_centerimage, $ss_center)) GUICtrlSetFont(Default, 9, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $gui_bkcolor_transparent) Return $button_handle EndFunc ;==>button_create ; create checkboxes. Func checkbox_create($text, $tip, $sub, $x, $y, $state = 0) Local $checkbox_handle = GUICtrlCreatePic($state ? $image_tick_on : $image_tick_off, $x, $y, 70, 20) GUICtrlSetTip(Default, $tip, $sub) Local $checkbox_label = GUICtrlCreateLabel($text, $x, $y, 50, 20, BitOR($ss_centerimage, $ss_center)) GUICtrlSetFont(Default, 9, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $gui_bkcolor_transparent) Return $checkbox_handle EndFunc ;==>checkbox_create ; create inputs (+5 on the left, -5 on the right; so we don't overlap the corners). Func input_create($x, $y, $tip) Local $input_handle = GUICtrlCreateInput('', $x, $y, 210, 20, $es_autohscroll, 0) GUICtrlSetTip(Default, $tip) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $color_control_gray) GUICtrlSetFont(Default, 12, 400, 0, $font_handel_gothic_bt) Return $input_handle EndFunc ;==>input_create #EndRegion custom gui create functions #Region checkbox messages Func checkbox_toggle($checkbox_handle, ByRef $checkbox_state) play_sound($sound_click) $checkbox_state = $checkbox_state ? 0 : 1 GUICtrlSetImage($checkbox_handle, $checkbox_state ? $image_tick_on : $image_tick_off) EndFunc ;==>checkbox_toggle #EndRegion checkbox messages #Region sound effects $checkbox_sound_state = Int(IniRead($file_settings, 'settings', 'sound', 1)) ; read from ini Func play_sound($name, $wait = 0) If $checkbox_sound_state Then SoundPlay($name, $wait) EndFunc ;==>play_sound #EndRegion sound effects #Region custom msgbox ; alert constants Const $alert_ok = 0 Const $alert_link_close = 1 Const $alert_yes_no_cancel = 2 ; a custom messagebox, used for warnings and notifications Func alert($title = 'Alert', $text = '', $type = $alert_ok) Local $alert_form = GUICreate('Alert', 230, 120, Default, Default, $ws_popup, BitOR($ws_ex_layered, $ws_ex_topmost)) GUISetBkColor($color_transparent_background) Local $alert_background = GUICtrlCreatePic($image_alert, 0, 0, 230, 120) GUICtrlSetState(Default, $gui_disable) Local $alert_title = title_create($title, 220) Local $alert_text = GUICtrlCreateLabel($text, 10, 35, 210, 50, $ss_center) ;, bitor($ss_centerimage, $ss_center, $bs_multiline)) GUICtrlSetFont(Default, 8, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $color_control_gray) Local $alert_button_1 = -14, $alert_button_2 = -14, $alert_button_3 = -14 Switch $type Case $alert_ok $alert_button_2 = button_create('Ok', '', Default, 80, 95) Case $alert_link_close $alert_button_1 = button_create('Link', 'Go to the AutoIt forum to check for MiniMark updates.', Default, 5, 95) $alert_button_3 = button_create('Close', '', Default, 155, 95) Case $alert_yes_no_cancel $alert_button_1 = button_create('Yes', '', Default, 5, 95) $alert_button_2 = button_create('No', '', Default, 80, 95) $alert_button_3 = button_create('Cancel', '', Default, 155, 95) EndSwitch _WinAPI_SetLayeredWindowAttributes($alert_form, $color_transparent_background) ; set the transparant gui color GUISetState(@SW_SHOW) play_sound($sound_alert) Local $choice ; to return what button was clicked While 1 Switch GUIGetMsg() Case $gui_event_close $choice = 0 ExitLoop Case $alert_button_1 $choice = 1 ExitLoop Case $alert_button_2 $choice = 2 ExitLoop Case $alert_button_3 $choice = 3 ExitLoop EndSwitch WEnd play_sound($sound_click) GUIDelete($alert_form) Return $choice EndFunc ;==>alert #EndRegion custom msgbox #Region dll calls ; set per-monitor v2 dpi awareness (requires windows 10 creators update or later) dllcall("user32.dll", "bool", "setprocessdpiawarenesscontext", "ptr", -4) #EndRegion dll calls #Region parameters Func get_filename() Local $path_split = StringSplit($cmdline[1], '\', 3) Return StringTrimRight($path_split[UBound($path_split) - 1], 4) EndFunc ;==>get_filename Func wrong_file_extension($path = $cmdline[1]) Return StringRight($path, 4) <> '.mnm' EndFunc ;==>wrong_file_extension Func set_default_file() Global $cmdline = [1, $file_intro] ; overwrite if empty to load default intro file EndFunc ;==>set_default_file If $cmdline[0] = 1 Then If wrong_file_extension() Then alert('Wrong file type!', 'You can only open *.mnm files with this program.', $alert_ok) set_default_file() EndIf Else set_default_file() EndIf #EndRegion parameters #Region MiniMark gui $MiniMark_form = GUICreate('MiniMark', 380, 480, Default, Default, $ws_popup, $ws_ex_layered) GUISetBkColor($color_border_gray) $MiniMark_background = GUICtrlCreatePic($image_MiniMark, 0, 0, 380, 480) GUICtrlSetState(Default, $gui_disable) $MiniMark_title = title_create(get_filename(), 370) $MiniMark_edit = _GUICtrlRichEdit_Create($MiniMark_form, 'Loading...', 10, 35, 270, 435, BitOR($es_multiline, $es_autovscroll, $es_nohidesel), 0) ; $es_nohidesel for visible selection when using search function _GUICtrlRichEdit_SetBkColor($MiniMark_edit, $color_control_gray) $button_settings = button_create('Options', 'Open settings.', Default, 305, 30) $button_open = button_create('Open', 'Open a new *.mnm file.', 'ctrl + o', 305, 55) $button_save = button_create('Save', 'Save file / save file as.', 'ctrl + s / shift + ctrl + s', 305, 80) $save_as = GUICtrlCreateDummy() $button_search = button_create('Search', 'Find and replace text.', 'ctrl + f', 305, 105) $button_upper = button_create('Upper', 'Make selection upper case.', 'escape', 305, 130) $button_lower = button_create('Lower', 'Make selection lower case.', 'escape', 305, 155) $button_bold = button_create('Bold', 'Make selection bold.', 'ctrl + b', 305, 180) $button_italic = button_create('Italic', 'Make selection italic.', 'ctrl + i', 305, 205) $button_struck = button_create('Struck', 'Make selection struck.', 'ctrl + t', 305, 230) $button_underline = button_create('Underline', 'Make selection underlined.', 'ctrl + u', 305, 255) $button_red = button_create('Red', 'Make selection red.', 'shift + ctrl + r', 305, 280) $button_green = button_create('Green', 'Make selection green.', 'shift + ctrl + g', 305, 305) $button_blue = button_create('Blue', 'Make selection blue.', 'shift + ctrl + b', 305, 330) $button_white = button_create('White', 'Make selection white.', 'shift + ctrl + w', 305, 355) $button_default = button_create('Default', 'Make selection default style and gray.', 'shift + ctrl + d', 305, 380) $button_tick = button_create('Tick', 'Add a checkmark or toggle it.', 'shift + ctrl + d', 305, 405) $button_now = button_create('Time', 'Insert the current date and time.', 'shift + ctrl + d', 305, 430) $button_quit = button_create('Quit', 'Quit the program.', 'escape', 305, 455) $MiniMark_scroll_up = GUICtrlCreatePic($image_scroll_up, 290, 30, 10, 10) $MiniMark_scroll_thumb = GUICtrlCreatePic($image_scroll, 290, 45, 10, 40) ; scroll background: 290, 45, 10, 315 $MiniMark_scroll_down = GUICtrlCreatePic($image_scroll_down, 290, 465, 10, 10) _WinAPI_SetLayeredWindowAttributes($MiniMark_form, $color_transparent_background) ;set the transparant gui color GUISetState(@SW_SHOW, $MiniMark_form) play_sound($sound_start) ; play MiniMark startup sound. #EndRegion MiniMark gui #Region markup functions ; function that handles text color actions. Func colorize($color) ; if already in selected color -> make default color again play_sound($sound_click) If _GUICtrlRichEdit_GetCharColor($MiniMark_edit) <> $color Then _GUICtrlRichEdit_SetCharColor($MiniMark_edit, $color) Else _GUICtrlRichEdit_SetCharColor($MiniMark_edit, $color_text_gray) EndIf If $color = $color_text_gray Then _GUICtrlRichEdit_SetCharAttributes($MiniMark_edit, '-bo-it-un-st') EndFunc ;==>colorize ; function that handles text style actions. Func stylize($style) ; if already in selected style -> undo style play_sound($sound_click) If StringInStr(_GUICtrlRichEdit_GetCharAttributes($MiniMark_edit), $style & '+') Then _GUICtrlRichEdit_SetCharAttributes($MiniMark_edit, '-' & $style) Else _GUICtrlRichEdit_SetCharAttributes($MiniMark_edit, '+' & $style) EndIf EndFunc ;==>stylize #EndRegion markup functions #Region tools Func change_case($upper) Local $selection = _GUICtrlRichEdit_GetSel($MiniMark_edit) If $selection[0] = $selection[1] Then Return Local $selection_text = _GUICtrlRichEdit_GetSelText($MiniMark_edit) If $upper Then $selection_text = StringUpper($selection_text) Else $selection_text = StringLower($selection_text) EndIf _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $selection_text) _GUICtrlRichEdit_SetSel($MiniMark_edit, $selection[0], $selection[1]) EndFunc Func tickmark() Local $first_char = _GUICtrlRichEdit_GetFirstCharPosOnLine($MiniMark_edit) Local $line_from_char = _GUICtrlRichEdit_GetLineNumberFromCharPos($MiniMark_edit, $first_char) Local $tick_type = StringLeft(_GUICtrlRichEdit_GetTextInLine($MiniMark_edit, $line_from_char), 1) Local $tick_replace Switch $tick_type ; ■□○●• Case '☐' $tick_replace = '☑' Case '☑' $tick_replace = '☐' Case Else _GUICtrlRichEdit_SetSel($MiniMark_edit, $first_char, $first_char) _GUICtrlRichEdit_InsertText($MiniMark_edit, '☐ ') Return endSwitch _GUICtrlRichEdit_SetSel($MiniMark_edit, $first_char, $first_char + 1) _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $tick_replace) EndFunc #EndRegion tools #Region edit and scrollbar messages ; the scrollbar of hell! ; https://www.autoitscript.com/forum/topic/212778-goto-specific-line-in-rich-edit-control AutoItSetOption('MouseCoordMode', 2) ; 2 = relative coords to the client area of the active window _GUICtrlRichEdit_SetEventMask($MiniMark_edit, $enm_scrollevents) $Scrolling = False func MouseOnTumb() local $MouseXY = MouseGetPos() static local $BarX = 290 static local $BarY = 45 static local $BarWidth = 10 static local $BarHeight = 415 if $MouseXY[0] >= $BarX and $MouseXY[0] <= $BarX + $BarWidth and $MouseXY[1] >= $BarY and $MouseXY[1] <= $BarY + $BarHeight then $Scrolling = True ConsoleWrite(@CRLF & "SCROLLING -> " & $Scrolling) EndFunc guiregistermsg($wm_command, wm_command) func wm_command($hwnd, $imsg, $wparam, $lparam) if $scrolling then return $gui_rundefmsg if $lparam <> $minimark_edit then return $gui_rundefmsg if bitshift($wparam, 16) = $en_update then updatetumbposition() if _guictrlrichedit_istextselected($minimark_edit) then return $gui_rundefmsg if _guictrlrichedit_getfont($minimark_edit)[1] <> $font_lucida_console then _guictrlrichedit_setfont($minimark_edit, 9, $font_lucida_console) _guictrlrichedit_setcharcolor($minimark_edit, $color_text_gray) endif return $gui_rundefmsg endfunc guiregistermsg($wm_notify, wm_notify) func wm_notify($hwnd, $imsg, $wparam, $lparam) local $tfilter = dllstructcreate($tagmsgfilter, $lparam) if $tfilter.hwndfrom = $minimark_edit then _guictrlrichedit_scrolllines($tfilter.hwndfrom, $tfilter.wparam ? 1 : -1) return $gui_rundefmsg endfunc Func UpdateTumbPosition() local $LineFirst = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($minimark_edit) static local $EditHeight = 435 local $LineLast = _GUICtrlRichEdit_GetLineNumberFromCharPos($minimark_edit, _GUICtrlRichEdit_GetCharPosFromXY($minimark_edit, 1, $EditHeight)) local $LineCount = _GUICtrlRichEdit_GetLineCount($minimark_edit) local $LinesVisible = $LineLast - $LineFirst + 1 ; "+ 1" = count last visible line too local $MaxScrollableLines = $LineCount - $LinesVisible local $EditPercent = 0 If $MaxScrollableLines > 0 Then $EditPercent = ($LineFirst - 1) / $MaxScrollableLines ; "> 0" to prevent division by 0 static local $BarY = 45 static local $BarHeight = 415 static local $TumbX = 290 static local $TumbHeight = 40 local $TumbY = $BarY + $EditPercent * ($BarHeight - $TumbHeight) GUICtrlSetPos($MiniMark_scroll_thumb, $TumbX, $TumbY) EndFunc Func UpdateEditPosition() local $MouseY = MouseGetPos(1) static local $TumbHeight = 40 local $TumbY = $MouseY - $TumbHeight / 2 static local $BarY = 45 If $TumbY < $BarY Then $TumbY = $BarY static local $BarHeight = 415 static local $TumbMax = $BarY + $BarHeight - $TumbHeight If $TumbY > $TumbMax Then $TumbY = $TumbMax static local $TumbX = 290 GUICtrlSetPos($MiniMark_scroll_thumb, $TumbX, $TumbY) local $TumbPercent = ($TumbY - $BarY) / ($TumbMax - $BarY) local $LineFirst = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($minimark_edit) static local $EditHeight = 435 local $LineLast = _GUICtrlRichEdit_GetLineNumberFromCharPos($minimark_edit, _GUICtrlRichEdit_GetCharPosFromXY($minimark_edit, 1, $EditHeight)) local $LineCount = _GUICtrlRichEdit_GetLineCount($minimark_edit) local $LinesVisible = $LineLast - $LineFirst local $LineTop = $TumbPercent * ($LineCount - $LinesVisible) + 1 ; "+ 1" = becouse it's a 1-based system for line positions _GUICtrlRichEdit_ScrollLines($minimark_edit, $LineTop - $LineFirst) EndFunc #EndRegion edit and scrollbar messages #Region shortcuts ; here we set all the shortcuts for the buttons. Dim $hotkeysaccel[18][2] = [ _ ['+^d', $button_default], _ ['^b', $button_bold], _ ['^i', $button_italic], _ ['^u', $button_underline], _ ['^t', $button_struck], _ ['+^r', $button_red], _ ['+^g', $button_green], _ ['+^b', $button_blue], _ ['+^w', $button_white], _ ['^o', $button_open], _ ['^s', $button_save], _ ['+^s', $save_as], _ ['{f5}', $button_now], _ ['!t', $button_tick], _ ['!u', $button_upper], _ ['!l', $button_lower], _ ['^f', $button_search], _ ['{esc}', $button_quit] _ ] GUISetAccelerators($hotkeysaccel, $MiniMark_form) #EndRegion shortcuts #Region search gui $search_form = GUICreate('Search', 305, 105, Default, Default, $ws_popup, BitOR($ws_ex_layered, $ws_ex_topmost)) GUISetBkColor($color_transparent_background) GUICtrlCreatePic($image_search, 0, 0, 305, 105) GUICtrlSetState(Default, $gui_disable) $search_title = title_create('Find and replace', 295) $input_find = input_create(10, 30, 'What to look for.') $input_replace = input_create(10, 55, 'Replace by what.') $checkbox_case_state = 0 $checkbox_case = checkbox_create('Case', 'Toggle casesence.', Default, 230, 30) $checkbox_word_state = 0 $checkbox_word = checkbox_create('Word', 'Toggle whole word only.', Default, 230, 55) $button_search_find = button_create('Find', 'find string.', Default, 5, 80) $button_search_replace = button_create('Replace', 'Replace current match.', Default, 80, 80) $button_search_replace_all = button_create('Replace all', 'Replace all matches.', Default, 155, 80) $button_search_close = button_create('Close', '', Default, 230, 80) _WinAPI_SetLayeredWindowAttributes($search_form, $color_transparent_background) ;set the transparant gui color #EndRegion search gui #Region search functions Func find() Local $find_text = GUICtrlRead($input_find) If $find_text = '' Then Return play_sound($sound_click) Local $selection = _GUICtrlRichEdit_GetSel($MiniMark_edit) $selection = _GUICtrlRichEdit_FindTextInRange($MiniMark_edit, $find_text, $selection[1], -1, $checkbox_case_state = 1, $checkbox_word_state = 1) If $selection[0] = -1 And $selection[1] = -1 Then alert('Search ended', 'No more matches found.' & @CRLF & 'Next time when you press the [Find] button, the search function will start looking from the beginning of the text.', $alert_ok) _GUICtrlRichEdit_SetSel($MiniMark_edit, 0, 0) Else _GUICtrlRichEdit_SetSel($MiniMark_edit, $selection[0], $selection[1]) EndIf EndFunc ;==>find Func replace() Local $find_text = GUICtrlRead($input_find) If $find_text = '' Then Return play_sound($sound_click) Local $replace_text = GUICtrlRead($input_replace) _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $replace_text) find() EndFunc ;==>replace Func replace_all() Local $find_text = GUICtrlRead($input_find) If $find_text = '' Then Return play_sound($sound_click) Local $replace_text = GUICtrlRead($input_replace) Local $selection = _GUICtrlRichEdit_FindTextInRange($MiniMark_edit, $find_text, 0, -1, $checkbox_case_state = 1, $checkbox_word_state = 1) While $selection[0] > -1 And $selection[1] > -1 _GUICtrlRichEdit_SetSel($MiniMark_edit, $selection[0], $selection[1]) _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $replace_text) $selection = _GUICtrlRichEdit_FindTextInRange($MiniMark_edit, $find_text, $selection[1], -1, $checkbox_case_state = 1, $checkbox_word_state = 1) WEnd alert('Search ended', 'No more matches found.' & @CRLF & 'All matches are replaced (if there were are any).', $alert_ok) EndFunc ;==>replace_all Func find_and_replace() play_sound($sound_click) local $selection_text = _GUICtrlRichEdit_GetSelText($MiniMark_edit) if @error <> -1 then GUICtrlSetData($input_find, $selection_text) GUISetState(@SW_SHOW, $search_form) While 1 Switch GUIGetMsg() Case $gui_event_close, $button_search_close play_sound($sound_click) GUISetState(@SW_HIDE, $search_form) ExitLoop Case $checkbox_case checkbox_toggle($checkbox_case, $checkbox_case_state) Case $checkbox_word checkbox_toggle($checkbox_word, $checkbox_word_state) Case $button_search_find find() Case $button_search_replace replace() Case $button_search_replace_all replace_all() EndSwitch WEnd EndFunc #EndRegion search functions #Region settings $font_size = Int(IniRead($file_settings, 'settings', 'fontsize', 100)) $settings_form = GUICreate('Settings', 230, 80, Default, Default, $ws_popup, BitOR($ws_ex_layered, $ws_ex_topmost)) GUISetBkColor($color_transparent_background) GUICtrlCreatePic($image_settings, 0, 0, 230, 80) GUICtrlSetState(Default, $gui_disable) $settings_title = title_create('Settings', 220) $checkbox_sound = checkbox_create('Sound', 'play sounds?', Default, 5, 30, $checkbox_sound_state) $button_settings_save = button_create('Save', 'Save settings.', Default, 5, 55) $button_settings_info = button_create('Info', 'About MiniMark.', Default, 155, 30) $button_settings_reset = button_create('Reset', 'Reset to default settings.', Default, 80, 55) $button_settings_close = button_create('Close', '', Default, 155, 55) $number_step = GUICtrlCreateInput($font_size, 85, 30, 45, 20, BitOR($es_center, $es_number, $es_autohscroll), 0) GUICtrlSetTip(Default, 'Custom font size (zoom).') GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $color_control_gray) GUICtrlSetFont(Default, 12, 400, 0, $font_handel_gothic_bt) GUICtrlSetLimit(Default, 8) $number_step_up = GUICtrlCreatePic($image_size_up, 130, 30, 20, 10) $number_step_down = GUICtrlCreatePic($image_size_down, 130, 40, 20, 10) _WinAPI_SetLayeredWindowAttributes($settings_form, $color_transparent_background) ;set the transparant gui color #EndRegion settings #Region settings function Func settings() play_sound($sound_click) GUICtrlSetData($number_step, Int(_GUICtrlRichEdit_GetZoom($MiniMark_edit))) GUISetState(@SW_SHOW, $settings_form) While 1 Switch GUIGetMsg() Case $gui_event_close, $button_settings_close play_sound($sound_click) GUISetState(@SW_HIDE, $settings_form) ExitLoop Case $checkbox_sound checkbox_toggle($checkbox_sound, $checkbox_sound_state) Case $number_step_up number_step(1) Case $number_step_down number_step(-1) Case $button_settings_info If alert('About', 'MiniMark version 4.' & @CRLF & 'Created by:' & @CRLF & 'Tom Schrauwen (TheAutomator).', $alert_link_close) = 1 Then ShellExecute('https://www.autoitscript.com/forum/topic/212763-MiniMark-a-minimalistic-rtf-editor') Case $button_settings_reset settings_reset() Case $button_settings_save settings_save() EndSwitch WEnd EndFunc #EndRegion settings function #Region settings messages ; write ini Func number_step($amount) Local $number = GUICtrlRead($number_step) $number += $amount GUICtrlSetData($number_step, $number) play_sound($sound_click) EndFunc ;==>number_step Func settings_reset() If Not $checkbox_sound_state Then checkbox_toggle($checkbox_sound, $checkbox_sound_state) GUICtrlSetData($number_step, 100) play_sound($sound_click) EndFunc ;==>settings_reset Func settings_save() IniWrite($file_settings, 'settings', 'sound', $checkbox_sound_state) IniWrite($file_settings, 'settings', 'fontsize', GUICtrlRead($number_step)) _GUICtrlRichEdit_SetZoom($MiniMark_edit, GUICtrlRead($number_step)) play_sound($sound_click) EndFunc ;==>settings_save #EndRegion settings messages #Region file functions ; if this is not the case, or when there are no arguments, we just open the intro file instead. ; also extract the filename from $cmdline to display as title. Func load_file() ; add fileexists check? GUICtrlSetData($MiniMark_title, get_filename()) GUICtrlSetTip($MiniMark_title, $cmdline[1]) ; display full path on mouse over title _GUICtrlRichEdit_Deselect($MiniMark_edit) _GUICtrlRichEdit_StreamFromFile($MiniMark_edit, $cmdline[1]) _GUICtrlRichEdit_SetZoom($MiniMark_edit, Int($font_size)) ; needed becouse it resets after loading (https://www.autoitscript.com/forum/topic/190695-_guictrlrichedit_setzoom-parameter-limitation) _GUICtrlRichEdit_SetModified($MiniMark_edit, False) _GUICtrlRichEdit_EmptyUndoBuffer($MiniMark_edit) updatetumbposition() EndFunc ;==>load_file load_file() ; load input file ; before opening another file or before quitting, we need to check if the current file is modified. Func save_changes_cancel() ; returns true if we wanna cancel follow up actions If Not _GUICtrlRichEdit_IsModified($MiniMark_edit) Then Return Switch alert('Save changes?', 'This file was modified.' & @CRLF & 'Do you wanna save your work first?', $alert_yes_no_cancel) Case 1 ; yes save_file() Case 2 ; no Return Case Else Return True ; abort next actions EndSwitch EndFunc ;==>save_changes_cancel ; the function that saves the current text to a *.mnm file. ; _guictrlrichedit_streamtofile($edit, $cmdline[1]) -> bug, adds new paragraph every time (see ticket). Func save_file($as = False) ; as triggers a save to dialog If $as Then play_sound($sound_click) Local $new_file = FileSaveDialog('Save MiniMark file...', @DesktopDir, 'MiniMark file (*.mnm)', 16, '', $MiniMark_form) If @error Or wrong_file_extension() Then Return $cmdline[1] = $new_file GUICtrlSetTip($MiniMark_title, $new_file) ; display full path on mouse over title GUICtrlSetData($MiniMark_title, get_filename()) Else If Not _GUICtrlRichEdit_IsModified($MiniMark_edit) Then Return play_sound($sound_click) EndIf _GUICtrlRichEdit_Deselect($MiniMark_edit) Local $var = _GUICtrlRichEdit_StreamToVar($MiniMark_edit) $var = StringTrimRight($var, 9) & "}" ; bug will be resolved in future versions Local $file = FileOpen($cmdline[1], $fo_overwrite) Local $written = FileWrite($file, $var) FileClose($file) If $written = 1 Then ; 0 = failed to write, 1 = succes _GUICtrlRichEdit_SetModified($MiniMark_edit, False) Else alert('File write error!', "Can't save the file..." & @CRLF & 'Check if the file is read only.', $alert_ok) EndIf EndFunc ;==>save_file ; open a file with the open dialog. Func open_file() If save_changes_cancel() Then Return play_sound($sound_click) Local $file = FileOpenDialog('Open new MiniMark file...', @DesktopDir, 'MiniMark file (*.mnm)', 3, '', $MiniMark_form) If @error Or wrong_file_extension() Then Return $cmdline[1] = $file load_file() EndFunc ;==>open_file #EndRegion file functions #Region quit function ; when the program unloads we need to destroy the rich edit control and play the stop sound Func quit() If save_changes_cancel() Then Return play_sound($sound_stop, 1) _GUICtrlRichEdit_Destroy($MiniMark_edit) GUIDelete() Exit EndFunc ;==>quit #EndRegion quit function #Region main loop While 1 Switch GUIGetMsg() Case $gui_event_close, $button_quit quit() Case $button_now _GUICtrlRichEdit_InsertText($MiniMark_edit, _now()) Case $button_tick tickmark() Case $button_upper change_case(True) Case $button_lower change_case(False) Case $MiniMark_scroll_up play_sound($sound_click) _GUICtrlRichEdit_ScrollLines($MiniMark_edit, -1) Case $MiniMark_scroll_down play_sound($sound_click) _GUICtrlRichEdit_ScrollLines($MiniMark_edit, 1) Case $button_open open_file() Case $button_save save_file() Case $save_as save_file(True) Case $button_bold stylize('bo') Case $button_italic stylize('it') Case $button_struck stylize('st') Case $button_underline stylize('un') Case $button_red colorize($color_text_red) Case $button_green colorize($color_text_green) Case $button_blue colorize($color_text_blue) Case $button_white colorize($color_text_white) Case $button_default colorize($color_text_gray) Case $gui_event_primarydown MouseOnTumb() Case $gui_event_mousemove if $Scrolling then UpdateEditPosition() Case $gui_event_primaryup $Scrolling = False Case $button_search find_and_replace() Case $button_settings settings() EndSwitch WEnd #EndRegion main loop And here is the code for the installer: SETUP FOR VERSION 4 STILL IN THE MAKING! #cs function: installer for MiniMark version: 3 made by: TheAutomator project: https://www.autoitscript.com/forum/topic/212763-minimark-a-minimalistic-rtf-editor todo: • check if programfiles exist when opened • add choice for install path and user level install • installer does'nt use the "fileinstall" function (yet) #ce #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #autoit3wrapper_icon=setup\setup.ico #autoit3wrapper_outfile=Setup.EXE #autoit3wrapper_compression=4 #autoit3wrapper_useupx=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #NoTrayIcon #RequireAdmin #include <guiconstants.au3> #include <winapisyswin.au3> const $source_path = @ScriptDir & '\minimark' const $setup_path = @ScriptDir & '\setup' const $install_path = @ProgramFilesDir & '\MiniMark' const $install_font = @ScriptDir & '\setup\handelgo.ttf' const $font_lucida = 'lucida console' const $image_background = @scriptdir & '\setup\setup.bmp' const $image_install = @scriptdir & '\setup\install.bmp' const $image_remove = @scriptdir & '\setup\remove.bmp' const $image_exit = @scriptdir & '\minimark\exit.bmp' const $color_gui_transparant = 0xff00ff const $color_edit_background = 0x323232 const $color_edit_gray = 0xb4b4b4 const $color_edit_red = 0xff0066 const $color_edit_green = 0x66ff00 const $sound_start = @scriptdir & '\minimark\start.wav' const $sound_click = @scriptdir & '\minimark\click.wav' const $sound_alert = @scriptdir & '\minimark\alert.wav' const $sound_stop = @scriptdir & '\minimark\stop.wav' local $check_installed = FileExists($install_path) soundplay($sound_start) ; startup sound $form = guicreate('MiniMark Setup', 310, 240, default, default, $ws_popup, $ws_ex_layered) guisetbkcolor($color_gui_transparant) $title = guictrlcreatelabel('', 10, 10, 280, 20, $SS_GRAYRECT, $gui_ws_ex_parentdrag) ; use label to drag form (hidden behind gui image) guictrlcreatepic($image_background, 0, 0, 310, 240) guictrlsetstate(default, $gui_disable) $console = GUICtrlCreateEdit('MiniMark V3 setup' & @CRLF & 'made by: TheAutomator', 20, 50, 270, 140, bitor($es_multiline, $es_autovscroll, $es_readonly), 0) GUICtrlSetColor(Default, $color_edit_gray) GUICtrlSetBkColor(Default, $color_edit_background) GUICtrlSetFont(Default, 9, 0, 0, $font_lucida) $button_install = guictrlcreatepic($check_installed ? $image_remove : $image_install, 10, 210, 50, 20) $button_exit = guictrlcreatepic($image_exit, 250, 210, 50, 20) $escape = guictrlcreatedummy() dim $hotkeysaccel[1][2] = [["{esc}", $escape]] guisetaccelerators($hotkeysaccel) _winapi_setlayeredwindowattributes($form, $color_gui_transparant) ; 0xff00ff is set as the transparant gui color guisetstate() func console($text) GUICtrlSetData($console, @crlf & @crlf & $text, 1) EndFunc console($check_installed ? 'it looks like MiniMark is already installed, press [remove] to uninstall' : 'it looks like MiniMark is not installed yet, press [install] to install it') func install_remove() ; needs admin rights, compiling installer to exe is probably needed... GUICtrlSetColor($console, $color_edit_green) soundplay($sound_click) GUICtrlSetState($button_install, $gui_hide) if $check_installed then ; remove it console('removing MiniMark from:') console($install_path) DirRemove($install_path, 1) console('removing MiniMark menu') RegDelete('HKEY_CLASSES_ROOT\.mnm') RegDelete('HKEY_CLASSES_ROOT\MiniMark') console('removing "handelgothic bt" font') RegDelete('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', 'HandelGothic BT (TrueType)') ; uninstall font in registery DllCall('gdi32.dll', 'int', 'RemoveFontResource', 'str', @WindowsDir & '\Fonts\handelgo.ttf') ; uninstall font in fonts folder DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', 0xFFFF, 'int', 0x1D, 'int', 0, 'int', 0) ; tell windows about font changes FileDelete(@WindowsDir & '\Fonts\handelgo.ttf') ; delete font in fonts folder $check_installed = FileExists($install_path) if $check_installed Then GUICtrlSetColor($console, $color_edit_red) soundplay($sound_alert) console('MiniMark was not removed correctly...') Else console('MiniMark was uninstalled succesfully!') EndIf Else ; install it console('installing MiniMark to:') console($install_path) DirCopy($source_path, $install_path, 1) ; $fc_overwrite console('installing MiniMark menu') RegWrite('HKEY_CLASSES_ROOT\.mnm', '', 'REG_SZ', 'MiniMark') ; add filetype RegWrite('HKEY_CLASSES_ROOT\.mnm', 'PerceivedType', 'REG_SZ', 'Document') ; tell windows it's a document RegWrite('HKEY_CLASSES_ROOT\.mnm\ShellNew', 'NullFile', 'REG_SZ', '') ; add it to the 'new' file menu RegWrite('HKEY_CLASSES_ROOT\MiniMark', '', 'REG_SZ', 'MiniMark File') ; add edit menu for *.mnm file RegWrite('HKEY_CLASSES_ROOT\MiniMark', 'BrowserFlags', 'REG_DWORD', '00000008') RegWrite('HKEY_CLASSES_ROOT\MiniMark', 'EditFlags', 'REG_DWORD', '00000000') RegWrite('HKEY_CLASSES_ROOT\MiniMark\DefaultIcon', '', 'REG_SZ', $install_path & '\MiniMark.exe,0') ; set icon for *.mnm file RegWrite('HKEY_CLASSES_ROOT\MiniMark\Shell\Open', 'Icon', 'REG_SZ', $install_path & '\MiniMark.exe,0') ; set icon for open menu RegWrite('HKEY_CLASSES_ROOT\MiniMark\Shell\Open\Command', '', 'REG_SZ', $install_path & '\MiniMark.exe "%1"') ; always open with MiniMark console('installing "handelgothic bt" font') FileCopy($install_font, @WindowsDir & '\Fonts\', 1) ; $FC_OVERWRITE (1) = overwrite existing files RegWrite('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', 'HandelGothic BT (TrueType)', 'REG_SZ', 'handelgo.ttf') ; install font in registery DllCall('gdi32.dll', 'int', 'AddFontResource', 'str', @WindowsDir & '\Fonts\handelgo.ttf') ; install font in fonts folder DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', 0xFFFF, 'int', 0x1D, 'int', 0, 'int', 0) ; tell windows about font changes DllCall('shell32.dll', 'none', 'SHChangeNotify', 'long', 0x08000000, 'uint', 0, 'ptr', 0, 'ptr', 0) ; refresh the icon cache (ie4uinit.exe -show) $check_installed = FileExists($install_path) if $check_installed Then console('MiniMark was installed succesfully!') Else GUICtrlSetColor($console, $color_edit_red) soundplay($sound_alert) console('MiniMark was not installed correctly...') EndIf EndIf guictrlsetimage($button_install, $check_installed ? $image_remove : $image_install) GUICtrlSetState($button_install, $gui_show) EndFunc func quit() soundplay($sound_stop, 1) exit endfunc while 1 switch guigetmsg() case $gui_event_close, $button_exit, $escape quit() case $button_install install_remove() endswitch wend Enjoy, TheAutomator. MiniMark 4 beta test.zip3 points -
Long time ago some posted a VB Wrapper for the controls To run them you need to install the VB6 Controls Runtime Plus 2.2 Dependency files: https://sourceforge.net/projects/vb6extendedruntime/ You only need this to install (not the rest !!) Once installed you can run the included AU3 Example scripts : I guess once you have installed the VB6 runtime control you can get the Edge Wrapper to work as well... Success _VB Controls.zip3 points
-
So hopefully there's a better way of doing this, but I was pretty happy when this actually worked! We've been looking at some MediaFoundation stuff recently - and in order to spin up the MFMediaEngine object you must provide an interface to handle callbacks. Basically you are meant to write your own handler with an IMFEventNotify interface, then pass it to the factory. But how do you do this in AutoIt? Well it seems you can dodgy something up! IMFEventNotify object inherits from IUnknown has 1 method of its own - EventNotify . write the 4 methods and throw them into memory with DllCallbackRegister. Grab all the function pointers and pop them into an array. You now have yourself a vtable. The pointer to a vtable is an interface ptr. And that is a COM object! #include <WinAPI.au3> Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_IMFMediaEngineNotify = "{fee7c112-e776-42b5-9bbf-0048524e2bd5}" Global Const $tag_IMFMediaEngineNotify = "EventNotify hresult(uint; ulong_ptr; uint);" ;The Obj will look like this in memory. ;Only 2 interfaces are supported, IUnknown, and one derived from IUnknown. - They both can coexist in the one place ;for a more complex object we might need to store the locations of multiple vtables, and return the correct one with QueryInterface. ; - pIface -> +- pVtab -> +- pQueryInterface ; | | ; +- iRefCnt +- pAddRef ; | ; +- pRelease ; | ; +- pEventNotify Local $tEventNotify_QI = DllCallbackRegister("IMFEventNotiy_QueryInterface", "long", "ptr;ptr;ptr") Local $tEventNotify_AR = DllCallbackRegister("IMFEventNotiy_AddRef", "long", "ptr") Local $tEventNotify_R = DllCallbackRegister("IMFEventNotiy_Release", "long", "ptr") Local $tEventNotify_EN = DllCallbackRegister("IMFEventNotiy_EventNotify", "long", "ptr;dword;dword_ptr;dword") Local $tIMFMediaEngineNotify_Vtab = DllStructCreate("ptr pQueryInterface;ptr pAddRef;ptr pRelease;ptr pEventNotify") $tIMFMediaEngineNotify_Vtab.pQueryInterface = DllCallbackGetPtr($tEventNotify_QI) $tIMFMediaEngineNotify_Vtab.pAddRef = DllCallbackGetPtr($tEventNotify_AR) $tIMFMediaEngineNotify_Vtab.pRelease = DllCallbackGetPtr($tEventNotify_R) $tIMFMediaEngineNotify_Vtab.pEventNotify = DllCallbackGetPtr($tEventNotify_EN) Local $tIMFMediaEngineNotify = DllStructCreate("ptr pVTab;int iRefCnt") $tIMFMediaEngineNotify.pVtab = DllStructGetPtr($tIMFMediaEngineNotify_Vtab) Func IMFEventNotiy_QueryInterface($pThis, $pIID, $ppObj) ; hResult = oThis.QueryInterface(In pIID, Out pObj*) Local $hResult = $S_OK If Not $ppObj Then Return $E_POINTER Local $tRetObj = DllStructCreate("ptr pObj", $ppObj) ;pObj is ByRef, so ppObj should always be provided. Switch _WinAPI_StringFromGUID($pIID) ;These interfaces are located where we currently are! ;So return ptr to self. Case $sIID_IMFMediaEngineNotify, $sIID_IUnknown $tRetObj.pObj = $pThis IMFEventNotiy_AddRef($pThis) Case Else $tRetObj.pObj = 0 $hResult = $E_NOINTERFACE EndSwitch Return $hResult EndFunc ;==>IMFEventNotiy_QueryInterface Func IMFEventNotiy_AddRef($pThis) ; iRefCnt = oThis.AddRef() Local $tThis = DllStructCreate("ptr VTab;int RefCnt", $pThis) $tThis.RefCnt += 1 Return $tThis.RefCnt EndFunc ;==>IMFEventNotiy_AddRef Func IMFEventNotiy_Release($pThis) ;iRefCnt = oThis.Release() Local $tThis = DllStructCreate("ptr VTab;int RefCnt", $pThis) $tThis.RefCnt -= 1 ;I guess we could probably do some cleanup once RefCnt = 0. ;Not sure how best to do that!. Return $tThis.RefCnt EndFunc ;==>IMFEventNotiy_Release ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Define Event handler. Func IMFEventNotiy_EventNotify($pThis, $iEvent, $iParam1, $iParam2) ConsoleWrite(StringFormat("EventRecieved! Event: %d, Param1: %d, Param2: %d", $iEvent, $iParam1, $iParam2) & @CRLF) EndFunc ;==>IMFEventNotiy_EventNotify ;Ready to go! Local $pIMFMediaEngineNotify = DllStructGetPtr($tIMFMediaEngineNotify) ; Interface ptr (to IMFMediaEngineNotify) IMFEventNotiy_AddRef($pIMFMediaEngineNotify) ;The oject exists in mem, so refCnt should start at 1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Local $oIMFMediaEngineNotify = ObjCreateInterface($pIMFMediaEngineNotify, $sIID_IMFMediaEngineNotify, $tag_IMFMediaEngineNotify) ConsoleWrite("IsObj($oIMFMediaEngineNotify) = " & IsObj($oIMFMediaEngineNotify) & @CRLF & @CRLF) ;Test some methods. - Get IUnknown Iface, then "release" it. ConsoleWrite("QueryInterface Test:" & @CRLF) Local $pIUnknown, $tGUID = _WinAPI_GUIDFromString($sIID_IUnknown) $oIMFMediaEngineNotify.QueryInterface(DllStructGetPtr($tGUID), $pIUnknown) ConsoleWrite(StringFormat("$pIUnknown = %s", Ptr($pIUnknown)) & @CRLF) Local $oIUnknown = ObjCreateInterface($pIUnknown, $sIID_IUnknown, "") ConsoleWrite("RefCnt = " & $oIUnknown.Release() & ", .Release()" & @CRLF & @CRLF) ;Test external Addref call. ConsoleWrite("AddRef Test:" & @CRLF) ConsoleWrite("RefCnt = " & $oIMFMediaEngineNotify.AddRef() & ", .AddRef()" & @CRLF) ConsoleWrite("RefCnt = " & $oIMFMediaEngineNotify.Release() & ", .Release()" & @CRLF & @CRLF) ;Send an event. ConsoleWrite("EventNotify Test:" & @CRLF) $oIMFMediaEngineNotify.EventNotify(1, 2, 3)3 points
-
I need an audio equalizer for my zPlayer
argumentum and 2 others reacted to MattyD for a topic
Hey CYCho I realize this doesn't really further our cause, but here's what I've managed to do with XAudio2 for what its worth. XAudio2.zip3 points -
Indeed, no need to register anything other than OrdoWebView2.ocx You just need a folder containing the files as shown in the figure below \MYFOLDER | OrdoWebView2.ocx | OrdoWebView2.au3 | OrdoWebView2_Demo.au3 | \---OrdoRC6 cairo_sqlite.dll DirectCOM.dll RC6.dll RC6Widgets.dll RegisterRC6inPlace.vbs RegisterRC6WidgetsInPlace.vbs WebView2Loader.dll _Library-Licenses.txt _Version-History.txt (You can find the necessary files in the 7z file in @Danyfirex's post as indicated in first post above) As @Ninedid, I also did the following: created a folder containing necessary files as above opened a DOS prompt with administrative rights; placed the current directory where the OrdoWebView2.ocx file is located I typed the following command: regsvr32 .\OrdoWebView2.ocx I received the popup message with the message "DllRegisterServer in .\OrdoWebView2.ocx succeeded" That's it, then running the OrdoWebView2_Demo.au3 file everything worked fine thanks all for the feedbacks2 points
-
Idk if this will make any difference, but when I registered the ocx I was inside the folder where it was located (instead of entering the full path). ps. i did not install the SDK. Just the .7z of Dany pps. you need to run it x86, it does not work x642 points
-
Resizable status bar without SBARS_SIZEGRIP
argumentum and one other reacted to pixelsearch for a topic
Now that it comes to changing fonts, DPI etc... I suggest you think twice : if argumentum script solves it in these situations, why not giving a complete try with his script based on labels to detect the eventual flaws ? It will be probably easier to manage with labels, if you need to work on fonts & DPI Just my 2 cts... Dinner in town with family in a few min, see you soon. Have a great week-end everybody2 points -
Another AutoIt extension for Visual Studio Code
argumentum and one other reacted to genius257 for a topic
Hey all! So with the recent vscode version updates i noticed terrible performance when working with my extension. I tracked down the reason to how my extension tries to open git URI's when viewing changes via the git diff view in vscode, triggering GIT to go crazy for some reason. I looked at the latest couple of vscode release notes and could not see something that could cause this, so maybe this has always been an issue, but only for certain repositories i own affect it this way? New or old problem, I seem to have found the issue, and will deploy a fix later today. Because this problem basically forces me to reload my vscode every time it does this, I need to release this fix FAST, so smaller bugs may occur, if so, let me know I will post again, after the release with the fix is out!2 points -
Resizable status bar without SBARS_SIZEGRIP
WildByDesign and one other reacted to pixelsearch for a topic
imho there's something wrong in the function _GUICtrlStatusBar_SetParts found in the include file GuiStatusBar.au3 Gary Frost forces the last part of the status bar to have a value of -1, even if the user explicitely indicates another value, for example : User in script... Local $aParts[3] = [75, 150, 230] ...becomes in UDF Local $aParts[3] = [75, 150, -1] Here are the results below : The picture on the right is what the user wants (better display of the last Part 2) and not what the UDF forces us to display. msdn never wrote that the last parameter must be -1, here is what we can read on msdn's site : If an element is -1, the right edge of the corresponding part extends to the border of the window. It's written "IF", not "it must be -1 and you have to use all the window width for your status bar" For what it's worth...2 points -
Resizable status bar without SBARS_SIZEGRIP
WildByDesign and one other reacted to pixelsearch for a topic
A new functionality has been added to my 2nd script (found on previous page) Now all parts of the status bar got a flexible width during resizing : On the left side of the image above, the status bar parts show (on purpose) too long texts... which won't be a problem after we resize the GUI You'll notice 2 GUI's on the right side of the image above : 1) One got a visible border around the status bar parts 2) The 2nd one doesn't have borders : just pick the line of code you prefer in the script : _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW) ; _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW + $SBT_NOBORDERS) ; interesting ? Also, I added this test... If _GUICtrlStatusBar_IsSimple($g_hStatus) Then _GUICtrlStatusBar_Resize($g_hStatus) Else ... EndIf ...because maybe someone will use the script with a simple status bar ("simple" = no parts) just for the color change. Without the test, a normal fatal error would happen. The test on a simple status bar has been done, it seems correct, fingers crossed2 points -
Resizable status bar without SBARS_SIZEGRIP
ioa747 and one other reacted to pixelsearch for a topic
With @KaFu's help in his post, adapted to our script : #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <WinAPIGdi.au3> #include <WinAPIRes.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) Global $g_hGui, $g_hSizebox, $g_hOldProc, $g_hBrush, $g_hStatus, $g_iHeight, $g_aText, $g_aRatioW, $g_iBkColor, $g_iTextColor Example() ;============================================== Func Example() Local Const $SBS_SIZEBOX = 0x08, $SBS_SIZEGRIP = 0x10 Local $iW = 300, $iH = 100 Dim $g_iBkColor = 0x808080, $g_iTextColor = 0xFFFFFF $g_hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor($g_iBkColor) ;----------------- ; Create a sizebox window (Scrollbar class) BEFORE creating the StatusBar control $g_hSizebox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, _ 0, 0, 0, 0, $g_hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP ; Subclass the sizebox (by changing the window procedure associated with the Scrollbar class) Local $hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam') $g_hOldProc = _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, DllCallbackGetPtr($hProc)) Local $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZENWSE) _WinAPI_SetClassLongEx($g_hSizebox, -12, $hCursor) ; $GCL_HCURSOR = -12 $g_hBrush = _WinAPI_CreateSolidBrush($g_iBkColor) ;----------------- $g_hStatus = _GUICtrlStatusBar_Create($g_hGui, -1, "", $WS_CLIPSIBLINGS) ; ClipSiblings style +++ Local $aParts[3] = [90, 180, -1] _GUICtrlStatusBar_SetParts($g_hStatus, $aParts) Dim $g_aText[Ubound($aParts)] = ["Part 0", "Part 1", "Part 2"] Dim $g_aRatioW[Ubound($aParts)] For $i = 0 To UBound($g_aText) - 1 _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW) ; _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW + $SBT_NOBORDERS) ; interesting ? $g_aRatioW[$i] = $aParts[$i] / $iW Next Local $idChangeText = GUICtrlCreateButton("Change Text", 110, 25, 80, 30), $iInc GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT) ; to allow the setting of StatusBar BkColor at least under Windows 10 _WinAPI_SetWindowTheme($g_hStatus, "", "") ; Set status bar background color _GUICtrlStatusBar_SetBkColor($g_hStatus, $g_iBkColor) $g_iHeight = _GUICtrlStatusBar_GetHeight($g_hStatus) + 3 ; change the constant (+3) if necessary GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idChangeText $iInc += 1 For $i = 0 To UBound($g_aText) - 1 $g_aText[$i] = "Part " & $i & " : Inc " & $iInc Next _WinAPI_RedrawWindow($g_hStatus) EndSwitch WEnd _GUICtrlStatusBar_Destroy($g_hStatus) _WinAPI_DeleteObject($g_hBrush) _WinAPI_DestroyCursor($hCursor) _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, $g_hOldProc) DllCallbackFree($hProc) GUIDelete($g_hGui) EndFunc ;==>Example ;============================================== Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam) ; Andreik If $hWnd = $g_hSizebox Then Switch $iMsg Case $WM_ERASEBKGND Local $tRect = _WinAPI_GetClientRect($hWnd) _WinAPI_FillRect($wParam, $tRect, $g_hBrush) Return True Case $WM_PAINT Local $tPAINTSTRUCT Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT) Local $tRect = _WinAPI_CreateRect($tPAINTSTRUCT.Left, $tPAINTSTRUCT.Top, $tPAINTSTRUCT.Right, $tPAINTSTRUCT.Bottom) _WinAPI_FillRect($hDC, $tRect, $g_hBrush) _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT) Return 0 EndSwitch EndIf Return _WinAPI_CallWindowProc($g_hOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>ScrollbarProc ;============================================== Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) ; Pixelsearch #forceref $iMsg, $wParam, $lParam If $hWnd = $g_hGUI Then Local $aSize = WinGetClientSize($g_hGui) If _GUICtrlStatusBar_IsSimple($g_hStatus) Then _GUICtrlStatusBar_Resize($g_hStatus) Else Local $aGetParts = _GUICtrlStatusBar_GetParts($g_hStatus) Local $aParts[$aGetParts[0]] For $i = 0 To $aGetParts[0] - 2 $aParts[$i] = Int($aSize[0] * $g_aRatioW[$i]) Next $aParts[$aGetParts[0] - 1] = -1 _GUICtrlStatusBar_SetParts($g_hStatus, $aParts) EndIf WinMove($g_hSizebox, "", $aSize[0] - $g_iHeight, $aSize[1] - $g_iHeight, $g_iHeight, $g_iHeight) _WinAPI_ShowWindow($g_hSizebox, (BitAND(WinGetState($g_hGui), $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW)) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_SIZE ;============================================== Func WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam) ; Kafu #forceref $hWnd, $iMsg, $wParam Local $tDRAWITEMSTRUCT = DllStructCreate("uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;HWND hwndItem;HANDLE hDC;long rcItem[4];ULONG_PTR itemData", $lParam) If $tDRAWITEMSTRUCT.hwndItem <> $g_hStatus Then Return $GUI_RUNDEFMSG ; only process the statusbar Local $itemID = $tDRAWITEMSTRUCT.itemID ; status bar part number (0, 1, ...) Local $hDC = $tDRAWITEMSTRUCT.hDC Local $tRect = DllStructCreate("long left;long top;long right; long bottom", DllStructGetPtr($tDRAWITEMSTRUCT, "rcItem")) Local $iTop = $tRect.top, $iLeft = $tRect.left Local $hBrush = _WinAPI_CreateSolidBrush($g_iBkColor) ; backgound color _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrush) _WinAPI_SetTextColor($hDC, $g_iTextColor) ; text color _WinAPI_SetBkMode($hDC, $TRANSPARENT) DllStructSetData($tRect, "top", $iTop + 1) DllStructSetData($tRect, "left", $iLeft + 1) _WinAPI_DrawText($hDC, $g_aText[$itemID], $tRect, $DT_LEFT) _WinAPI_DeleteObject($hBrush) $tDRAWITEMSTRUCT = 0 Return $GUI_RUNDEFMSG EndFunc ;==>WM_DRAWITEM2 points -
Resizable status bar without SBARS_SIZEGRIP
WildByDesign and one other reacted to pixelsearch for a topic
@WildByDesign does this work for you ? #include <GUIConstantsEx.au3> #include <GuiStatusBar.au3> #include <WinAPIGdi.au3> #include <WinAPIRes.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) Global $g_hGui, $g_hSizebox, $g_hOldProc, $g_hBrush, $g_hStatus, $g_iHeight Example() ;============================================== Func Example() Local Const $SBS_SIZEBOX = 0x08, $SBS_SIZEGRIP = 0x10 Local $iW = 250, $iH = 100, $iBkColor = 0x00FF00 $g_hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetBkColor($iBkColor) ;----------------- ; Create a sizebox window (Scrollbar class) BEFORE creating the StatusBar control $g_hSizebox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, _ 0, 0, 0, 0, $g_hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP ; Subclass the sizebox (by changing the window procedure associated with the Scrollbar class) Local $hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam') $g_hOldProc = _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, DllCallbackGetPtr($hProc)) Local $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZENWSE) _WinAPI_SetClassLongEx($g_hSizebox, -12, $hCursor) ; $GCL_HCURSOR = -12 $g_hBrush = _WinAPI_CreateSolidBrush($iBkColor) ;----------------- $g_hStatus = _GUICtrlStatusBar_Create($g_hGui, -1, "", $WS_CLIPSIBLINGS) ; ClipSiblings style +++ Local $aParts[3] = [75, 150, -1] _GUICtrlStatusBar_SetParts($g_hStatus, $aParts) _GUICtrlStatusBar_SetText($g_hStatus, "Part 0", 0) _GUICtrlStatusBar_SetText($g_hStatus, "Part 1", 1) _GUICtrlStatusBar_SetText($g_hStatus, "Part 2", 2) ; to allow the setting of StatusBar BkColor at least under Windows 10 _WinAPI_SetWindowTheme($g_hStatus, "", "") ; Set status bar background color _GUICtrlStatusBar_SetBkColor($g_hStatus, $iBkColor) $g_iHeight = _GUICtrlStatusBar_GetHeight($g_hStatus) + 3 ; change the constant (+3) if necessary GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _GUICtrlStatusBar_Destroy($g_hStatus) _WinAPI_DeleteObject($g_hBrush) _WinAPI_DestroyCursor($hCursor) _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, $g_hOldProc) DllCallbackFree($hProc) GUIDelete($g_hGui) EndFunc ;==>Example ;============================================== Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam) ; Andreik's If $hWnd = $g_hSizebox Then Switch $iMsg Case $WM_ERASEBKGND Local $tRect = _WinAPI_GetClientRect($hWnd) _WinAPI_FillRect($wParam, $tRect, $g_hBrush) Return True Case $WM_PAINT Local $tPAINTSTRUCT Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT) Local $tRect = _WinAPI_CreateRect($tPAINTSTRUCT.Left, $tPAINTSTRUCT.Top, $tPAINTSTRUCT.Right, $tPAINTSTRUCT.Bottom) _WinAPI_FillRect($hDC, $tRect, $g_hBrush) _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT) Return 0 EndSwitch EndIf Return _WinAPI_CallWindowProc($g_hOldProc, $hWnd, $iMsg, $wParam, $lParam) EndFunc ;==>ScrollbarProc ;============================================== Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $wParam, $lParam If $hWnd = $g_hGUI Then Local $aSize = WinGetClientSize($g_hGui) _GUICtrlStatusBar_Resize($g_hStatus) WinMove($g_hSizebox, "", $aSize[0] - $g_iHeight, $aSize[1] - $g_iHeight, $g_iHeight, $g_iHeight) _WinAPI_ShowWindow($g_hSizebox, (BitAND(WinGetState($g_hGui), $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW)) EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_SIZE2 points -
Got bored today, while working on my au3unit project, and made this class-ish solution with functions, variables and maps. Maybe someone will use it 😜 Features: public class properties public static class properties public methods public static methods class Inheritance Repository: https://github.com/genius257/au3-functional-class ZIP download: https://github.com/genius257/au3-functional-class/archive/8503c876f65cb0cf339a324d0483d588a63eb4df.zip Online example file: https://github.com/genius257/au3-functional-class/blob/8503c876f65cb0cf339a324d0483d588a63eb4df/example.au3 Enjoy 😀2 points
-
Easy if and else
argumentum and one other reacted to Jos for a topic
No shit, Yuchan is back.... This isn't going to end well.2 points -
Media Foundation - Media Engine.
CYCho and one other reacted to argumentum for a topic
$sSource = FileOpenDialog("Open Media", @ScriptDir & "\", "Video Files (*.mp4;*.m4v;*.mpg;*.wmv;*.mov;*.mkv)" & _ "|Audio Files (*.mp3;*.aac;*.m4a;*.wma)|Good luck (*.*)", $FD_FILEMUSTEXIST) If Not FileExists($sSource) Then ContinueLoop2 points -
haha, yeah I'm bound to have missed a bunch of formats. I'll fix up my end so It'll make the next upload2 points
-
App Control Tray & Policy Manager (App Control for Business)
ioa747 and one other reacted to WildByDesign for a topic
So I just had my very first “Aha!” moment is my AutoIt journey and it proved to be extremely beneficial. Beginner Level 2 unlocked! 😄 App Control Policy Manager was my first AutoIt GUI app. The underlying functionality and logic is extremely powerful and I am proud of that. However, the UI/UX is not its strong point. Problems: too many buttons and controls visible harder for me to resize and DPI scaling Goals: ensure policy ListView is main focal point as it should be move all button functions into menu bar move info from status label into status bar This would make sure that the policy ListView is the star of the show and with less distractions. It would also make it so much easier to deal with resizing and DPI scaling changes. Challenges: dark mode menu bar (success) dark mode status bar There was absolutely no way I was going to do this GUI transformation if I could not achieve a dark mode menu bar. Last night and this morning I was able to achieve a fully dark mode, beautiful menu bar. It was quick and easy to add my already existing functions to the menu items and everything is working. I am going to try to tackle the dark mode status bar later today. I am posting from my phone right now so I can’t share a current screenshot or code at the moment but I will later in the day.2 points -
Exit Function...but not script!
argumentum and one other reacted to pixelsearch for a topic
Yes, you definitely should have started with this last script, which makes much more sense. So now what's wrong with @argumentum suggestion in his post ? Line 52 : just change Exit with Return and you're back to your menu . argumentum suggestion couldn't make it with your 1st "truncated" script but now it should be ok... or I'm still missing something2 points -
First I must thank @MattyD for showing me how to perform such a task in this thread. I felt I needed to play with it to fully understand the intrinsic. So I ended up making a small UDF that is accomplishing the creation of interface objects and the deletion of those made by the UDF. The example included in the zip file is largely inspired on the example made by the original author of the Media Engine topic. I believe the UDF is quite straightforward to use but, in any cases, post here your questions, I will be glad to answer in the scope of my knowledge. Version 2025-04-16 * Solved an issue with the tag transformation * Code optimization * Added tag validation ObjFromTag UDF.zip2 points
-
Please help with Run PowerShell Command 'quotes"
SOLVE-SMART and one other reacted to AspirinJunkie for a topic
Exactly - it is not escaping for Powershell code. But we're not at that level yet (as I said before: escaping with such nested interpreters is quite annoying...) Escaping per \" is not intended for powershell.exe but for the Windows API function CreateProcessA/W (which is the basis for the AutoIt function Run()). This function must ensure that the parameters are passed correctly to powershell.exe and the syntax is such that double quotation marks are escaped via \". A little clearer with the example: If you execute the following via Run (or from the command line): powershell.exe -Command "Write-Host \"This is a \"\"short\"\" test with multiple \"\"quotes\"\".\"" Then powershell.exe receives the following code as a parameter: Write-Host "This is a ""short"" test with multiple ""quotes""." And your double quotation marks for the powershell are correct again! This is exactly what the _prc_runPS() function does here.2 points -
Good find. I was trying to use one of my IPC to connect both running processes. Even with the MsgBox I am having a hard time to send messages to rendering process. However the Main process can receive quite nicely messages from the rendering process. Along the way I made a small UDF to create interface object, based on our discussion and from a post I saw from trancexx. I also included it in the script. I'll let you decide what you want to do with this version 2 of the engine. MediaEngine.zip2 points
-
It's a watery based version of ChatGPT in bathers or swimsuit.2 points
-
Thanks for help. Modifying accordingly made my code works. Learning is a fascinating thing. Don't be. This is why I created in the collaboration section. It was fun playing with this foundation. I am very happy with the result of this thread. Good work on it. I will update my OP code but refer to your last script as the solution. Next, I will take a look at the capture part of the foundation. If I come up with something I'll post here also. See ya around2 points
-
Microsoft Media Foundation
argumentum and one other reacted to MattyD for a topic
Hey Nine, yeah, the shuffling stuff around was more me catching up to you - i.e. following and figuring out what was supposed to happen. but looking back at it - this bit seems to be problematic. $tGUID = __COM_CreateGUID($blah, DllStructGetPtr($tGUID)) I'd say we're releasing memory of the "old" struct when we reassign $tGUID. But we're never actually allocating memory for the "new" struct at the old position because we're specifying a ptr in DllStructCreate, also a small gremlin. this was being created as $MF_TOPOLOGY_SOURCESTREAM_NODE. $aCall = DllCall("Mf.dll", "long", "MFCreateTopologyNode", "dword", $MF_TOPOLOGY_OUTPUT_NODE, "ptr*", 0) $pOutputNode = $aCall[2] $oOutputNode = ObjCreateInterface($pOutputNode, $sIID_IMFTopologyNode, $tag_IMFTopologyNode) @argumentum - as my niece would say, "you get what you get and you don't get upset" . Sorry, I don't have an answer for you at this stage mate, but will let you know if we come across anything!2 points -
Another way : #include <Constants.au3> #include <WindowsConstants.au3> #include <SendMessage.au3> Global Const $WM_NOTIFYICON = $WM_USER + 1 Global Const $sWinTitle = "TrayExample" AutoItWinSetTitle($sWinTitle) Opt("TrayMenuMode", 3) Example() Func Example() Local $idAbout = TrayCreateItem("About") TrayCreateItem("") Local $idExit = TrayCreateItem("Exit") HotKeySet("{F9}", ShowTrayMenu) While True Switch TrayGetMsg() Case $idExit ExitLoop Case $idAbout MsgBox($MB_SYSTEMMODAL, "About", "AutoIt tray menu example." & @CRLF & @CRLF & _ "Version: " & @AutoItVersion & @CRLF & _ "Install Path: " & StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1) - 1)) EndSwitch WEnd EndFunc ;==>Example Func ShowTrayMenu() _SendMessage(WinGetHandle($sWinTitle), $WM_NOTIFYICON, 0, $WM_LBUTTONDOWN) EndFunc ;==>ShowTrayMenu2 points
-
Modbus RTU using libmodbus.dll
argumentum and one other reacted to Geppo for a topic
You were right. Now I succeed to read the content of registers using "[1] " & DllStructGetData($tRegisterData, 1, 1) & @CRLF & _ "[2] " & DllStructGetData($tRegisterData, 1, 2) & @CRLF & _ And now also works Local $RTU_Result = DllCall($hDLL, "int:cdecl", "modbus_set_debug", "ptr", $pRTU_Ptr[0], "int", 1) using an int parameter. Evidently I have been mistaken. I will proceed to test other modbus functions, then I will code some Autoit functions to manage them at the best. Than you very much for your help.2 points -
Microsoft Edge - WebView2, embed web code in your native application
argumentum and one other reacted to ptrex for a topic
2 points -
On my Forum, I have created a page that lists and distributes MF Codecs created by Microsoft. Look here.2 points
-
Need help to make a 4k video player
SOLVE-SMART and one other reacted to Nine for a topic
Well, you got also my attention on it. It seems very promising, so I started to learn/code about it. I hope you do not mind, but I started a collaboration thread about this. If you should participate, it would be awesome. That way we could get faster and have greater result. Hope to see you there.2 points -
After the opencv udf, Dlib seems to be a missing library for image processing. This UDF provides a way to use dlib in AutoIt The usage is similar to the python usage of dlib Prerequisites Download and extract autoit-dlib-19.24.4-opencv-4.10.0-com-v1.4.3.7z into a folder Sources Here Documentation A generated documentation for functions is available here Examples More examples can be found here To run them, please follow these instructions Face detection #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Misc.au3> #include "autoit-dlib-com\udf\dlib_udf_utils.au3" _Dlib_Open("opencv-4.7.0-windows\opencv\build\x64\vc16\bin\opencv_world470.dll", "autoit-dlib-com\autoit_dlib_com-19.24-470.dll") OnAutoItExitRegister("_OnAutoItExit") Example() Func Example() Local Const $dlib = _Dlib_get() If Not IsObj($dlib) Then Return Local $detector = $dlib.get_frontal_face_detector() Local $win = _Dlib_ObjCreate("image_window") Local $image_path = _Dlib_FindFile("examples\faces\2008_002470.jpg") Local $img = $dlib.load_rgb_image($image_path) $win.set_image($img) ; The 1 in the second argument indicates that we should upsample the image ; 1 time. This will make everything bigger and allow us to detect more ; faces. Local $dets = $detector.call($img, 1) ConsoleWrite("Number of faces detected: " & UBound($dets) & @CRLF) Local $d For $i = 0 To UBound($dets) - 1 $d = $dets[$i] ConsoleWrite(StringFormat("Detection %d: Left: %d Top: %d Right: %d Bottom: %d", _ $i, $d.left(), $d.top(), $d.right(), $d.bottom()) & @CRLF) Next $win.add_overlay($dets) hit_to_continue() EndFunc ;==>Example Func hit_to_continue() ToolTip("Hit ESC to continue", 0, 0) ConsoleWrite("Hit ESC to continue" & @CRLF) Do Sleep(50) Until _IsPressed("1B") EndFunc ;==>hit_to_continue Func _OnAutoItExit() _Dlib_Close() EndFunc ;==>_OnAutoItExit Camera face detection using opencv First, download the opencv UDF from here #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Misc.au3> #include "autoit-dlib-com\udf\dlib_udf_utils.au3" #include "autoit-opencv-com\udf\opencv_udf_utils.au3" _Dlib_Open("opencv-4.7.0-windows\opencv\build\x64\vc16\bin\opencv_world470.dll", "autoit-dlib-com\autoit_dlib_com-19.24-470.dll") _OpenCV_Open("opencv-4.7.0-windows\opencv\build\x64\vc16\bin\opencv_world470.dll", "autoit-opencv-com\autoit_opencv_com470.dll") OnAutoItExitRegister("_OnAutoItExit") Example() Func Example() Local Const $dlib = _Dlib_get() If Not IsObj($dlib) Then Return Local Const $cv = _OpenCV_get() If Not IsObj($cv) Then Return Local $detector = $dlib.get_frontal_face_detector() Local $cam = _OpenCV_ObjCreate("VideoCapture").create(0) Local $color_green = _OpenCV_Tuple(0, 255, 0) Local $line_width = 3 Local $img, $dets, $det While True If $cam.read() Then $img = $cv.extended[1] $dets = $detector.call($img) For $i = 0 To UBound($dets) - 1 $det = $dets[$i] $cv.rectangle($img, _OpenCV_Tuple($det.left(), $det.top()), _OpenCV_Tuple($det.right(), $det.bottom()), $color_green, $line_width) Next ;; Flip the image horizontally to give the mirror impression $cv.imshow("my webcam", $cv.flip($img, 1)) EndIf If _IsPressed("1B") Then ExitLoop ; esc to quit EndIf Sleep(1) WEnd $cv.destroyAllWindows() EndFunc ;==>Example Func _OnAutoItExit() _OpenCV_Close() _Dlib_Close() EndFunc ;==>_OnAutoItExit2 points
-
I needed a way to HexEdit / Patch a file to repair a common file corruption problem in a software package my company uses. I first used the AutoIt core FileOpen / FileWrite functions but this method required me to open the whole file into memory. The files I work with can be several hundred megabytes in size and easily cause out of memory errors. So, After searching / hacking I came up with this solution. I hope someone finds it useful #include <WinAPI.au3> _Demo() Func _Demo() Local Const $TestFile_Path = @ScriptDir & "\Test.Bin" Local $TestFile_ID, $bData, $Offset ;## Hex offsets / lengths of the data stored in the file. Local Const $Offset_Phone[2] = [0x012, 4] Local Const $Offset_NewToy[2] = [0x1b6, 18] Local Const $Offset_Recycle[2] = [0x594, 24] ;## Binary string of the test file. Local Const $TestFile_Data = "0x" & _ "42494E000000000000000000000000000000867530900000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000446F6E27742054617A65206D" & _ "652042726F21000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000536F796C656E742067726565" & _ "6E2069732070656F706C6521000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000" ;## Create Test File $TestFile_ID = FileOpen($TestFile_Path, 14) FileWrite($TestFile_ID, Binary($TestFile_Data)) FileClose($TestFile_ID) ;## Read the Recycle Value $bData = _HexRead($TestFile_Path, $Offset_Recycle[0], $Offset_Recycle[1]) ;## Convert data to a string and display. MsgBox(4096, Default, "Recycle:" & @CRLF & BinaryToString($bData)) ;## Change the recycle value $bData = StringToBinary("It Tastes like chicken!!") _HexWrite($TestFile_Path, $Offset_Recycle[0], $bData) ;## Read the Recycle Value $bData = _HexRead($TestFile_Path, $Offset_Recycle[0], $Offset_Recycle[1]) ;## Convert data to a string and display. MsgBox(4096, Default, "Recycle:" & @CRLF & BinaryToString($bData)) ;## Search for a specific value and display $Offset = _HexSearch($TestFile_Path, $bData) MsgBox(4096, "HexSearch Function", "Search performed to locate data stream: " & @CRLF & @TAB & $bData & @CRLF & "Result = 0x" & Hex($Offset, 3)) EndFunc #Region ;**** HexEdit Functions Func _HexWrite($FilePath, $Offset, $BinaryValue) Local $Buffer, $ptr, $bLen, $fLen, $hFile, $Result, $Written ;## Parameter Checks If Not FileExists($FilePath) Then Return SetError(1, @error, 0) $fLen = FileGetSize($FilePath) If $Offset > $fLen Then Return SetError(2, @error, 0) If Not IsBinary($BinaryValue) Then Return SetError(3, @error, 0) $bLen = BinaryLen($BinaryValue) If $bLen > $Offset + $fLen Then Return SetError(4, @error, 0) ;## Place the supplied binary value into a dll structure. $Buffer = DllStructCreate("byte[" & $bLen & "]") DllStructSetData($Buffer, 1, $BinaryValue) If @error Then Return SetError(5, @error, 0) $ptr = DllStructGetPtr($Buffer) ;## Open File $hFile = _WinAPI_CreateFile($FilePath, 2, 4, 0) If $hFile = 0 Then Return SetError(6, @error, 0) ;## Move file pointer to offset location $Result = _WinAPI_SetFilePointer($hFile, $Offset) $err = @error If $Result = 0xFFFFFFFF Then _WinAPI_CloseHandle($hFile) Return SetError(7, $err, 0) EndIf ;## Write new Value $Result = _WinAPI_WriteFile($hFile, $ptr, $bLen, $Written) $err = @error If Not $Result Then _WinAPI_CloseHandle($hFile) Return SetError(8, $err, 0) EndIf ;## Close File _WinAPI_CloseHandle($hFile) If Not $Result Then Return SetError(9, @error, 0) EndFunc Func _HexRead($FilePath, $Offset, $Length) Local $Buffer, $ptr, $fLen, $hFile, $Result, $Read, $err, $Pos ;## Parameter Checks If Not FileExists($FilePath) Then Return SetError(1, @error, 0) $fLen = FileGetSize($FilePath) If $Offset > $fLen Then Return SetError(2, @error, 0) If $fLen < $Offset + $Length Then Return SetError(3, @error, 0) ;## Define the dll structure to store the data. $Buffer = DllStructCreate("byte[" & $Length & "]") $ptr = DllStructGetPtr($Buffer) ;## Open File $hFile = _WinAPI_CreateFile($FilePath, 2, 2, 0) If $hFile = 0 Then Return SetError(5, @error, 0) ;## Move file pointer to offset location $Pos = $Offset $Result = _WinAPI_SetFilePointer($hFile, $Pos) $err = @error If $Result = 0xFFFFFFFF Then _WinAPI_CloseHandle($hFile) Return SetError(6, $err, 0) EndIf ;## Read from file $Read = 0 $Result = _WinAPI_ReadFile($hFile, $ptr, $Length, $Read) $err = @error If Not $Result Then _WinAPI_CloseHandle($hFile) Return SetError(7, $err, 0) EndIf ;## Close File _WinAPI_CloseHandle($hFile) If Not $Result Then Return SetError(8, @error, 0) ;## Return Data $Result = DllStructGetData($Buffer, 1) Return $Result EndFunc Func _HexSearch($FilePath, $BinaryValue, $StartOffset = Default) Local $Buffer, $ptr, $hFile, $Result, $Read, $SearchValue, $Pos, $BufferSize = 2048 ;## Parameter Defaults If $StartOffset = Default Then $StartOffset = 0 ;## Parameter Checks If Not FileExists($FilePath) Then Return SetError(1, @error, 0) $fLen = FileGetSize($FilePath) If $StartOffset > $fLen Then Return SetError(2, @error, 0) If Not IsBinary($BinaryValue) Then Return SetError(3, @error, 0) If Not IsNumber($StartOffset) Then Return SetError(4, @error, 0) ;## Prep the supplied binary value for search $SearchValue = BinaryToString($BinaryValue) ;## Define the dll structure to store the data. $Buffer = DllStructCreate("byte[" & $BufferSize & "]") $ptr = DllStructGetPtr($Buffer) ;## Open File $hFile = _WinAPI_CreateFile($FilePath, 2, 2, 1) If $hFile = 0 Then Return SetError(5, @error, 0) ;## Move file pointer to offset location $Result = _WinAPI_SetFilePointer($hFile, $StartOffset) $err = @error If $Result = 0xFFFFFFFF Then _WinAPI_CloseHandle($hFile) Return SetError(5, $err, 0) EndIf ;## Track the file pointer's position $Pos = $StartOffset ;## Start Search Loop While True ;## Read from file $Read = 0 $Result = _WinAPI_ReadFile($hFile, $ptr, $BufferSize, $Read) $err = @error If Not $Result Then _WinAPI_CloseHandle($hFile) Return SetError(6, $err, 0) EndIf ;## Prep read data for search $Result = DllStructGetData($Buffer, 1) $Result = BinaryToString($Result) ;## Search the read data for first match $Result = StringInStr($Result, $SearchValue) If $Result > 0 Then ExitLoop ;## Test for EOF and return -1 to signify value was not found If $Read < $BufferSize Then _WinAPI_CloseHandle($hFile) Return -1 EndIf ;## Value not found, Continue Tracking file pointer's position $Pos += $Read WEnd ;## Close File _WinAPI_CloseHandle($hFile) If Not $Result Then Return SetError(7, @error, 0) ;## Calculate the offset and return $Result = $Pos + $Result - 1 Return $Result EndFunc Func _WinAPI_SetFilePointer($hFile, $nDistance, $nMethod = 0) Local $nRet $nRet = DllCall("kernel32.dll", "dword", "SetFilePointer", "ptr", $hFile, "long", $nDistance, "ptr", 0, "dword", $nMethod) Return $nRet[0] EndFunc #EndRegion ** UPDATES ** Added new function: _HexSearch()2 points
-
MiniMark (a minimalistic rtf editor)
TheAutomator and one other reacted to pixelsearch for a topic
@TheAutomator there are always good things to learn from @Nine's code, but it takes time to (try to) understand it, because our knowledge of AutoIt/Windows isn't as high as his. I always said he's a great coder ! Nine uses Subclassing a lot, which seems to be the shortest way to accomplish many tasks, which would require much code when not used. For example, with the code below I can mimic a scrollbar (using 4 label controls) without subclassing, by registering WM_COMMAND & WM_NOTIFY, but it requires more code than subclassing : #include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <Misc.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Global $g_hRichEdit, $g_idDummy, $g_idThumb, $g_idUp, $g_idDn, $g_idBack, $g_aBack Global $g_aCheckLine[3] ; [0] = 1st visible line, [1] = last visible line, [2] = total lines Example() Func Example() ; Constants changeable in these 4 lines Local $hGui = GUICreate("Label is Scrollbar", 320, 416) Local $aEdit[4] = [10, 10, 210, 396] ; coords richedit control Local $iGap = 3 ; number of pixels between right border of edit control & vertical scrollbar Local $aUp[4] = [$aEdit[0] + $aEdit[2] + $iGap, $aEdit[1], 15, 20] ; coords Up arrow ; Nothing to change here Dim $g_aBack[4] = [$aUp[0], $aUp[1] + $aUp[3], $aUp[2], $aEdit[3] - $aUp[3] * 2] Local $aDn[4] = [$aUp[0], $aEdit[1] + $aEdit[3] - $aUp[3], $aUp[2], $aUp[3]] Local $sString For $i = 1 To 100 $sString &= @crlf & "Line " & $i Next $sString = StringTrimLeft($sString, 2) ; remove 2 first characters (@cr & @lf) $g_hRichEdit = _GUICtrlRichEdit_Create($hGui, $sString, $aEdit[0], $aEdit[1], $aEdit[2], $aEdit[3], _ BitOR($ES_MULTILINE, $ES_AUTOVSCROLL)) $g_idUp = GUICtrlCreateLabel(Chr(241), $aUp[0], $aUp[1], $aUp[2], $aUp[3], BitOr($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 15, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings") GUICtrlSetBkColor(-1, 0xE0DFE3) ; my GUI light grey background $g_idDn = GUICtrlCreateLabel(Chr(242), $aDn[0], $aDn[1], $aDn[2], $aDn[3], BitOr($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 15, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings") GUICtrlSetBkColor(-1, 0xE0DFE3) ; my GUI light grey background ;======= create $g_idThumb BEFORE $g_idBack (as they overlap) . $WS_CLIPSIBLINGS style for $g_idBack $g_idThumb = GUICtrlCreateLabel("", $g_aBack[0], $g_aBack[1], 0, 0) GUICtrlSetBkColor(-1, 0xFF0000) ; red $g_idBack = GUICtrlCreateLabel("", $g_aBack[0], $g_aBack[1], $g_aBack[2], $g_aBack[3], $WS_CLIPSIBLINGS) GUICtrlSetBkColor(-1, 0x808080) ; dark grey ;======= $g_idDummy = GUICtrlCreateDummy() Local $idButton = GUICtrlCreateButton("Button", $aUp[0] + $aUp[2] + 10, $aUp[1], 60, 30) _GUICtrlRichEdit_SetEventMask($g_hRichEdit, $ENM_SCROLLEVENTS) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") GUISetState(@SW_SHOW) _GUICtrlRichEdit_SetScrollPos($g_hRichEdit, 0, 0) ; good behavior when placed after GUISetState (in case total lines = total visible + 1) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($g_hRichEdit) GUIDelete($hGUI) Exit Case $g_idDummy ; triggered by WM_COMMAND . Needed to process ALL repeated clicks on labels Local $iDummyVal = GUICtrlRead($g_idDummy) Switch $iDummyVal Case $g_idUp, $g_idDn ; line up / line down _GUICtrlRichEdit_ScrollLines($g_hRichEdit, ($iDummyVal = $g_idUp) ? -1 : 1) Sleep(200) While _IsPressed("01") _GUICtrlRichEdit_ScrollLines($g_hRichEdit, ($iDummyVal = $g_idUp) ? -1 : 1) Sleep(100) WEnd Case $g_idBack ; page up / page down If BitAnd(GUICtrlGetState($g_idThumb), $GUI_SHOW) Then Local $aPosThumb, $iY, $iOpt = Opt("MouseCoordMode", 2) ; 2 = relative to client area While True $aPosThumb = ControlGetPos($hGUI, "", $g_idThumb) $iY = MouseGetPos(1) If $iY < $aPosThumb[1] Then _GUICtrlRichEdit_ScrollLineOrPage($g_hRichEdit, "pu") ElseIf $iY > $aPosThumb[1] + $aPosThumb[3] Then _GUICtrlRichEdit_ScrollLineOrPage($g_hRichEdit, "pd") EndIf Sleep(200) If Not _IsPressed("01") Then ExitLoop WEnd Opt("MouseCoordMode", $iOpt) EndIf EndSwitch Case $g_idThumb ; based on Nine's formula Local $iOpt = Opt("MouseCoordMode", 2) Local $aThumb = ControlGetPos($hGUI, "", $g_idThumb) Local $iTop = $g_aBack[1], $iTop2, $iBottom = $g_aBack[3] - $aThumb[3] Local $iY = MouseGetPos(1), $iY1 = $iY, $iY2, $iDeltaInit = $aThumb[1] - $iY While _IsPressed("01") $iY2 = MouseGetPos(1) If $iY2 <> $iY1 Then $iY2 += $iDeltaInit $iY2 = $iY2 < $iTop ? $iTop : ($iY2 > $iBottom ? $iBottom : $iY2) $iTop2 = _ScrollCalc(($iY2 - $iTop) / ($iBottom - $iTop)) _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $iTop2 - $g_aCheckLine[0]) $iY1 = $iY2 EndIf Sleep(10) WEnd Opt("MouseCoordMode", $iOpt) Case $idButton _ScrollCalc() ; just to display the result of 1st visible line, last visible line, total lines ConsoleWrite("Button pressed " & $g_aCheckLine[0] & " " & $g_aCheckLine[1] & " " & $g_aCheckLine[2] & @crlf) EndSwitch WEnd EndFunc ;==>Example ;=========================================== Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam) If $tMsgFilter.hwndFrom = $g_hRichEdit Then _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $tMsgFilter.wParam ? 1 : -1) Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ;=========================================== Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) If $lParam = $g_hRichEdit Then If BitShift($wParam, 16) = $EN_UPDATE Then ; Hi Word (control notification code) _ScrollUpdate() EndIf Else Local $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word (control ID) Switch $iIDFrom Case $g_idUp, $g_idDn, $g_idBack GUICtrlSendToDummy($g_idDummy, $iIDFrom) EndSwitch EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND ;=========================================== Func _ScrollUpdate() _ScrollCalc() If $g_aCheckLine[0] = 1 And $g_aCheckLine[1] = $g_aCheckLine[2] Then GUICtrlSetState($g_idThumb, $GUI_HIDE) Return EndIf Local $fRatio = ($g_aCheckLine[1] - $g_aCheckLine[0] + 1) / $g_aCheckLine[2] Local $iThumbHeight = Int($g_aBack[3] * $fRatio), $iY Select Case $g_aCheckLine[0] = 1 $iY = $g_aBack[1] Case $g_aCheckLine[1] = $g_aCheckLine[2] $iY = $g_aBack[1] + $g_aBack[3] - $iThumbHeight Case Else Local $iTotalHiddenLines = $g_aCheckLine[2] - ($g_aCheckLine[1] - $g_aCheckLine[0] + 1) Local $fRatio2 = ($g_aCheckLine[0] - 1) / $iTotalHiddenLines Local $iYPosThumb = Int(($g_aBack[3] - $iThumbHeight) * $fRatio2) $iY = $g_aBack[1] + $iYPosThumb EndSelect GUICtrlSetPos($g_idThumb, $g_aBack[0], $iY, $g_aBack[2], $iThumbHeight) GUICtrlSetState($g_idThumb, $GUI_SHOW) EndFunc ;==>_ScrollUpdate ;=========================================== Func _ScrollCalc($nPos = 0) Local Static $aRect = _GUICtrlRichEdit_GetRECT($g_hRichEdit) Local $iCharIndex = _GUICtrlRichEdit_GetCharPosFromXY($g_hRichEdit, $aRect[0] + 2, $aRect[3] - 2) $g_aCheckLine[0] = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($g_hRichEdit) $g_aCheckLine[1] = _GUICtrlRichEdit_GetLineNumberFromCharPos($g_hRichEdit, $iCharIndex) ; last visible line $g_aCheckLine[2] = _GUICtrlRichEdit_GetLineCount($g_hRichEdit) If $nPos Then Local $iShown = $g_aCheckLine[1] - $g_aCheckLine[0] + 1 Local $iTop2 = Int($nPos * ($g_aCheckLine[2] - $iShown)) + 1 Return $iTop2 EndIf EndFunc ;==>_ScrollCalc In this script, the scroll "thumb" (a label control) has a dynamic height, it's not static as in your script (or Nine's) and its height varies with the number of total lines in the richedit control . Also I can click on the "scroll background rectangle" (another label control which overlaps with the thumb control) to scroll 1 page up/down, or on the 2 scrolls arrows (2 other label controls) to scroll 1 line up/down, as in a normal scrollbar. I'm not satisfied with the fact that clicking quickly on the scroll arrows doesn't scroll 1 line up/down each time the user clicks on a scroll arrow. I just discovered why today : clicking quickly twice on a label control doesn't trigger (twice) the corresponding Case in main loop, because it's recognized as a double click on the label control, which should be taken care of in WM_COMMAND as @Melba23 indicates here . This "annoyance" doesn't occur with button controls. [ Note : the preceding "Strikethrough" comment has been fixed in the code by using a Dummy control, triggered by WM_COMMAND and processed in main loop. ] Using Pic controls (as you do) instead of Label controls seem to work , as both are static controls. What is important is the order of creation of the 2 overlapping controls, as found in the script, e.g. the big "scroll bar rectangle" (dark grey in the pic) and the smaller "scroll thumb" (red in the pic) I scripted this only for educational purpose, because simply adding the "WS_SCROLL" style to the richedit control would solve it all, but I understand why you don't want to use WS_SCROLL (you explained it before) Maybe the script above will help you, maybe not, or maybe it will be a good occasion for you to spend some time on Nine's subclassing part & the learning of DllCallbackRegister etc... For example, see in this post how @LarsJ quickly used subclassing to efficiently solve OP's question, amazing ! Good luck Update: April 8th : simplified code in Case $g_idBack2 points -
2 points
-
Hi @smbape, thanks a lot for this great UDF 😊! Finally a solution I got to work, that can perform face recognition and matching. I used your https://github.com/smbape/node-autoit-dlib-com?tab=readme-ov-file#running-examples guidance to set-up the environment and manually downloaded the two additional dlib-models required. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; Dlib UDF by smbape ; https://www.autoitscript.com/forum/topic/207773-dlib-udf/ ; Dlib Face Recognition example by KaFu ; https://github.com/davisking/dlib/blob/v19.24/python_examples/face_recognition.py #include <Misc.au3> #include "..\autoit-dlib-com\udf\dlib_udf_utils.au3" ; sample - one of the faces from the example gallery picture "2007_007763.jpg" Local $a_128D_Face_Descriptor_of_Face_to_look_for[129] = [128, -0.091833, 0.0675418, 0.00142617, -0.0139504, -0.0903373, -0.0616875, -0.0384285, -0.14486, 0.0820726, -0.0852851, 0.17568, -0.0610356, -0.145164, -0.0266639, -0.0164959, 0.113634, -0.124758, -0.103387, -0.146446, -0.045612, 0.00516588, -9.29451E-05, 0.0863597, 0.0242456, -0.14534, -0.328905, -0.123818, -0.0685623, 0.0621051, 0.00807183, 0.0105838, 0.0424884, -0.254334, -0.118144, 0.0365846, 0.0897826, -0.0123099, -0.0522731, 0.226144, 0.0407339, -0.18469, 0.0978772, 0.049654, 0.260682, 0.230801, -0.0613484, 0.0384872, -0.0580775, 0.070347, -0.190347, 0.0539085, 0.122605, 0.136734, 0.0766652, -0.029859, -0.040169, 0.0905577, 0.16567, -0.184592, 0.0334291, 0.131489, -0.105992, -0.0602567, 0.043018, 0.142796, 0.110119, -0.086098, -0.164362, 0.0712913, -0.101671, -6.08778E-05, 0.0195526, -0.136251, -0.131349, -0.324134, 0.050356, 0.397348, 0.0955416, -0.193875, 0.0465133, -0.143481, 0.0191909, 0.0440991, 0.0355733, -0.0547336, -0.0449448, -0.105943, 0.0979393, 0.154901, -0.0282238, -0.0588183, 0.193323, 0.00501542, -0.0170646, 0.0698614, 0.130419, -0.161941, -0.0505242, -0.109364, -0.042785, 0.10326, -0.0566043, 0.0215982, 0.107899, -0.215276, 0.213152, -0.0453729, -0.00757293, 0.0653693, -0.0408494, -0.0396944, -0.00927441, 0.126415, -0.17009, 0.166003, 0.15904, -0.0532249, 0.13575, 0.138663, 0.0392869, -0.0467882, 0.0669965, -0.15721, -0.0904878, 0.0118087, 0.0483355, 0.100762, 0.0341779] _Dlib_Open(_Dlib_FindDLL("opencv_world4100*"), _Dlib_FindDLL("autoit_dlib_com-*-4100*")) OnAutoItExitRegister("_OnAutoItExit") Func _OnAutoItExit() _Dlib_Close() EndFunc ;==>_OnAutoItExit Local Const $o_Dlib = _Dlib_get() If Not IsObj($o_Dlib) Then Exit 356 Local $s_Data_Path_Predictor = @ScriptDir & "\data\shape_predictor_5_face_landmarks.dat" ; https://github.com/davisking/dlib-models/raw/master/shape_predictor_5_face_landmarks.dat.bz2 Local $s_Data_Path_Face_Rec_Model = @ScriptDir & "\data\dlib_face_recognition_resnet_model_v1.dat" ; https://github.com/davisking/dlib-models/raw/master/dlib_face_recognition_resnet_model_v1.dat.bz2 ; Load all the models we need: a detector to find the faces, a shape predictor to find face landmarks so we can precisely localize the face, and finally the face recognition model. Local $o_Dlib_Frontal_Face_Detector = $o_Dlib.get_frontal_face_detector() Local $o_Dlib_Shape_Predictor = _Dlib_ObjCreate("shape_predictor").create($s_Data_Path_Predictor) Local $o_Dlib_Face_Rec_Model = _Dlib_ObjCreate("face_recognition_model_v1").create($s_Data_Path_Face_Rec_Model) ; For display of results only, not required for the operation itself Local $o_Dlib_Window = _Dlib_ObjCreate("image_window") Local $a_All_Files_found_to_process = _Dlib_FindFiles("*.jpg", @ScriptDir & "\faces\") ; Now process all the images For $s_Current_File_to_process In $a_All_Files_found_to_process $s_Current_File_to_process = @ScriptDir & "\faces\" & "\" & $s_Current_File_to_process ConsoleWrite(@CRLF & "Processing file: " & $s_Current_File_to_process & @CRLF) $o_Dlib_Image = $o_Dlib.load_rgb_image($s_Current_File_to_process) $o_Dlib_Window.clear_overlay() $o_Dlib_Window.set_title($s_Current_File_to_process) $o_Dlib_Window.set_image($o_Dlib_Image) ; Ask the detector to find the bounding boxes of each face. ; The 1 in the second argument indicates that we should upsample the image 1 time. This will make everything bigger and allow us to detect more faces. ; The third argument to run is an optional adjustment to the detection threshold, where a negative value will return more detections and a positive value fewer. $a_Detected_Faces_Rect = $o_Dlib_Frontal_Face_Detector($o_Dlib_Image, 1, 0) ; $a_Detected_Faces_Rect = $o_Dlib.extended[0] ; same result ConsoleWrite("Number of faces detected in image: " & UBound($a_Detected_Faces_Rect) & @CRLF) ; You can ask the detector to tell you the score for each detection. The score is bigger for more confident detections. $a_Detected_Faces_Confidence_Scores = $o_Dlib.extended[1] ; The idx tells you which of the face sub-detectors matched. This can be used to broadly identify faces in different orientations. $a_Detected_Faces_Matching_Filter_idx = $o_Dlib.extended[2] ; https://github.com/davisking/dlib/blob/master/dlib/image_processing/frontal_face_detector.h ; 1 = front looking ; 2 = left looking ; 3 = right looking ; 4 = front looking but rotated left ; 5 = front looking but rotated right #cs ; Show an overlay of all detected faces in preview window $o_Dlib_All_Rectangles_of_all_detected_Faces = _Dlib_ObjCreate("VectorOfRectangle") For $i_Detected_Faces_Enum = 0 To UBound($a_Detected_Faces_Rect) - 1 $o_Dlib_All_Rectangles_of_all_detected_Faces.Add($a_Detected_Faces_Rect[$i_Detected_Faces_Enum]) Next $o_Dlib_Window.add_overlay($o_Dlib_All_Rectangles_of_all_Faces) #ce ; Now process each face we found. For $i_Detected_Faces_Enum = 0 To UBound($a_Detected_Faces_Rect) - 1 $t_Detected_Face_Rectangle = $a_Detected_Faces_Rect[$i_Detected_Faces_Enum] ConsoleWrite("+ Face #" & $i_Detected_Faces_Enum + 1 & @TAB & @TAB) ConsoleWrite(StringFormat("Left: %d, Top: %d, Right: %d, Bottom: %d", $t_Detected_Face_Rectangle.left(), $t_Detected_Face_Rectangle.top(), $t_Detected_Face_Rectangle.right(), $t_Detected_Face_Rectangle.bottom()) & @CRLF) ConsoleWrite("Confidence score = " & $a_Detected_Faces_Confidence_Scores[$i_Detected_Faces_Enum] & @TAB & @CRLF) ConsoleWrite("Matching filter = " & $a_Detected_Faces_Matching_Filter_idx[$i_Detected_Faces_Enum] & @CRLF) ; Get the landmarks/parts for the face in box $t_Detected_Face_Rectangle $o_Detected_Face_Landmarks_Shape = $o_Dlib_Shape_Predictor($o_Dlib_Image, $t_Detected_Face_Rectangle) ; ; Get the landmarks/parts for the face ConsoleWrite(StringFormat("Landmark 0: %s, Landmark 1: %s ...", $o_Detected_Face_Landmarks_Shape.part(0).ToString(), $o_Detected_Face_Landmarks_Shape.part(1).ToString()) & @CRLF) ; Draw the face landmarks on the screen so we can see what face is currently being processed. $o_Dlib_Window.clear_overlay() $o_Dlib_Window.add_overlay($t_Detected_Face_Rectangle) $o_Dlib_Window.add_overlay($o_Detected_Face_Landmarks_Shape) ; Compute the 128D vector that describes the face in img identified by shape. ; It should also be noted that you can also call this function like this: ; face_descriptor = facerec.compute_face_descriptor(img, shape, 100, 0.25) ; The version of the call without the 100 gets 99.13% accuracy on LFW while the version with 100 gets 99.38%. However, the 100 makes the call 100x slower to execute, so choose whatever version you like. To explain a little, the 3rd argument tells the code how many times to ; jitter/resample the image. When you set it to 100 it executes the face descriptor extraction 100 times on slightly modified versions of the face and returns the average result. You could also pick a more middle value, such as 10, which is only 10x slower but still gets an ; LFW accuracy of 99.3%. 4th value (0.25) is padding around the face. If padding == 0 then the chip will be closely cropped around the face. Setting larger padding values will result a looser cropping. In particular, a padding of 0.5 would double the width of the cropped area, a value of ; would triple it, and so forth. There is another overload of compute_face_descriptor that can take as an input an aligned image. ConsoleWrite("Computing 128D face description vector..." & @CRLF) $o_Detected_Face_Descriptor = $o_Dlib_Face_Rec_Model.compute_face_descriptor($o_Dlib_Image, $o_Detected_Face_Landmarks_Shape) ; $o_Detected_Face_Descriptor = $o_Dlib_Face_Rec_Model.compute_face_descriptor($o_Dlib_Image, $o_Detected_Face_Landmarks_Shape, 4, 1) ConsoleWrite("$o_Detected_Face_Descriptor.ToString() = " & @TAB & @TAB & @TAB & StringReplace($o_Detected_Face_Descriptor.ToString(), @LF, ",") & @CRLF) ; It is important to generate the aligned image as dlib.get_face_chip would do it i.e. the size must be 150x150, centered and scaled. ConsoleWrite("Computing description on aligned image..." & @CRLF) ; Let's generate the aligned image using get_face_chip $o_Detected_Face_Chip_Aligned_Image = $o_Dlib.get_face_chip($o_Dlib_Image, $o_Detected_Face_Landmarks_Shape) ; https://dlib.net/python/#dlib_pybind11.get_face_chip #cs ; Show 5 jittered images without data augmentation Local $a_Jittered_Images = $o_Dlib.jitter_image($o_Detected_Face_Chip_Aligned_Image, 5) show_jittered_images($o_Dlib_Window, $a_Jittered_Images) ; Show 5 jittered images with data augmentation $a_Jittered_Images = $o_Dlib.jitter_image($o_Detected_Face_Chip_Aligned_Image, 5, True) show_jittered_images($o_Dlib_Window, $a_Jittered_Images) #ce ; Now we simply pass this chip (aligned image) to the api $o_Detected_Face_Descriptor_from_prealigned_image = $o_Dlib_Face_Rec_Model.compute_face_descriptor($o_Detected_Face_Chip_Aligned_Image) ConsoleWrite("$o_Detected_Face_Descriptor_from_prealigned_image.ToString() = " & @TAB & StringReplace($o_Detected_Face_Descriptor_from_prealigned_image.ToString(), @LF, ",") & @CRLF) $a_Detected_Face_Descriptor_128D = StringSplit($o_Detected_Face_Descriptor_from_prealigned_image.ToString(), @LF) If Not IsArray($a_128D_Face_Descriptor_of_Face_to_look_for) Then ; if no target has been set yet, use the first face found as pattern for the search If UBound($a_Detected_Face_Descriptor_128D) = 129 Then $a_128D_Face_Descriptor_of_Face_to_look_for = $a_Detected_Face_Descriptor_128D #cs ; manually create 128D target descriptor $s_128D_Face_Descriptor_of_Face_to_look_for = "$a_128D_Face_Descriptor_of_Face_to_look_for[129] = [128" For $i = 1 To 128 $s_128D_Face_Descriptor_of_Face_to_look_for &= "," & $a_128D_Face_Descriptor_of_Face_to_look_for[$i] Next $s_128D_Face_Descriptor_of_Face_to_look_for &= "]" ConsoleWrite($s_128D_Face_Descriptor_of_Face_to_look_for & @CRLF) #ce ContinueLoop 2 Else ContinueLoop ; Descriptor not valid EndIf EndIf $i_128D_Euclidean_Distance = _Euclidean_Distance_of_128D_Vectors($a_Detected_Face_Descriptor_128D, $a_128D_Face_Descriptor_of_Face_to_look_for) If $i_128D_Euclidean_Distance <= 0.5 Then ; Possible match ConsoleWrite("+ Possible MATCH, Euclidean Distance = " & @TAB & $i_128D_Euclidean_Distance & @CRLF) MsgBox(32, "Dlib Face Recognition result - Possible MATCH", "Possible Face MATCH found" & @CRLF & @CRLF _ & "Euclidean Distance to Face to look for = " & $i_128D_Euclidean_Distance _ & @CRLF & @CRLF & @CRLF & @CRLF & @CRLF & @CRLF _ & "In general, if two face descriptor vectors have a Euclidean distance between them less than 0.6 then they are from the same person, otherwise they are from different people." & @CRLF & @CRLF _ & "KaFu: I found 0.5 to be more accurate, more testing required") Else ; No match ConsoleWrite("- Face does not seem to match, Euclidean Distance = " & @TAB & $i_128D_Euclidean_Distance & @CRLF) MsgBox(48, "Dlib Face Recognition result - Not matching", "Face does not seem to match" & @CRLF & @CRLF _ & "Euclidean Distance to Face to look for = " & $i_128D_Euclidean_Distance _ & @CRLF & @CRLF & @CRLF & @CRLF & @CRLF & @CRLF _ & "In general, if two face descriptor vectors have a Euclidean distance between them less than 0.6 then they are from the same person, otherwise they are from different people." & @CRLF & @CRLF _ & "KaFu: I found 0.5 to be more accurate, more testing required") EndIf Next Next Func _Euclidean_Distance_of_128D_Vectors($a_Vector_1, $a_Vector_2) If UBound($a_Vector_1) <> 129 Then Return SetError(1, 0, -1) ; 1-based 128 array required If UBound($a_Vector_2) <> 129 Then Return SetError(2, 0, -1) ; https://en.wikipedia.org/wiki/Euclidean_distance Local $i_Euclidean_Distance_of_128D_Vectors For $i = 1 To 128 $i_Euclidean_Distance_of_128D_Vectors += ($a_Vector_1[$i] - $a_Vector_2[$i]) ^ 2 ; ConsoleWrite("_Euclidean_Distance_of_128D_Vectors = " & $i & @TAB & $i_128D_Vector_Euclidean_Distance & @TAB & $a_Vector_1[$i] & @TAB & $a_Vector_2[$i] & @CRLF) Next Return Sqrt($i_Euclidean_Distance_of_128D_Vectors) EndFunc ;==>_Euclidean_Distance_of_128D_Vectors Func show_jittered_images($window, $jittered_images) ; Shows the specified jittered images one by one For $i = 0 To UBound($jittered_images) - 1 Local $img = $jittered_images[$i] $window.set_image($img) MsgBox(0, "show_jittered_images", "jittered image " & $i & ": ") Next EndFunc ;==>show_jittered_images Currently the dll is compiled for 64bit, maybe you could provide a 32bit version too? Your effort is much appreciated 👍!2 points
-
goto specific line in rich edit control
TheAutomator and one other reacted to argumentum for a topic
2 points