Leaderboard
Popular Content
Showing content with the highest reputation on 09/01/2025 in all areas
-
Latest update just released. See below for change log.6 points
-
To flesh this out a bit more - I attempted to recreate this example.. The XML looks like this... <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="3*"/> <ColumnDefinition Width="5*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Border Background="#2f5cb6"/> <Border Grid.Column ="1" Background="#1f3d7a"/> <Border Grid.Row="1" Grid.ColumnSpan="2" Background="#152951"/> <StackPanel Grid.Column="1" Margin="40,0,0,0" VerticalAlignment="Center"> <TextBlock Foreground="White" FontSize="25" Text="Today - 64° F"/> <TextBlock Foreground="White" FontSize="25" Text="Partially Cloudy"/> <TextBlock Foreground="White" FontSize="25" Text="Precipitation: 25%"/> </StackPanel> <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Foreground="White" FontSize="25" Text="High: 66°" Margin="0,0,20,0"/> <TextBlock Foreground="White" FontSize="25" Text="Low: 43°" Margin="0,0,20,0"/> <TextBlock Foreground="White" FontSize="25" Text="Feels like: 63°"/> </StackPanel> <Image Margin="20" Source="Assets/partially-cloudy.png"/> </Grid> Now last time out we were specifying our Row/Column definitions like this.. Local $tGridLen = DllStructCreate("align 1;double Value;ulong GridUnitType") $tGridLen.GridUnitType = $mGridUnitType["Star"] $pRowDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.RowDefinition") $tGridLen.Value = 2 IRowDefinition_SetHeight($pRowDef, $tGridLen) IVector_Append($pRowDefs, $pRowDef) The default interface for a "RowDefinition" is IRowDefinition - but it seems ActivateInstance doesn't put us there. So appending the object to the collection worked OK- the cells obviously appeared. But setting the height property was actually failing. So the learning is: If you're instantiating via ActivateInstance, you should always follow up with a _WinRT_SwitchInterface. Local $tGridLen = DllStructCreate("align 1;double Value;ulong GridUnitType") $tGridLen.GridUnitType = $mGridUnitType["Star"] $pRowDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.RowDefinition") _WinRT_SwitchInterface($pRowDef, $sIID_IRowDefinition) ;ADD THIS! $tGridLen.Value = 2 IRowDefinition_SetHeight($pRowDef, $tGridLen) IVector_Append($pRowDefs, $pRowDef) In this example, we have a few new controls: stackpanels - these work like grids, but the're 1-dimentional. (Edit: Well they have a width and height, but its just one row or one column of panels!) You don't need to assign a "grid spot" for the controls of a stackpanel though - they seem to appear in the order they were added in the IPanel::Children collection. Vectors do assign indexes to child items by memory - so I'd imagine if we shuffled items around via IVector, the GUI would probably follow suit (untested). textblocks - not much to be said about these. But at this point, I'll quickly mention that IFrameworkElement interface seems to look after most of the spatial things for a control (its margins, vertical and horizontal alignment, min/max sizing etc). And this is common across everything we've seen so far. Then we have an image - this one is a bit more interesting. You load it in with a URI, so for local storage we'll need to specify something like file:///C:/path/to/file.blah. Once you have yourself an uri object - we can bring the file in via a BitmapImage object. And finally we associate that with the UI object "controls.Image" Local $pURI_Fact = _WinRT_GetActivationFactory("Windows.Foundation.Uri", $sIID_IUriRuntimeClassFactory) Local $pImageURI = IUriRuntimeClassFactory_CreateWithRelativeUri($pURI_Fact, "file:///C:/FilePath/", "image.png") Local $pBitmap = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Media.Imaging.BitmapImage") _WinRT_SwitchInterface($pBitmap, $sIID_IBitmapImage) IBitmapImage_SetUriSource($pBitmap, $pImageURI) Local $pImage = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Image") _WinRT_SwitchInterface($pImage, $sIID_IImage) IImage_SetSource($pImage, $pBitmap) The loading is asynchronous, so if you need the dimensions of the source for example - those details are only available once the image is ready. If those properties are important we can register a delegate that will fire once the image is loded. Also, if the image fails to load, there's a delegate for that too... Local $pImgFailedDgte = _WinRT_CreateDelegate("ImageLoadFail") Local $iImgFailedDgteTkn = IBitmapImage_AddHdlrImageFailed($pBitmap, $pImgFailedDgte) ;Attempt to load image IBitmapImage_SetUriSource($pBitmap, $pImageURI) Func ImageLoadFail($pThis, $pSource, $pArgs) #forceref $pThis, $pSource, $pArgs ConsoleWrite("Image failed to load!" & @CRLF) EndFunc Final point on this example, I've tied the content bridge's size (the container encompassing the xaml controls) to the Windows WM_SIZE message. Case $WM_SIZE $tRect.Width = BitAND(0xFFFF, $lParam) $tRect.Height = BitShift($lParam, 16) IDesktopSiteBridge_MoveAndResize($pBridge, $tRect) $iReturn = _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) And resizing the window actually works remarkably well. I guess I was expecting some flicker or something- so that was a pleasant surprise! WindowTest Grid.zip3 points
-
WinRT - WinUI3
WildByDesign reacted to MattyD for a topic
Thanks mate, we'll have to credit whoever came up with the design at Microsoft though! This is honestly fine, but we're not exactly asking much of the runtime either at this point in time! Au3check can grind a bit when you really start pushing the #include file count. But for what I'm doing at the moment its OK. I haven't looked at this at all sorry!1 point -
DwmColorBlurMica
argumentum reacted to WildByDesign for a topic
I just updated the first post with the release notes for version 1.2.6 and 1.3.0. The source code on the first post has been updated to the latest source which is 1.3.0.1 point -
WinRT - WinUI3
MattyD reacted to argumentum for a topic
Yes it did. Fun demo, moving the button around ;That last line of the func should be: (Line 37 in WinRT_WinUI3.au3) ;Return SetError($aCall[0], 0, $aCall[0] = $S_OK) ;So _WinUI3_Startup() should return False on failure, and spit out an error code. ... ... _WinRT_Startup() _WinUI3_Startup() If @error Then ConsoleWrite('! install "https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/downloads" to run this.' & @CRLF) Exit 4 EndIf ... ...1 point -
WinRT - WinUI3
argumentum reacted to MattyD for a topic
OK thanks! I've managed to reproduce that on a machine that didn't have the runtime installed - does installing that that fix things? I threw together _WinU3I_Startup() just before uploading, and obviously didn't reintroduce error checking there in the example... And it probably wouldn't have helped anyway, because I've made a mistake in the function! That last line of the func should be: (Line 37 in WinRT_WinUI3.au3) Return SetError($aCall[0], 0, $aCall[0] = $S_OK) So _WinUI3_Startup() should return False on failure, and spit out an error code.1 point -
For even more fun, here are more symbols and also indices available: Func _Exponent($s) Local Static $sInp = "()+-0123456789=AÆBDEƎGHIJKLMNOPRTUWabcdefghijklmnoprstuvwxyz" Local Static $sExp = "⁽⁾⁺⁻⁰¹²³⁴⁵⁶⁷⁸⁹⁼ᴬᴭᴮᴰᴱᴲᴳᴴᴵᴶᴷᴸᴹᴺᴼᴾᴿᵀᵁᵂᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖʳˢᵗᵘᵛʷˣʸᶻ" Local Static $mExp[] If UBound($mExp) = 0 Then For $i = 1 To StringLen($sInp) $mExp[StringMid($sInp, $i, 1)] = StringMid($sExp, $i, 1) Next EndIf Local $c For $i = 1 To StringLen($s) $c = StringMid($s, $i, 1) If MapExists($mExp, $c) Then $s = StringReplace($s, $c, $mExp[$c]) Next Return($s) EndFunc ;==>_Exponent Func _Indice($s) Local Static $sInp = "()+-0123456789=aehijklmnoprstuvx" Local Static $sInd = "₍₎₊₋₀₁₂₃₄₅₆₇₈₉₌ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓ" Local Static $mInd[] If UBound($mInd) = 0 Then For $i = 1 To StringLen($sInp) $mInd[StringMid($sInp, $i, 1)] = StringMid($sInd, $i, 1) Next EndIf Local $c For $i = 1 To StringLen($s) $c = StringMid($s, $i, 1) If MapExists($mInd, $c) Then $s = StringReplace($s, $c, $mInd[$c]) Next Return($s) EndFunc ;==>_Indice1 point
-
Alrighty, here's a couple of general notes around this attachment, then there will be a follow up post with more detail around the Grid stuff. (last one for the weekend I promise!) We can now include "Include\WinRT_WinUI3.au3" which exposes _WinUI3_Startup and _WinUI3_Shutdown. This is basically those boostrapper calls to spin up and down the runtime. In WinRT.au3, I've popped _WinRT_SwitchInterface in as a standard func so we don't have to do multi-step calls through IUnknown to jump between interfaces. I've also added a _WinRT_CreateDelegate() and _WinRT_DestroyDelegate() in WinRT.au3 to do the heavy lifting for creating delegates. So the syntax now looks like this: ; Creation $pBtnClickDelegate = _WinRT_CreateDelegate("BtnClick") $iBtnClickHandlerTkn = IButtonBase_AddHdlrClick($pButton, $pBtnClickDelegate) ; Teardown IButtonBase_RemoveHdlrClick($pButton, $iBtnClickHandlerTkn) _WinRT_DestroyDelegate($pBtnClickDelegate) Func BtnClick($pThis, $pSender, $pArgs) ;Do stuff EndFunc I'll still need to fix up a few more things before popping this all up on sourceforge - but just thought I'd get these quality of life things out the door while I'm feeling energetic! WindowTest - Grid.zip1 point
-
ermar, Certainly - how about this: #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include "GUIListViewEx.au3" Opt("GUIOnEventMode", 1) ; Create GUI $hGUI = GUICreate("LVEx Example", 320, 320) ; Create ListView $cListView = GUICtrlCreateListView("Tom|Dick|Harry", 10, 10, 300, 300, $LVS_SHOWSELALWAYS) _GUICtrlListView_SetExtendedListViewStyle($cListView, $LVS_EX_FULLROWSELECT) _GUICtrlListView_SetColumnWidth($cListView, 0, 93) _GUICtrlListView_SetColumnWidth($cListView, 1, 93) _GUICtrlListView_SetColumnWidth($cListView, 2, 93) ; Set font GUICtrlSetFont($cListView, 12, Default, Default, "Courier New") ; Note edit control will use same font ; Create array and fill listview Global $aLV_List[20] For $i = 0 To UBound($aLV_List) - 1 If Mod($i, 5) Then $aLV_List[$i] = "Tom " & $i & "|Dick " & $i & "|Harry " & $i Else $aLV_List[$i] = "Tom " & $i & "||Harry " & $i EndIf GUICtrlCreateListViewItem($aLV_List[$i], $cListView) Next ; Initiate LVEx $iLV_Left_Index = _GUIListViewEx_Init($cListView, $aLV_List) ; Column 1 & 2 editable - simple text _GUIListViewEx_SetEditStatus($iLV_Left_Index, "1;2") ; Register for sorting, dragging and editing - but do NOT register WM_Notify _GUIListViewEx_MsgRegister(Default) ; Now register the user WM_NOTIFY handler GUIRegisterMsg(0x004E, "_User_WM_NOTIFY_Handler") GUISetState() GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_Ex") While 1 Sleep(10) $vRet = _GUIListViewEx_EventMonitor(0) If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Event error: " & @error) EndIf Switch @extended Case 1 If $vRet = "" Then MsgBox($MB_SYSTEMMODAL, "Edit", "Edit aborted" & @CRLF) Else _ArrayDisplay($vRet, "ListView " & _GUIListViewEx_GetActive() & " content edited", Default, 8) EndIf EndSwitch WEnd Func _Exit_Ex() Exit EndFunc Func _User_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam) ; Do whatever the user handler is supposed to do here ; Must be LAST line of the handler Return(_GUIListViewEx_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam)) EndFunc Please ask if you have any questions. M231 point
-
WinRT - WinUI3
Gianni reacted to WildByDesign for a topic
I personally really appreciate these longer blog-like posts. You are learning this WinUI3 stuff as you go and we are learning along with you (thanks to you). I think that this teaching style of posts is the only way to go, honestly. I also think that this has a lot of great potential for any of us who use AutoIt for making GUI programs. This has the potential to create more opportunities for designing modern looking GUI apps in AutoIt and that is definitely a bonus. Therefore, for any of us that have an interest in that area and who are following along with you, I personally am very thankful for the amount of detail that you share in your posts. You have a good teaching style.1 point -
If you need/want to characterize floats beyond just being of datatype "double", you can pick ideas from this code: Local $a = [ _ [0xfff0000000000000, "-infinity"], _ ; 1 11111111111 0000000000000000000000000000000000000000000000000000 ⎫ [0xffefffffffffffff, "smallest negative normal"], _ ; 1 11111111110 1111111111111111111111111111111111111111111111111111 ⎪ [0x8010000000000000, "largest negative normal"], _ ; 1 00000000001 0000000000000000000000000000000000000000000000000000 ⎪ [0x8000000000000000, "negative zero"], _ ; 1 00000000000 0000000000000000000000000000000000000000000000000000 ⎪ [0x0000000000000000, "positive zero"], _ ; 0 00000000000 0000000000000000000000000000000000000000000000000000 ⎬ Numbers you can deal with [0x0010000000000000, "smallest positive normal"], _ ; 0 00000000001 0000000000000000000000000000000000000000000000000000 ⎪ [0x7fefffffffffffff, "largest positive normal"], _ ; 0 11111111110 1111111111111111111111111111111111111111111111111111 ⎪ [0x7ff0000000000000, "+infinity"], _ ; 0 11111111111 0000000000000000000000000000000000000000000000000000 ⎭ [0x800fffffffffffff, "smallest negative denormal"], _ ; 1 00000000000 1111111111111111111111111111111111111111111111111111 ⎫ [0x8000000000000001, "largest negative denormal"], _ ; 1 00000000000 0000000000000000000000000000000000000000000000000001 ⎬ Numbers best avoided unless [0x0000000000000001, "smallest positive denormal"], _ ; 0 00000000000 0000000000000000000000000000000000000000000000000001 ⎪ dealing with extra-small values [0x000fffffffffffff, "largest positive denormal"], _ ; 0 00000000000 1111111111111111111111111111111111111111111111111111 ⎭ [0xfff8000000000001, "-NAN (quiet, denormal)"], _ ; 1 11111111111 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎫ [0xfff0000000000001, "-NAN (signaling, denormal)"], _ ; 1 11111111111 00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎪ [0xfff4000000000001, "-NAN (signaling, normal)"], _ ; 1 11111111111 0100000000000000000000000000000000000000000000000000 ⎪ [0x7ff4000000000001, "+NAN (signaling, normal)"], _ ; 0 11111111111 0100000000000000000000000000000000000000000000000000 ⎬ You shouldn't get those [0x7ff8000000000001, "+NAN (quiet, denormal)"], _ ; 0 11111111111 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎪ [0x7ff0000000000001, "+NAN (signaling, denormal)"], _ ; 0 11111111111 00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎭ [0xfff8000000000000, " NAN (indeterminate)"] _ ; 1 11111111111 1000000000000000000000000000000000000000000000000000 ◀ You made a big mistake ] ConsoleWrite("Ranges of double values" & @LF) Local $t = DllStructCreate("int64") Local $u = DllStructCreate("double", DllStructGetPtr($t)) Local $v For $n = 0 To UBound($a) - 1 DllStructSetData($t, 1, $a[$n][0]) $v = DllStructGetData($u, 1) ConsoleWrite(StringFormat("%s%23s\t%s\n", VarGetType($v), $v, $a[$n][1])) Next ConsoleWrite(@LF & "FP zeroes are signed !" & @LF) ConsoleWrite(" 0/3" & @TAB & (0/3) & @LF) ConsoleWrite("-0/-3" & @TAB & (-0/-3) & @LF) ConsoleWrite(" 0/-3" & @TAB & (0/-3) & @LF) ConsoleWrite("-0/3" & @TAB & (-0/3) & @LF) ConsoleWrite("Yet (hopefully)" & @LF) ConsoleWrite("0/-3 = 0/3" & @TAB & (0/-3 = 0/3) & @LF) ConsoleWrite("0/-3 = 0" & @TAB & (0/3 = 0) & @LF) ConsoleWrite(@LF & "Infinities compute (but if you get there, you are mostly stuck!)" & @LF) Local Const $PI = 3.141592653589793 ConsoleWrite("3/0" & @TAB & @TAB & (3/0) & @LF) ConsoleWrite("3/0 + 100" & @TAB & (3/0 + 100) & @LF) ConsoleWrite("(3/0) / 2" & @TAB & ((3/0) / 2) & @LF) ConsoleWrite("(3/0) ^ 2" & @TAB & ((3/0) ^ 2) & @LF) ConsoleWrite("-3/0" & @TAB & @TAB & (-3/0) & @LF) ConsoleWrite("-3/0 + 100" & @TAB & (-3/0 + 100) & @LF) ConsoleWrite("(-3/0) / 2" & @TAB & ((-3/0) / 2) & @LF) ConsoleWrite("(-3/0) ^ 2" & @TAB & ((-3/0) ^ 2) & @LF) ConsoleWrite("(-3/0) ^ 5" & @TAB & ((-3/0) ^ 5) & @LF) ConsoleWrite("Log(1/0)" & @TAB & Log(1/0) & @LF) ConsoleWrite("Exp(1/0)" & @TAB & Exp(1/0) & @LF) ConsoleWrite("Tan($Pi/2)" & @TAB & Tan($Pi/2) & @TAB & "<-- should be 'inf'" & @LF) ConsoleWrite("Tan(-$Pi/2)" & @TAB & Tan(-$Pi/2) & @TAB & "<-- should be '-inf'" & @LF) ConsoleWrite("ATan(1/0)" & @TAB & ATan(1/0) & @TAB & @TAB & "<-- Pi/2" & @LF) ConsoleWrite("ATan(-1/0)" & @TAB & ATan(-1/0) & @TAB & "<-- -Pi/2" & @LF) ConsoleWrite("1/(1/0)" & @TAB & @TAB & 1/(1/0) & @LF) ConsoleWrite("-1/(1/0)" & @TAB & -1/(1/0) & @LF) ConsoleWrite("1/(-1/0)" & @TAB & 1/(-1/0) & @LF) ConsoleWrite("-1/(-1/0)" & @TAB & -1/(-1/0) & @LF) ConsoleWrite("0^0)" & @TAB & @TAB & 0^0 & @TAB & @TAB & @TAB & "<-- NOT indeterminate in FP" & @LF) ConsoleWrite("(1/0)^0" & @TAB & @TAB & (1/0)^0 & @TAB & @TAB & @TAB & "<-- NOT indeterminate in FP" & @LF) ConsoleWrite(@LF & "Indeterminate forms" & @LF) Local $ind = [ _ ["0/0", 0/0], _ ["0*(1/0)", 0*(1/0)], _ ["0*(-1/0)", 0*(-1/0)], _ ["(1/0)-(1/0)", (1/0)-(1/0)], _ ["(-1/0)-(-1/0)", (-1/0)-(-1/0)], _ ["(1/0)+(-1/0)", (1/0)+(-1/0)], _ ["(-1/0)+(1/0)", (-1/0)+(1/0)], _ ["1^(1/0)", 1^(1/0)], _ ["1^(-1/0)", 1^(-1/0)], _ ["-1^(1/0)", -1^(1/0)], _ ["-1^(-1/0)", -1^(-1/0)], _ ["Cos(1/0)", Cos(1/0)], _ ["Sin(1/0)", Sin(1/0)], _ ["ACos(5)", ACos(5)], _ ["ASin(5)", ASin(5)], _ ["Sqrt(-1)", Sqrt(-1)], _ ["Log(-1)", Log(-1)] _ ] For $i = 0 To UBound($ind) - 1 ConsoleWrite(StringFormat("%-15s\t%s\t%f\n", $ind[$i][0], VarGetType($ind[$i][1]), $ind[$i][1])) Next ConsoleWrite(@LF & "NANs never compare !" & @LF) ConsoleWrite("0/0 > 0" & @TAB & @TAB & (0/0 > 0) & @LF) ConsoleWrite("0/0 = 0" & @TAB & @TAB & (0/0 = 0) & @LF) ConsoleWrite("0/0 < 0" & @TAB & @TAB & (0/0 < 0) & @LF) ConsoleWrite("0/0 > -0/0" & @TAB & (0/0 > -0/0) & @LF) ConsoleWrite("0/0 = -0/0" & @TAB & (0/0 = -0/0) & @LF) ConsoleWrite("0/0 < -0/0" & @TAB & (0/0 < -0/0) & @LF)1 point
-
Brief: native WinMove() has a "speed" parameter for a more fluent movement. unfortunately, that applies to the change in position, but not the change in size. the position changes in the specified "speed", but size changes abruptly. _WinPose() is similar to WinMove(), except that move and resize are simultaneous, both conform to the speed parameter. UDF: (save as "WinPose.au3") #include-once #include <WinAPISysWin.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinPose ; Description ...: same as native WinMove(), except that move and resize are simultaneous, both conform to the speed parameter. ; Syntax ........: _WinPose($hWnd, $sText, $x, $y, $w, $h[, $speed = 0]) ; Parameters ....: $hWnd - the title/hWnd/class of the window to pose. ; $sText - the text of the window to pose. ; $x - X coordinate to move to. ; $y - Y coordinate to move to. ; $w - [optional] new width of the window. ; $h - [optional] new height of the window. ; $speed - [optional] the speed to pose the window (smaller value = faster speed, 0 = instantaneous). ; Return values .: Success - a handle to the window. ; Failure - 0 if the window is not found (also sets @error to non-zero). ; Author ........: orbs ; Modified ......: ; Remarks .......: parameters and return values are practically identical to those of the native WinMove() function. ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WinPose($hWnd, $sText, $x, $y, $w = Default, $h = Default, $speed = 0) ; find the window to move If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd, $sText) If @error Then Return SetError(1, 0, False) EndIf Local $aPos = WinGetPos($hWnd) If @error Then Return SetError(2, 0, False) ; initialize variables Local Enum $pos_x, $pos_y, $pos_w, $pos_h Local Enum $aiCurrent, $aiTarget, $aiDelta, $aiRatio Local $aPosTarget[4][4] = [[$aPos[$pos_x], $x, 0, 0], [$aPos[$pos_y], $y, 0, 0], [$aPos[$pos_w], $w, 0, 0], [$aPos[$pos_h], $h, 0, 0]] ; accomodate for Default keyword For $iElement = 0 To 3 If $aPosTarget[$iElement][$aiTarget] = Default Then $aPosTarget[$iElement][$aiTarget] = $aPos[$iElement] Next ; calculate delta For $iElement = 0 To 3 $aPosTarget[$iElement][$aiDelta] = $aPosTarget[$iElement][$aiTarget] - $aPosTarget[$iElement][$aiCurrent] Next ; find the maximum delta Local $iMaxElement = 0, $iMaxDelta = 0 For $iElement = 0 To 3 If Abs($aPosTarget[$iElement][$aiDelta]) > $iMaxDelta Then $iMaxElement = $iElement $iMaxDelta = $aPosTarget[$iElement][$aiDelta] EndIf Next ; accomodate for negative delta If ($aPosTarget[$iMaxElement][$aiTarget] - $aPos[$iMaxElement]) < 0 Then $iMaxDelta = -$iMaxDelta ; calculate ratio for all elements For $iElement = 0 To 3 $aPosTarget[$iElement][$aiRatio] = $aPosTarget[$iElement][$aiDelta] / $iMaxDelta Next ; move & resize the window gradually For $iStep = 0 To $iMaxDelta For $iElement = 0 To 3 $aPosTarget[$iElement][$aiCurrent] += $aPosTarget[$iElement][$aiRatio] Next For $i = 1 To $speed _WinAPI_MoveWindow($hWnd, _ $aPosTarget[$pos_x][$aiCurrent], _ $aPosTarget[$pos_y][$aiCurrent], _ $aPosTarget[$pos_w][$aiCurrent], _ $aPosTarget[$pos_h][$aiCurrent], False) Next Next ; validate final outcome is as expected Return WinMove($hWnd, '', $x, $y, $w, $h) EndFunc ;==>_WinPose Example: #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <AutoItConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include 'WinPose.au3' Global Const $iMinW = 250, $iMinH = 100 Global $x, $y, $w, $h, $speed Global $hGUI = GUICreate('_WinPose() Example', $iMinW, $iMinH) Global $gButton = GUICtrlCreateButton('Click Me!', 25, 25, 200, 50) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUISetState(@SW_SHOW) Global $msg While True $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE ExitLoop Case $gButton $w = Random($iMinW, @DesktopWidth / 3, 1) $h = Random($iMinH, @DesktopHeight / 3, 1) $x = Random(0, @DesktopWidth - $w, 1) $y = Random(0, @DesktopHeight - $h, 1) $speed = Random(10, 100, 1) _WinPose($hGUI, '', $x, $y, $w, $h, $speed) EndSwitch WEnd click the button to pose the window in a new random position and size, in a random speed. enjoy 🙂1 point
-
I’m thrilled to introduce my IStream UDF, a sophisticated library designed to handle the COM IStream interface in AutoIt. This UDF enables management of data streams, whether from files, memory, or other sources, leveraging Windows IStream APIs. It provides a reliable solution for reading, writing, and administering streams in your AutoIt scripts. Whether you need to process large files, manipulate in-memory data, or handle transactional streams, this UDF is crafted to be versatile, well-documented, and user-friendly.Key Features Full Implementation of the IStream Interface: Supports all methods of the IStream interface (Read, Write, Seek, SetSize, CopyTo, Commit, Revert, LockRegion, UnlockRegion, Stat, Clone). Support for File and Memory Streams: Create streams from files using _SHCreateStreamOnFileEx or from in-memory data with _StreamCreateFromData, _SHCreateMemStream, and _StreamCreateFromDataOnHGlobal. Advanced Error Handling: Includes a detailed HRESULT error table ($tagIStreamErrorTable) and a _IStream_GetErrorInfo function for clear, understandable error messages. Utility Functions: Functions like _StreamGetSize, _StreamGetName, _StreamGetType, and _StreamStatDisplay simplify access to stream metadata. Comprehensive Documentation: Each function comes with standard UDF-format documentation, including syntax, parameters, return values, remarks, MSDN links, and practical examples. Compatibility: Works with AutoIt 3.3+ and relies on standard libraries (AutoItObject, WinAPI, Memory, Date). Use Cases Reading and writing large files without loading their entire content into memory. Handling in-memory binary data for applications such as network stream processing or serialized data manipulation. Supporting transactional streams for secure operations (e.g., via StgCreateDocfile). Integration with other COM interfaces requiring IStream. you need: AutoItObject.au3 Example: copy data between streams #include "IStream.au3" ; Example demonstrating the use of _StreamCopyToEx to copy data between streams Func Example_StreamCopyToEx() ; Create a source stream with the content "Strong" using _StreamCreateFromDataOnHGlobal ConsoleWrite("Creating source stream with 'Strong'..." & @CRLF) Local $iSrcSize,$aError Local $oSrcStream = _StreamCreateFromDataOnHGlobal("Strong", $iSrcSize, True) If @error Or Not IsObj($oSrcStream) Then ; Handle errors by displaying the HRESULT code and details from $tagIStreamErrorTable ConsoleWrite("Error: Failed to create source stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf Return EndIf ConsoleWrite("Source stream created, size: " & $iSrcSize & " bytes" & @CRLF) ; Create a destination stream with the content "AutoIt is " using _StreamCreateFromDataOnHGlobal ConsoleWrite("Creating destination stream with 'AutoIt is '..." & @CRLF) Local $iDestSize Local $oDestStream = _StreamCreateFromDataOnHGlobal("AutoIt is ", $iDestSize, True) If @error Or Not IsObj($oDestStream) Then ; Handle errors for destination stream creation ConsoleWrite("Error: Failed to create destination stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Release the source stream and COM resources before exiting _StreamRelease($oSrcStream) Return EndIf ConsoleWrite("Destination stream created, size: " & $iDestSize & " bytes" & @CRLF) ; Copy the content from the source stream to the destination stream using _StreamCopyToEx ConsoleWrite("Copying 'Strong' to destination stream..." & @CRLF) Local $iBytesRead, $iBytesWritten If Not _StreamCopyToEx($oSrcStream, $oDestStream, $iSrcSize, $iBytesRead, $iBytesWritten) Then ; Handle errors during the copy operation ConsoleWrite("Error: _StreamCopyToEx failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Release both streams and COM resources before exiting _StreamRelease($oDestStream) _StreamRelease($oSrcStream) Return EndIf ConsoleWrite("Copied " & $iBytesRead & " bytes read, " & $iBytesWritten & " bytes written." & @CRLF) ; Read and display the content of the destination stream ConsoleWrite("Reading destination stream content..." & @CRLF) Local $iNewDestSize = _StreamGetSize($oDestStream) If @error Then ; Handle errors when retrieving the destination stream size ConsoleWrite("Error: Failed to get destination stream size. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Release both streams and COM resources before exiting _StreamRelease($oDestStream) _StreamRelease($oSrcStream) Return EndIf ConsoleWrite("Destination stream size after copy: " & $iNewDestSize & " bytes" & @CRLF) ; Position the stream pointer at the beginning for reading Local $pDestMem, $iDestRead _StreamSeek($oDestStream, 0, $STREAM_SEEK_SET) If @error Then ; Handle errors when seeking in the destination stream ConsoleWrite("Error: Failed to seek destination stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf _StreamRelease($oDestStream) _StreamRelease($oSrcStream) Return EndIf ; Read the content of the destination stream _StreamRead($oDestStream, $iNewDestSize, $pDestMem, $iDestRead) If @error Then ; Handle errors when reading the destination stream ConsoleWrite("Error: Failed to read destination stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Free the memory buffer if allocated, then release streams and COM resources If $pDestMem Then _MemGlobalFree($pDestMem) _StreamRelease($oDestStream) _StreamRelease($oSrcStream) _WinAPI_CoUninitialize() Return EndIf ; Convert the read data to a string and display it Local $bufSize Local $bDestData = _WinAPI_GetBufferData($pDestMem, $bufSize) ConsoleWrite("Destination stream content: " & BinaryToString($bDestData, 4) & @CRLF) ; Free the memory buffer If $pDestMem Then _MemGlobalFree($pDestMem) ; Release both streams to prevent memory leaks _StreamRelease($oDestStream) _StreamRelease($oSrcStream) ConsoleWrite("COM uninitialized, resources freed." & @CRLF) EndFunc ;==>Example_StreamCopyToEx ; Run the example Example_StreamCopyToEx() example demonstrating multiple IStream interface methods #include "IStream.au3" ; Example demonstrating multiple IStream interface methods Func Example_IStream() ; Initialize the COM object model (required for COM API calls) _WinAPI_CoInitialize() ConsoleWrite("=== Creating Stream with SHCreateMemStream ===" & @CRLF) ; Create a memory stream with initial content "Hello, IStream UDF!" Local $sData = "Hello, IStream UDF!" Local $iSize = 0 Local $oStream = _StreamCreateFromData($sData, $iSize) If @error Then ; Handle stream creation error and display details ConsoleWrite("Error: Failed to create stream. @error = " & @error & @CRLF) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Stream created successfully. Size: " & $iSize & " bytes" & @CRLF) ; Test IUnknown::QueryInterface to verify the IStream interface ConsoleWrite("Testing QueryInterface..." & @CRLF) Local $IID_IStream = "{0000000C-0000-0000-C000-000000000046}" Local $pQueriedStream = _StreamQueryInterface($oStream, $IID_IStream) If @error Then ; Handle QueryInterface error and release resources ConsoleWrite("Error: QueryInterface failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("QueryInterface succeeded." & @CRLF) ; Release the queried interface to prevent memory leaks DllCall("ole32.dll", "ulong", "Release", "ptr", $pQueriedStream) ; Test IStream::Write by appending additional data ConsoleWrite("Testing Write..." & @CRLF) Local $sNewData = " Additional data." ; 16 characters Local $iNewSize = 0 Local $pMemory = _StreamCreateMemoryBuffer($sNewData, $iNewSize) If @error Then ; Handle memory buffer creation error ConsoleWrite("Error: Failed to create memory buffer. @error = " & @error & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf Local $iWrittenSize = 0 ; Set the stream size to accommodate new data If Not _StreamSetSize($oStream, $iSize + $iNewSize) Then ConsoleWrite("Error: SetSize failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemory) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Move the stream pointer to the end for appending If Not _StreamSeek($oStream, $iSize, $STREAM_SEEK_SET) Then ConsoleWrite("Error: Seek failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemory) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Write the new data to the stream If Not _StreamWrite($oStream, $pMemory, $iNewSize, $iWrittenSize) Then ConsoleWrite("Error: Write failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemory) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Wrote " & $iWrittenSize & " bytes." & @CRLF) ; Free the memory buffer _WinAPI_FreeMemory($pMemory) ; Test IStream::Seek to move the pointer to the beginning ConsoleWrite("Testing Seek..." & @CRLF) Local $iNewPosition = _StreamSeek($oStream, 0, $STREAM_SEEK_SET) If @error Then ConsoleWrite("Error: Seek failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Stream pointer moved to: " & $iNewPosition & @CRLF) ; Test IStream::Read to retrieve the entire stream content ConsoleWrite("Testing Read..." & @CRLF) Local $pMemoryRead = 0, $iReadSize = 0 If Not _StreamRead($oStream, $iSize + $iNewSize, $pMemoryRead, $iReadSize) Then ConsoleWrite("Error: Read failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemoryRead) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf Local $bData = _WinAPI_GetBufferData($pMemoryRead, $iReadSize) ConsoleWrite("Read " & $iReadSize & " bytes: " & BinaryToString($bData) & @CRLF) _WinAPI_FreeMemory($pMemoryRead) ; Verify that the read data matches the expected content If $iReadSize <> $iSize + $iNewSize Or BinaryToString($bData) <> $sData & $sNewData Then ConsoleWrite("Error: Read data does not match expected: " & $sData & $sNewData & @CRLF) EndIf ; Test IStream::CopyTo by copying the stream to a new destination stream ConsoleWrite("Testing CopyTo..." & @CRLF) ; Create a destination stream Local $pDestStream = _WinAPI_CreateStreamOnHGlobal(0, True) If Not $pDestStream Then ConsoleWrite("Error: Failed to create destination stream." & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Move the source stream pointer to the beginning $iNewPosition = _StreamSeek($oStream, 0, $STREAM_SEEK_SET) If @error Then ConsoleWrite("Error: Seek failed on source stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Copy the content to the destination stream Local $iBytesRead = 0, $iBytesWritten = 0 If Not _StreamCopyTo($oStream, $pDestStream, $iSize + $iNewSize, $iBytesRead, $iBytesWritten) Then ConsoleWrite("Error: CopyTo failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Copied " & $iBytesRead & " bytes read, " & $iBytesWritten & " bytes written." & @CRLF) ; Create an IStream object from the destination stream pointer Local $oDestStream = _AutoItObject_WrapperCreate($pDestStream, $tagIStream) If @error Then ConsoleWrite("Error: Failed to create destination stream object. @error = " & @error & @CRLF) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Read and verify the destination stream content _StreamSeek($oDestStream, 0, $STREAM_SEEK_SET) Local $pDestMemory, $iDestReadSize If Not _StreamRead($oDestStream, $iSize + $iNewSize, $pDestMemory, $iDestReadSize) Then ConsoleWrite("Error: Reading destination stream failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pDestMemory) _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf Local $bDestData = _WinAPI_GetBufferData($pDestMemory, $iDestReadSize) ConsoleWrite("Destination stream content: " & BinaryToString($bDestData, $SB_UTF8) & @CRLF) _WinAPI_FreeMemory($pDestMemory) ; Verify that the copied data matches the expected content ; Test IStream::Commit ConsoleWrite("Testing Commit..." & @CRLF) If Not _StreamCommit($oDestStream, $STGC_DEFAULT) Then ConsoleWrite("Error: Commit failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Commit succeeded." & @CRLF) EndIf ; Test IStream::Revert ConsoleWrite("Testing Revert..." & @CRLF) If Not _StreamRevert($oDestStream) Then ; Note that Revert may not be supported by memory streams ConsoleWrite("Note: Revert may not be supported. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Revert succeeded (unexpected for memory stream)." & @CRLF) EndIf ; Test IStream::LockRegion and UnlockRegion ConsoleWrite("Testing LockRegion..." & @CRLF) If Not _StreamLockRegion($oStream, 0, 10, 0) Then ; Note that LockRegion may not be supported by memory streams ConsoleWrite("Note: LockRegion may not be supported. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) __IStreamErrorInfo(@extended) Else ConsoleWrite("LockRegion succeeded." & @CRLF) ConsoleWrite("Testing UnlockRegion..." & @CRLF) If Not _StreamUnlockRegion($oStream, 0, 10, 0) Then ConsoleWrite("Error: UnlockRegion failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("UnlockRegion succeeded." & @CRLF) EndIf EndIf ; Test IStream::Stat to retrieve stream metadata ConsoleWrite("Testing GetStat..." & @CRLF) Local $pStatFlag = 0 If Not _StreamGetStat($oStream, $pStatFlag) Then ConsoleWrite("Error: GetStat failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Displaying stream metadata:" & @CRLF) _StreamStatDisplay($pStatFlag) _WinAPI_CoTaskMemFree($pStatFlag) ; Test IStream::GetType and GetName ConsoleWrite("Testing GetType and GetName..." & @CRLF) Local $sType = _StreamGetType($oStream) If @error Then ConsoleWrite("Error: GetType failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Stream type: " & $sType & @CRLF) EndIf Local $sName = _StreamGetName($oStream) If @error Then ConsoleWrite("Error: GetName failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Stream name: " & $sName & @CRLF) EndIf ; Test IStream::Clone ConsoleWrite("Testing Clone..." & @CRLF) Local $pCloned Local $oCloneStream = _StreamClone($oStream, $pCloned) If @error Then ConsoleWrite("Error: Clone failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Clone stream created successfully." & @CRLF) _StreamRelease($oCloneStream) DllCall("ole32.dll", "ulong", "Release", "ptr", $pCloned) ; Clean up all resources _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() ConsoleWrite("All streams released and COM uninitialized." & @CRLF) EndFunc ;==>Example_IStream ; Run the example Example_IStream() The help file is included with the UDF IStream.zip New update Description: The IStream2 UDF (Interface Stream User Defined Function) is an AutoIt library designed to create, manipulate, and interact with IStream COM objects, implementing all methods of the IStream interface defined by Microsoft. This interface enables operations such as reading, writing, seeking, and copying on data streams, whether file-based or in-memory. Version 2 of this UDF has been optimized for native AutoIt usage, removing the dependency on AutoItObject.au3, making it lighter, self-contained, and more accessible.The UDF provides robust error handling through HRESULT codes, well-defined constants for COM flags (STGM, STGC, etc.), and comprehensive documentation for each function. It is ideal for developers looking to manipulate data streams in various contexts, such as file processing, memory management, or integration with structured storage systems. The previous version has been retained for compatibility reasons. This version 2 is designed to be fully compatible with any development using the IStorage interface, while avoiding data conflicts. IStream2.au31 point