MattyD
Active Members-
Posts
530 -
Joined
-
Last visited
-
Days Won
28
MattyD last won the day on May 7
MattyD had the most liked content!
MattyD's Achievements
-
pixelsearch reacted to a post in a topic:
Pic control resize issue
-
Maybe using a textured brush for the background could help us here? If we wanted a grid that doesn't grow, we probably should create the brush once and just reuse it for efficiency. #include <GDIPlus.au3> #include <GuiConstants.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> _GDIPlus_Startup() _Example() _GDIPlus_Shutdown() Func _Example() GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") GUICreate("Test Window", 200, 100, -1, -1, $WS_OVERLAPPEDWINDOW) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc Func WM_ERASEBKGND($hWnd, $iMsg, $wParam, $lParam) Local Static $iHGridDiv = 10, $iVGridDiv = 5 Local $tRect = _WinAPI_GetClientRect($hWnd) Local $hTextureBrush = CreateGridTexture(Int($tRect.Right/$iHGridDiv), Int($tRect.Bottom/$iVGridDiv)) Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($wParam) _WinAPI_FillRect($wParam, $tRect, _WinAPI_GetStockObject($WHITE_BRUSH)) _GDIPlus_GraphicsFillRect($hGraphics, 0, 0, $tRect.Right, $tRect.Bottom, $hTextureBrush) _GDIPlus_BrushDispose($hTextureBrush) _GDIPlus_GraphicsDispose($hGraphics) Return 1 EndFunc Func CreateGridTexture($iGridW, $iGridH) Local $hTextureBmp = _GDIPlus_BitmapCreateFromScan0($iGridW, $iGridH) Local $hTextureGraph = _GDIPlus_ImageGetGraphicsContext($hTextureBmp) _GDIPlus_GraphicsClear($hTextureGraph, 0xFF00010) _GDIPlus_GraphicsDrawLine($hTextureGraph, $iGridW-1, 0, $iGridW-1, $iGridH-1) _GDIPlus_GraphicsDrawLine($hTextureGraph, 0, $iGridH-1, $iGridW-1, $iGridH-1) Local $hTextureBrush = _GDIPlus_TextureCreate($hTextureBmp, 0) _GDIPlus_GraphicsDispose($hTextureGraph) _GDIPlus_BitmapDispose($hTextureBmp) Return $hTextureBrush EndFunc
-
argumentum reacted to a post in a topic:
Advanced Icon Displayer In Listview
-
Ok this is still pretty rough in patches, but we have some drag/drop-ability. When dragging icons out the the app, I'm dumping ico files into a temp dir then moving them. Its just easier for dealing with the drag/drop operations for now. I'm using the desktop as a reference point here (in GetDataObjectOfFiles). This is not the %userprofile%\Desktop path - rather its the root for shell file objects. We can't use "..\" for relative paths with IDLs, so my idea was that everything can mapped relative to the root. I *think* this might have caused problems when dragging to unc paths or something though.. Can't really remember! Anyway, we're sourcing everything from that one temp folder - so we should probably just use that for the parent object!. Will fix that one later... _Icons.zip
-
argumentum reacted to a post in a topic:
Advanced Icon Displayer In Listview
-
I think this could be simplified quite a bit... Maybe this as a starting point. If we want to add drag and drop, I have some code somewhere that should take tare of most of the heavy lifting .. I'll see if I can dig it out. #include <GuiConstants.au3> #include <WindowsConstants.au3> #include <GuiListView.au3> #include <WinAPI.au3> #include <GuiImageList.au3> #include <GuiButton.au3> #include <GuiEdit.au3> Global $hGUI, $hListView, $hImageList, $hGo, $hInput _Init() _Main() _Cleanup() Func _Init() Local $iClientW = 420, $iClientH = 400 $hGUI = GUICreate("Icons", $iClientW, $iClientH, -1, -1, $WS_OVERLAPPEDWINDOW) GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") $hListView = _GUICtrlListView_Create($hGUI, "", 0, 0, 0, 0, BitOR($LVS_ICON, $LVS_AUTOARRANGE), $WS_EX_CLIENTEDGE) $hGo = _GUICtrlButton_Create($hGUI, "Go", 0, 0, 0, 0, $BS_DEFPUSHBUTTON) $hInput = _GUICtrlEdit_Create($hGUI, "C:\Windows\System32\imageres.dll", 0, 0, 0, 0, $ES_LEFT) _GUICtrlListView_SetExtendedListViewStyle($hListView, $LVS_EX_BORDERSELECT) GUISetState() EndFunc Func _Main() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc Func _Cleanup() ClearImages() GUIDelete($hGUI) EndFunc Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) If ($lParam = $hGo) And (_WinAPI_HiWord($wParam) = $BN_CLICKED) Then GetImages(_GUICtrlEdit_GetText($hInput)) If (_WinAPI_HiWord($wParam) = 0) And (_WinAPI_LoWord($wParam) = $IDOK) Then If _WinAPI_GetFocus() = $hInput Then GetImages(_GUICtrlEdit_GetText($hInput)) EndIf EndFunc Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) Local $iClientW = _WinAPI_WordToShort(_WinAPI_LoWord($lParam)) Local $iClientH = _WinAPI_WordToShort(_WinAPI_HiWord($lParam)) _WinAPI_MoveWindow($hInput, 10, 10, $iClientW - 110, 25) _WinAPI_MoveWindow($hGo, $iClientW - 90, 10, 80, 25) _WinAPI_MoveWindow($hListView, 10, 45, $iClientW - 20, $iClientH - 55) _GUICtrlListView_SetWorkAreas($hListView, 0, 0, $iClientW - 20, $iClientH - 55) EndFunc Func ClearImages() _GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_DeleteAllItems($hListView) _GUIImageList_Destroy($hImageList) _GUICtrlListView_EndUpdate($hListView) EndFunc Func GetImages($sFile) ClearImages() _GUICtrlListView_BeginUpdate($hListView) If Not FileExists($sFile) Then Return If StringInStr(FileGetAttrib($sFile), "D") Then Return Local $aCall = DllCall('shell32.dll', 'uint', 'ExtractIconExW', 'wstr', $sFile, 'int', -1, 'ptr', 0, 'ptr', 0, 'uint', 0) If @error Then Return SetError(@error, @extended, 0) Local $iNumIcons = $aCall[0] Local $tIcons = DllStructCreate(StringFormat("handle icons[%d]", $iNumIcons)) Local $aIconInfo, $iBuffSize, $tObj, $tBmp Local $aCall = DllCall('shell32.dll', 'uint', 'ExtractIconExW', 'wstr', $sFile, 'int', 0, 'struct*', $tIcons, 'ptr', 0, 'uint', $iNumIcons) If Not $aCall[0] Then Return $aIconInfo = _WinAPI_GetIconInfo($tIcons.icons(1)) $iBuffSize = _WinAPI_GetObject($aIconInfo[5], 0, 0) $tObj = DllStructCreate(StringFormat("byte[%d]", $iBuffSize)) _WinAPI_GetObject($aIconInfo[5], DllStructGetSize($tObj), DllStructGetPtr($tObj)) $tBmp = DllStructCreate($tagBITMAP, DllStructGetPtr($tObj)) $hImageList = _GUIImageList_Create($tBmp.bmWidth, $tBmp.bmHeight, (Log($tBmp.bmBitsPixel)/Log(2)), 1, $iNumIcons, $iNumIcons) For $i = 1 To $iNumIcons $aIconInfo = _WinAPI_GetIconInfo($tIcons.icons(($i))) $iBuffSize = _WinAPI_GetObject($aIconInfo[5], 0, 0) $tObj = DllStructCreate(StringFormat("byte[%d]", $iBuffSize)) _WinAPI_GetObject($aIconInfo[5], DllStructGetSize($tObj), DllStructGetPtr($tObj)) _GUIImageList_Add($hImageList, $aIconInfo[5], $aIconInfo[4]) _GUICtrlListView_SetImageList($hListView, $hImageList) _GUICtrlListView_AddItem($hListView, $i, $i - 1) _WinAPI_DestroyIcon($tIcons.icons(1)) Next _GUICtrlListView_EndUpdate($hListView) EndFunc Edit.. Obviously this needs more work. I've just thrown this thing together...
-
We can animate! to a degree. Here we're binding the stackpanel's "Spacing" property to a double animation. That's double as in a 64bit float- not a 2x animation! ;~ #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y #Tidy_Parameters=/sf #include "..\Include\WinRT.au3" #include "..\Include\WinRT_WinUI3.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Application.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.LaunchActivatedEventArgs.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Window.au3" #include "..\Include\Classes\Microsoft.UI.Windowing.AppWindow.au3" #include "..\Include\Classes\Microsoft.UI.Windowing.AppWindowPresenter.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.Stackpanel.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.FontIcon.au3" #include "..\Include\Enumerations\Microsoft.UI.Xaml.Controls.Symbol.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.Button.au3" #include "..\Include\Classes\Windows.Foundation.PropertyValue.au3" #include "..\Include\Interfaces\Windows.Foundation.Collections.IVector.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Media.Animation.Storyboard.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Media.Animation.DoubleAnimation.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Media.Animation.ObjectAnimationUsingKeyFrames.au3" Global Const $sIID_IReference_1_Double_ = "{2F2D6C29-5473-5F3E-92E7-96572BB990E2}" $__g_mIIDs[$sIID_IReference_1_Double_] = "IReference_1_Double_" Global $mDurationType[] $mDurationType["Automatic"] = 0x00000000 $mDurationType["TimeSpan"] = 0x00000001 $mDurationType["Forever"] = 0x00000002 __WinRT_AddReverseMappings($mDurationType) Global $pStoryboard, $pPlayButton Global $aDelegates[10] _WinRT_Startup() If @error Then Exit MsgBox(0, "WinRT Startup", "Error Initialising: " & _WinAPI_GetErrorMessage(@error)) _WinUI3_Startup() If @error Then MsgBox(0, "WinRT Startup", "Error Initialising: " & _WinAPI_GetErrorMessage(@error)) _WinRT_Shutdown() Exit EndIf _WinUI3_StartApp("OnLaunched") _WinUI3_Shutdown() _WinRT_Shutdown() Cleanup() Func OnLaunched($pApplication, $pEventArgs) #forceref $pApplication, $pEventArgs ;Setup Window Local $pWindow = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Window") _WinRT_SwitchInterface($pWindow, $sIID_IWindow) IWindow_SetTitle($pWindow, "Animation Test") _WinRT_SwitchInterface($pWindow, $sIID_IWindow2) Local $pAppWindow = IWindow2_GetAppWindow($pWindow) Local $tRectInt = DllStructCreate("int X;int Y;int Width; int Height") $tRectInt.Width = 300 $tRectInt.Height = 100 $tRectInt.X = (@DesktopWidth - $tRectInt.Width) / 2 $tRectInt.Y = (@DesktopHeight - $tRectInt.Height) / 2 _WinRT_SwitchInterface($pAppWindow, $sIID_IAppWindow) IAppWindow_MoveAndResize($pAppWindow, $tRectInt) IUnknown_Release($pAppWindow) ;Create Stackpanel for buttons. Local $pStackPanel = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.StackPanel") _WinRT_SwitchInterface($pStackPanel, $sIID_IStackPanel) IStackPanel_SetOrientation($pStackPanel, $mOrientation["Horizontal"]) Local $tPadding = DllStructCreate("struct;double Left;double Top;double Right; double Bottom;endstruct") $tPadding.Left = 10 $tPadding.Top = 10 $tPadding.Right = 10 $tPadding.Bottom = 10 IStackPanel_SetPadding($pStackPanel, $tPadding) _WinRT_SwitchInterface($pWindow, $sIID_IWindow) IWindow_SetContent($pWindow, $pStackPanel) ;Create play button $pPlayButton = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Button") ButtonSetGlyph($pPlayButton, "Play") PanelAddChild($pStackPanel, $pPlayButton) _WinRT_SwitchInterface($pPlayButton, $sIID_IButtonBase) IButtonBase_AddHdlrClick($pPlayButton, CreateDelegate("Play")) ;~ ;Create reset button Local $pResetButton = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Button") ButtonSetGlyph($pResetButton, "Previous") PanelAddChild($pStackPanel, $pResetButton) _WinRT_SwitchInterface($pResetButton, $sIID_IButtonBase) IButtonBase_AddHdlrClick($pResetButton, CreateDelegate("Reset")) IUnknown_Release($pResetButton) ;~ ;Create reset button Local $pEndButton = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Button") ButtonSetGlyph($pEndButton, "Next") PanelAddChild($pStackPanel, $pEndButton) _WinRT_SwitchInterface($pEndButton, $sIID_IButtonBase) IButtonBase_AddHdlrClick($pEndButton, CreateDelegate("GotoEnd")) IUnknown_Release($pEndButton) ;Animation Local $pSpacingAni = CreateDoubleAnimation(0, 50, 1000) $pStoryboard = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Media.Animation.Storyboard") StoryboardAddAnimation($pStoryboard, $pSpacingAni) _WinRT_SwitchInterface($pStackPanel, $sIID_IDependencyObject) _WinRT_SwitchInterface($pStoryboard, $sIID_ITimeline) ITimeline_AddHdlrCompleted($pStoryboard, CreateDelegate("AniComplete")) Local $pSboardStatics = _WinRT_GetActivationFactory("Microsoft.UI.Xaml.Media.Animation.Storyboard", $sIID_IStoryboardStatics) IStoryboardStatics_SetTargetProperty($pSboardStatics, $pSpacingAni, "Spacing") IStoryboardStatics_SetTarget($pSboardStatics, $pSpacingAni, $pStackPanel) IUnknown_Release($pSboardStatics) IUnknown_Release($pSpacingAni) IUnknown_Release($pStackPanel) ;Activate window _WinRT_SwitchInterface($pWindow, $sIID_IWindow) IWindow_Activate($pWindow) IUnknown_Release($pWindow) EndFunc ;==>OnLaunched Func Cleanup() IUnknown_Release($pStoryboard) IUnknown_Release($pPlayButton) For $i = 0 To UBound($aDelegates) - 1 If $aDelegates[$i] Then _WinRT_DestroyDelegate($aDelegates[$i]) Next EndFunc Func CreateDoubleAnimation($iFrom, $iTo, $iTime = Default) Local $pAnimation = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Media.Animation.DoubleAnimation") _WinRT_SwitchInterface($pAnimation, $sIID_IDoubleAnimation) IDoubleAnimation_SetEnableDependentAnimation($pAnimation, True) Local $pProp_Fact = _WinRT_GetActivationFactory("Windows.Foundation.PropertyValue", $sIID_IPropertyValueStatics) Local $pAniFrom = IPropertyValueStatics_CreateDouble($pProp_Fact, $iFrom) Local $pAniTo = IPropertyValueStatics_CreateDouble($pProp_Fact, $iTo) _WinRT_SwitchInterface($pAniFrom, $sIID_IReference_1_Double_) _WinRT_SwitchInterface($pAniTo, $sIID_IReference_1_Double_) IDoubleAnimation_SetFrom($pAnimation, $pAniFrom) IDoubleAnimation_SetTo($pAnimation, $pAniTo) IUnknown_Release($pAniFrom) IUnknown_Release($pAniTo) IUnknown_Release($pProp_Fact) Local $tTimespan = DllStructCreate("align 1;int64 duration;int type") If $iTime = Default Or $iTime < 0 Then $tTimespan.type = $mDurationType["Automatic"] Else $tTimespan.duration = $iTime * 10000 $tTimespan.type = $mDurationType["TimeSpan"] EndIf _WinRT_SwitchInterface($pAnimation, $sIID_ITimeline) ITimeline_SetDuration($pAnimation, $tTimespan) Return $pAnimation EndFunc Func StoryboardAddAnimation($pStoryboard, $pTimeline) _WinRT_SwitchInterface($pStoryboard, $sIID_IStoryboard) _WinRT_SwitchInterface($pTimeline, $sIID_ITimeline) Local $pChildren = IStoryboard_GetChildren($pStoryboard) IVector_Append($pChildren, $pTimeline) IUnknown_Release($pChildren) EndFunc Func ButtonSetGlyph($pButton, $sSymbol) Local $pButtonIcon = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.FontIcon") _WinRT_SwitchInterface($pButtonIcon, $sIID_IFontIcon) IFontIcon_SetGlyph($pButtonIcon, ChrW($mSymbol[$sSymbol])) _WinRT_SwitchInterface($pButton, $sIID_IContentControl) IContentControl_SetContent($pButton, $pButtonIcon) IUnknown_Release($pButtonIcon) EndFunc ;==>ButtonSetGlyph Func PanelAddChild($pPanel, $pChild) _WinRT_SwitchInterface($pPanel, $sIID_IPanel) _WinRT_SwitchInterface($pChild, $sIID_IUIElement) Local $pChildren = IPanel_GetChildren($pPanel) IVector_Append($pChildren, $pChild) IUnknown_Release($pChildren) EndFunc ;==>PanelAddChild Func CreateDelegate($sName, $sType = "") Local Static $iCount If $iCount = UBound($aDelegates) Then ReDim $aDelegates[UBound($aDelegates) + 10] $aDelegates[$iCount] = _WinRT_CreateDelegate($sName, $sType) $iCount += 1 Return $aDelegates[$iCount - 1] EndFunc ;==>CreateDelegate Func Play($pThis, $pSender, $pArgs) _WinRT_SwitchInterface($pStoryboard, $sIID_IStoryboard) Local Static $sLastAction Switch _WinRT_GetEnum($mClockState, IStoryboard_GetCurrentState($pStoryboard)) Case "Stopped" IStoryboard_Begin($pStoryboard) ButtonSetGlyph($pSender, "Pause") $sLastAction = "Play" Case "Filling" IStoryboard_Stop($pStoryboard) ButtonSetGlyph($pSender, "Play") $sLastAction = "Stop" Case "Active" If $sLastAction = "Play" Then IStoryboard_Pause($pStoryboard) ButtonSetGlyph($pSender, "Play") $sLastAction = "Pause" Else IStoryboard_Resume($pStoryboard) ButtonSetGlyph($pSender, "Pause") $sLastAction = "Play" EndIf EndSwitch EndFunc Func Reset($pThis, $pSender, $pArgs) _WinRT_SwitchInterface($pStoryboard, $sIID_IStoryboard) IStoryboard_Stop($pStoryboard) ButtonSetGlyph($pPlayButton, "Play") EndFunc Func GotoEnd($pThis, $pSender, $pArgs) _WinRT_SwitchInterface($pStoryboard, $sIID_IStoryboard) IStoryboard_Begin($pStoryboard) IStoryboard_SkipToFill($pStoryboard) EndFunc Func AniComplete($pThis, $pSender, $pArgs) _WinRT_SwitchInterface($pSender, $sIID_IStoryboard) ButtonSetGlyph($pPlayButton, "Stop") EndFunc But what if the property we want to bind to isn't a float? Well we can create a different type of animation like ObjectAnimationUsingKeyFrames, which in theory lets us attach to other types. Our values do need to be "boxed" though. They need to be wrapped up as an IReference object - like so: Windows.Foundation.IReference`1<Double> Windows.Foundation.IReference`1<Int32> Windows.Foundation.IReference`1<Windows.Foundation.Point> etc... All these common types can be instantiated through a Windows.Foundation.PropertyValue statics object. And presumably it should cover a good chunk of what we'll be realistically be dealing with. But say we wanted to animate something different, for eg. Microsoft.UI.Xaml.GridLength. This one is a "double;int32" struct, and we can't create that via a PropertyValue object. We need a "Windows.Foundation.IReference`1<Microsoft.UI.Xaml.GridLength>". In C++ its simple enough, but I've no idea how to replicate/get at it... winrt::box_value(Value) I might see if we just create our own implementation of the IReference interface for now. (i.e. build our own IReference object). We can generate IIDs though _WinRT_GetParameterizedTypeInstanceIID provided we're using genuine WinRT classnames. What can possibly go wrong!
-
MattyD reacted to a post in a topic:
WinRT Object Libraries
-
MattyD reacted to a post in a topic:
WinRT - WinUI3
-
CYCho reacted to a post in a topic:
WinRT - WinUI3
-
@CYCho, I've been having a bit of a play with the WinUI3 media player over the last couple of days. Its still pretty rough, and there's not a lot of error checking going on - but thought you might want a look. There's issues with displaying the internal transport controls - my best guess is that we're missing some resources. But in the meantime we can just create our own. I've added in some extra bits as an experiment. There's an idle timer on the mouse. If you're in fullscreen, after a couple of seconds of inactivity the controls will hide and the cursor will disappear. I think we can animate the controls hiding too - but I need to look a bit closer at that. You can double click/double tap the player to enter/exit fullscreen Added in some KB accelerators. Space or P - Play/Pause, O - Open File, F - Fullscreen #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y #Tidy_Parameters=/sf #include "..\Include\WinRT.au3" #include "..\Include\WinRT_WinUI3.au3" ;~ #include "..\Include\Interfaces\IInputCursorStaticsInterop.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Application.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.LaunchActivatedEventArgs.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Window.au3" #include "..\Include\Classes\Microsoft.UI.Windowing.AppWindow.au3" #include "..\Include\Classes\Microsoft.UI.Windowing.AppWindowPresenter.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.XamlRoot.au3" #include "..\Include\Classes\Microsoft.UI.Content.ContentIslandEnvironment.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.Grid.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.RowDefinitionCollection.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.ColumnDefinitionCollection.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.RowDefinition.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.ColumnDefinition.au3" #include "..\Include\Enumerations\Microsoft.UI.Xaml.GridUnitType.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.Stackpanel.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.FontIcon.au3" #include "..\Include\Enumerations\Microsoft.UI.Xaml.Controls.Symbol.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.Button.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.Slider.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Input.KeyboardAccelerator.au3" #include "..\Include\Classes\Windows.Foundation.PropertyValue.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.MediaPlayerElement.au3" #include "..\Include\Classes\Windows.Storage.StorageFile.au3" #include "..\Include\Classes\Windows.Media.Core.MediaSource.au3" #include "..\Include\Classes\Windows.Media.Core.MediaSourceStateChangedEventArgs.au3" #include "..\Include\Classes\Windows.Media.Playback.MediaPlayer.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.Controls.MediaTransportControls.au3" #include "..\Include\Classes\Microsoft.UI.Xaml.DispatcherTimer.au3" #include "..\Include\Classes\Microsoft.UI.Input.InputCursor.au3" #include "..\Include\Classes\Windows.UI.Core.CoreCursor.au3" #include "..\Include\Classes\Microsoft.Windows.Storage.Pickers.FileOpenPicker.au3" #include "..\Include\Classes\Microsoft.Windows.Storage.Pickers.PickFileResult.au3" Global Const $sIID_IInputCursorStaticsInterop = "{AC6F5065-90C4-46CE-BEB7-05E138E54117}" $__g_mIIDs[$sIID_IInputCursorStaticsInterop] = "IInputCursorStaticsInterop" Global $iAppWindowId, $iWindowId Global $iMediaDuration, $sPlayerState Global $pPlayer, $pColCtrlRowDef, $pPlayButton, $pFullScrButton, $pMediaPlayerElement, $pTimer Global $bAreCtrlsHidden Global $aDelegates[10] _WinAPI_SetThreadExecutionState(BitOR($ES_CONTINUOUS, $ES_DISPLAY_REQUIRED)) _WinRT_Startup() If @error Then Exit MsgBox(0, "WinRT Startup", "Error Initialising: " & _WinAPI_GetErrorMessage(@error)) _WinUI3_Startup() If @error Then MsgBox(0, "WinRT Startup", "Error Initialising: " & _WinAPI_GetErrorMessage(@error)) _WinRT_Shutdown() Exit EndIf _WinUI3_StartApp("OnLaunched") Cleanup() _WinUI3_Shutdown() _WinRT_Shutdown() Func OnLaunched($pApplication, $pEventArgs) #forceref $pApplication, $pEventArgs ;Setup Window Local $pWindow = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Window") _WinRT_SwitchInterface($pWindow, $sIID_IWindow) IWindow_SetTitle($pWindow, "Media Player") _WinRT_SwitchInterface($pWindow, $sIID_IWindow2) Local $pAppWindow = IWindow2_GetAppWindow($pWindow) _WinRT_SwitchInterface($pAppWindow, $sIID_IAppWindow) $iAppWindowId = IAppWindow_GetId($pAppWindow) Local $tRectInt = DllStructCreate("int X;int Y;int Width; int Height") $tRectInt.Width = 800 $tRectInt.Height = 450 $tRectInt.X = (@DesktopWidth - $tRectInt.Width) / 2 $tRectInt.Y = (@DesktopHeight - $tRectInt.Height) / 2 IAppWindow_MoveAndResize($pAppWindow, $tRectInt) IUnknown_Release($pAppWindow) ;Create Grid Local $pGrid = CreateGrid() IUnknown_Release(GridAddRow($pGrid)) $pColCtrlRowDef = GridAddRow($pGrid, 60, "Pixel") IUnknown_Release(GridAddColumn($pGrid)) _WinRT_SwitchInterface($pWindow, $sIID_IWindow) IWindow_SetContent($pWindow, $pGrid) ;Create Stackpanel for buttons. Local $pStackPanel = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.StackPanel") _WinRT_SwitchInterface($pStackPanel, $sIID_IStackPanel) IStackPanel_SetOrientation($pStackPanel, $mOrientation["Horizontal"]) IStackPanel_SetSpacing($pStackPanel, 10) Local $tPadding = DllStructCreate("struct;double Left;double Top;double Right; double Bottom;endstruct") $tPadding.Left = 10 $tPadding.Top = 10 $tPadding.Right = 10 $tPadding.Bottom = 10 IStackPanel_SetPadding($pStackPanel, $tPadding) PanelAddChild($pGrid, $pStackPanel) UIElementAssignGridPos($pStackPanel, 2, 1) ;Create Play/Pause Button $pPlayButton = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Button") _WinRT_SwitchInterface($pPlayButton, $sIID_IFrameworkElement) ButtonSetGlyph($pPlayButton, "Play") PanelAddChild($pStackPanel, $pPlayButton) _WinRT_SwitchInterface($pPlayButton, $sIID_IButtonBase) IButtonBase_AddHdlrClick($pPlayButton, CreateDelegate("Play")) UIElementAssignAccel($pPlayButton, "Space") UIElementAssignAccel($pPlayButton, "P") ;Create Fullscreen Button $pFullScrButton = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Button") ButtonSetGlyph($pFullScrButton, "FullScreen") PanelAddChild($pStackPanel, $pFullScrButton) _WinRT_SwitchInterface($pFullScrButton, $sIID_IButtonBase) Local $pFullScrDgt = CreateDelegate("FullScreen") IButtonBase_AddHdlrClick($pFullScrButton, $pFullScrDgt) UIElementAssignAccel($pFullScrButton, "F") ;Open Button Local $pFileOpenButton = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Button") ButtonSetGlyph($pFileOpenButton, "OpenFile") PanelAddChild($pStackPanel, $pFileOpenButton) _WinRT_SwitchInterface($pFileOpenButton, $sIID_IButtonBase) IButtonBase_AddHdlrClick($pFileOpenButton, CreateDelegate("OpenMedia")) UIElementAssignAccel($pFileOpenButton, "O") IUnknown_Release($pFileOpenButton) IUnknown_Release($pStackPanel) ;Create Player Element $pMediaPlayerElement = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.MediaPlayerElement") _WinRT_SwitchInterface($pMediaPlayerElement, $sIID_IFrameworkElement) PanelAddChild($pGrid, $pMediaPlayerElement) _WinRT_SwitchInterface($pGrid, $sIID_IUIElement) ;Add mouse idle handler etc. $pTimer = _WinRT_ActivateInstance("Microsoft.UI.Xaml.DispatcherTimer") _WinRT_SwitchInterface($pTimer, $sIID_IDispatcherTimer) IDispatcherTimer_AddHdlrTick($pTimer, CreateDelegate("TimerExp")) IDispatcherTimer_SetInterval($pTimer, 3 * 10000000) IDispatcherTimer_Start($pTimer) IUIElement_AddHdlrPointerMoved($pGrid, CreateDelegate("MouseMoved")) IUnknown_Release($pGrid) ;Add double tap handler _WinRT_SwitchInterface($pMediaPlayerElement, $sIID_IUIElement) IUIElement_AddHdlrDoubleTapped($pMediaPlayerElement, $pFullScrDgt) ;Create the underlying player object $pPlayer = _WinRT_ActivateInstance("Windows.Media.Playback.MediaPlayer") _WinRT_SwitchInterface($pPlayer, $sIID_IMediaPlayer) Local $pPlayerStateChgDgt = CreateDelegate("PlayerStateChange", "Windows.Foundation.TypedEventHandler`2<Windows.Media.Playback.MediaPlayer, Object>") IMediaPlayer_AddHdlrCurrentStateChanged($pPlayer, $pPlayerStateChgDgt) ;Attach the player obj to the XAML control. _WinRT_SwitchInterface($pMediaPlayerElement, $sIID_IMediaPlayerElement) IMediaPlayerElement_SetMediaPlayer($pMediaPlayerElement, $pPlayer) ;Activate window _WinRT_SwitchInterface($pWindow, $sIID_IWindow) IWindow_Activate($pWindow) IUnknown_Release($pWindow) OpenMedia(0, 0, 0) EndFunc ;==>OnLaunched Func Cleanup() IUnknown_Release($pColCtrlRowDef) IUnknown_Release($pFullScrButton) IUnknown_Release($pPlayButton) IUnknown_Release($pMediaPlayerElement) IUnknown_Release($pTimer) If $pPlayer Then ;~ _WinRT_SwitchInterface($pPlayer, $sIID_IClosable) ;~ IClosable_Close($pPlayer) IUnknown_Release($pPlayer) EndIf For $i = 0 To UBound($aDelegates) - 1 If $aDelegates[$i] Then _WinRT_DestroyDelegate($aDelegates[$i]) Next EndFunc ;==>Cleanup Func _WinAPI_CreateCursor($hInst, $iXHotSpot, $iYHotSpot, $iWidth, $iHeight, $tANDPlane, $tORPlane) Local $aCall = DllCall("User32.dll", "handle", "CreateCursor", "handle", $hInst, "int", $iXHotSpot, "int", $iYHotSpot, "int", $iWidth, "int", $iHeight, "struct*", $tANDPlane, "struct*", $tORPlane) If @error Then Return SetError(@error, @extended, 0) Return $aCall[0] EndFunc ;==>_WinAPI_CreateCursor ;modfied to include indefinate wait. Func _WinRT_WaitForAsync2(ByRef $pAsync, $sDataType = "ptr*", $iTimeout = 500) Local $pAsyncInfo = IUnknown_QueryInterface($pAsync, $sIID_IAsyncInfo) If @error Then Return SetError(@error, @extended, -1) Local $hTimer = TimerInit() Local $iStatus, $iError, $vResult = Null Do $iStatus = IAsyncInfo_GetStatus($pAsyncInfo) If ($iTimeout > 0) And (TimerDiff($hTimer) > $iTimeout) Then ExitLoop Sleep(10) Until $iStatus <> _WinRT_GetEnum($mAsyncStatus, "Started") Switch $iStatus Case _WinRT_GetEnum($mAsyncStatus, "Started") $iStatus = -1 $iError = $WAIT_TIMEOUT Case Else $iError = IAsyncInfo_GetErrorCode($pAsyncInfo) EndSwitch If $iStatus = _WinRT_GetEnum($mAsyncStatus, "Completed") Then IUnknown_QueryInterface($pAsync, $sIID_IAsyncAction) If Not @error Then $vResult = ($iError = $S_OK) Else $vResult = IAsyncOperation_GetResults($pAsync, $sDataType) If @error Then $iError = @error EndIf EndIf _WinRT_DeleteObject($pAsync) Return SetError($iError, $iStatus, $vResult) EndFunc ;==>_WinRT_WaitForAsync2 Func ButtonSetGlyph($pButton, $sSymbol) Local $pButtonIcon = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.FontIcon") _WinRT_SwitchInterface($pButtonIcon, $sIID_IFontIcon) IFontIcon_SetGlyph($pButtonIcon, ChrW($mSymbol[$sSymbol])) _WinRT_SwitchInterface($pButton, $sIID_IContentControl) IContentControl_SetContent($pButton, $pButtonIcon) IUnknown_Release($pButtonIcon) EndFunc ;==>ButtonSetGlyph Func CreateDelegate($sName, $sType = "") Local Static $iCount If $iCount = UBound($aDelegates) Then ReDim $aDelegates[UBound($aDelegates) + 10] $aDelegates[$iCount] = _WinRT_CreateDelegate($sName, $sType) $iCount += 1 Return $aDelegates[$iCount - 1] EndFunc ;==>CreateDelegate Func CreateGrid($iRows = 0, $iCols = 0) Local $pGrid = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Grid") _WinRT_SwitchInterface($pGrid, $sIID_IGrid) Local $tGridLen = DllStructCreate("struct;double Value;ulong GridUnitType;endstruct") $tGridLen.Value = 1 $tGridLen.GridUnitType = $mGridUnitType["Star"] Local $pRowDefs = IGrid_GetRowDefinitions($pGrid) _WinRT_SwitchInterface($pRowDefs, $sIID_IVector_1_RowDefinition_) Local $pRowDef For $i = 0 To $iRows - 1 $pRowDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.RowDefinition") _WinRT_SwitchInterface($pRowDef, $sIID_IRowDefinition) IRowDefinition_SetHeight($pRowDef, $tGridLen) IVector_Append($pRowDefs, $pRowDef) IUnknown_Release($pRowDef) Next IUnknown_Release($pRowDefs) Local $pColDefs = IGrid_GetColumnDefinitions($pGrid) _WinRT_SwitchInterface($pColDefs, $sIID_IVector_1_ColumnDefinition_) Local $pColDef For $i = 0 To $iCols - 1 $pColDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.ColumnDefinition") _WinRT_SwitchInterface($pColDef, $sIID_IColumnDefinition) IColumnDefinition_SetWidth($pColDef, $tGridLen) IVector_Append($pColDefs, $pColDef) IUnknown_Release($pColDef) Next IUnknown_Release($pColDefs) Return $pGrid EndFunc ;==>CreateGrid Func CreateHiddenCursor() Local $hInst = _WinAPI_GetModuleHandle(0) Local $tANDPlane = DllStructCreate("byte plane[1]") Local $tXORPlane = DllStructCreate("byte plane[1]") $tANDPlane.plane = 0x80 $tXORPlane.plane = 0 Return _WinAPI_CreateCursor($hInst, 0, 0, 1, 1, $tANDPlane, $tXORPlane) EndFunc ;==>CreateHiddenCursor Func FullScreen($pThis, $pSender, $pArgs) #forceref $pThis, $pSender, $pArgs Local $pAppWindow = GetAppWindowFromId($iAppWindowId) _WinRT_SwitchInterface($pAppWindow, $sIID_IAppWindow) _WinRT_SwitchInterface($pMediaPlayerElement, $sIID_IMediaPlayerElement) Local $pPresenter = IAppWindow_GetPresenter($pAppWindow) Switch _WinRT_GetEnum($mAppWindowPresenterKind, IAppWindowPresenter_GetKind($pPresenter)) Case "FullScreen" IMediaPlayerElement_SetIsFullWindow($pMediaPlayerElement, False) IAppWindow_SetPresenter2($pAppWindow, $mAppWindowPresenterKind["Overlapped"]) ButtonSetGlyph($pFullScrButton, "FullScreen") Case "Overlapped" IMediaPlayerElement_SetIsFullWindow($pMediaPlayerElement, True) IAppWindow_SetPresenter2($pAppWindow, $mAppWindowPresenterKind["FullScreen"]) ButtonSetGlyph($pFullScrButton, "BackToWindow") HideControls(False) EndSwitch IUnknown_Release($pPresenter) IUnknown_Release($pAppWindow) EndFunc ;==>FullScreen Func GetAppWindowFromId($iAppWindowId) Local $pAppWinStatics = _WinRT_GetActivationFactory("Microsoft.UI.Windowing.AppWindow", $sIID_IAppWindowStatics) Local $pAppWindow = IAppWindowStatics_GetFromWindowId($pAppWinStatics, $iAppWindowId) IUnknown_Release($pAppWinStatics) Return $pAppWindow EndFunc ;==>GetAppWindowFromId Func GridAddColumn($pGrid, $fWidth = 1, $vUnit = "Star") _WinRT_SwitchInterface($pGrid, $sIID_IGrid) If @error Then Return SetError(@error, @extended, False) Local $tGridLen = DllStructCreate("align 4;double Value;ulong GridUnitType") $tGridLen.Value = $fWidth $tGridLen.GridUnitType = IsString($vUnit) ? $mGridUnitType[$vUnit] : $vUnit Local $pColDef, $pColDefs = IGrid_GetColumnDefinitions($pGrid) $pColDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.ColumnDefinition") _WinRT_SwitchInterface($pColDef, $sIID_IColumnDefinition) IRowDefinition_SetHeight($pColDef, $tGridLen) Local $iError = @error If Not $iError Then IVector_Append($pColDefs, $pColDef) IUnknown_Release($pColDefs) Return SetError($iError, 0, $pColDef) EndFunc ;==>GridAddColumn Func GridAddRow($pGrid, $fHeight = 1, $vUnit = "Star") _WinRT_SwitchInterface($pGrid, $sIID_IGrid) If @error Then Return SetError(@error, @extended, False) Local $tGridLen = DllStructCreate("align 4;double Value;ulong GridUnitType") $tGridLen.Value = $fHeight $tGridLen.GridUnitType = IsString($vUnit) ? $mGridUnitType[$vUnit] : $vUnit Local $pRowDef, $pRowDefs = IGrid_GetRowDefinitions($pGrid) $pRowDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.RowDefinition") _WinRT_SwitchInterface($pRowDef, $sIID_IRowDefinition) IRowDefinition_SetHeight($pRowDef, $tGridLen) Local $iError = @error If Not $iError Then IVector_Append($pRowDefs, $pRowDef) IUnknown_Release($pRowDefs) Return SetError($iError, 0, $pRowDef) EndFunc ;==>GridAddRow Func HideControls($bHide) Local $tGridLen = DllStructCreate("align 4;double Value;ulong GridUnitType") $tGridLen.GridUnitType = $mGridUnitType["Pixel"] $tGridLen.Value = $bHide ? 0 : 60 _WinRT_SwitchInterface($pColCtrlRowDef, $sIID_IRowDefinition) IRowDefinition_SetHeight($pColCtrlRowDef, $tGridLen) $bAreCtrlsHidden = $bHide EndFunc ;==>HideControls Func MediaSrcStateChanged($pThis, $pMediaSrc, $pArgs) #forceref $pThis, $pMediaSrc, $pArgs Local $sState = _WinRT_GetEnum($mMediaSourceState, IMediaSourceStateChangedEventArgs_GetNewState($pArgs)) ConsoleWrite("Source State: " & $sState & @CRLF) Switch $sState Case "Opened" _WinRT_SwitchInterface($pMediaSrc, $sIID_IMediaSource2) Local $pTimeSpan = IMediaSource2_GetDuration($pMediaSrc) $iMediaDuration = _WinRT_GetReference($pTimeSpan, "Int64*") IUnknown_Release($pTimeSpan) $iMediaDuration = Round($iMediaDuration / 10000000) ;Convert to sec ConsoleWrite(StringFormat("Media Duration: %dh %02dm %02ds\r\n", Floor($iMediaDuration / 3600), Mod($iMediaDuration, 3600) / 60, Mod($iMediaDuration, 60))) EndSwitch EndFunc ;==>MediaSrcStateChanged Func MouseMoved($pThis, $pSender, $pArgs) If $bAreCtrlsHidden Then HideControls(False) Local $pMediaPlayerElementCurs = $pMediaPlayerElement _WinRT_SwitchInterface($pMediaPlayerElementCurs, $sIID_IUIElementProtected) Local $pInputCursor = IUIElementProtected_GetProtectedCursor($pMediaPlayerElementCurs) IUIElementProtected_SetProtectedCursor($pMediaPlayerElementCurs, 0) If $pInputCursor Then _WinRT_SwitchInterface($pInputCursor, $sIID_IClosable) IClosable_Close($pInputCursor) IUnknown_Release($pInputCursor) EndIf EndIf #forceref $pThis, $pSender, $pArgs IDispatcherTimer_Stop($pTimer) IDispatcherTimer_Start($pTimer) EndFunc ;==>MouseMoved Func OpenMedia($pThis, $pSender, $pArgs) #forceref $pThis, $pSender, $pArgs Local Static $pMediaSrcStateChDgt = CreateDelegate("MediaSrcStateChanged", "Windows.Foundation.TypedEventHandler`2<Windows.Media.Core.MediaSource, Windows.Media.Core.MediaSourceStateChangedEventArgs>") Local $pPickerFact = _WinRT_GetActivationFactory("Microsoft.Windows.Storage.Pickers.FileOpenPicker", $sIID_IFileOpenPickerFactory) Local $pPicker = IFileOpenPickerFactory_CreateInstance($pPickerFact, $iAppWindowId) IUnknown_Release($pPickerFact) _WinRT_SwitchInterface($pPicker, $sIID_IFileOpenPicker2) IFileOpenPicker2_SetSuggestedStartFolder($pPicker, @WorkingDir) _WinRT_SwitchInterface($pPicker, $sIID_IFileOpenPicker) Local $pFilter = IFileOpenPicker_GetFileTypeFilter($pPicker) Local $ahSupTypes[] = [ _ _WinRT_CreateHString(".mp4"), _ _WinRT_CreateHString(".mov"), _ _WinRT_CreateHString(".mkv"), _ _WinRT_CreateHString(".mpg"), _ _WinRT_CreateHString(".mmv")] For $i = 0 To UBound($ahSupTypes) - 1 IVector_Append($pFilter, $ahSupTypes[$i]) _WinRT_DeleteHString($ahSupTypes[$i]) Next Local $pAsync = IFileOpenPicker_PickSingleFileAsync($pPicker) _WinRT_SwitchInterface($pAsync, _WinRT_GetParameterizedTypeInstanceIID("Windows.Foundation.IAsyncOperation`1<Microsoft.Windows.Storage.Pickers.PickFileResult>")) Local $pPickedFile = _WinRT_WaitForAsync2($pAsync, "ptr*", -1) Local $sFilePath = IPickFileResult_GetPath($pPickedFile) IUnknown_Release($pPickedFile) If FileExists($sFilePath) Then Local $pFileFact = _WinRT_GetActivationFactory("Windows.Storage.StorageFile", $sIID_IStorageFileStatics) $pAsync = IStorageFileStatics_GetFileFromPathAsync($pFileFact, $sFilePath) Local $pFile = _WinRT_WaitForAsync($pAsync, "ptr*", 3000) IUnknown_Release($pFileFact) _WinRT_SwitchInterface($pFile, $sIID_IStorageFile) ;Create MediaSource from file object. Local $pMediaSrcFact = _WinRT_GetActivationFactory("Windows.Media.Core.MediaSource", $sIID_IMediaSourceStatics) Local $pMediaSrc = IMediaSourceStatics_CreateFromStorageFile($pMediaSrcFact, $pFile) IUnknown_Release($pMediaSrcFact) _WinRT_SwitchInterface($pMediaSrc, $sIID_IMediaSource3) IMediaSource3_AddHdlrStateChanged($pMediaSrc, $pMediaSrcStateChDgt) _WinRT_SwitchInterface($pPlayer, $sIID_IMediaPlayerSource) IMediaPlayerSource_SetMediaSource($pPlayer, $pMediaSrc) IUnknown_Release($pMediaSrc) IUnknown_Release($pFile) EndIf IUnknown_Release($pFilter) IUnknown_Release($pPicker) EndFunc ;==>OpenMedia Func PanelAddChild($pPanel, $pChild) _WinRT_SwitchInterface($pPanel, $sIID_IPanel) _WinRT_SwitchInterface($pChild, $sIID_IUIElement) Local $pChildren = IPanel_GetChildren($pPanel) IVector_Append($pChildren, $pChild) IUnknown_Release($pChildren) EndFunc ;==>PanelAddChild Func Play($pThis, $pSender, $pArgs) #forceref $pThis, $pSender, $pArgs _WinRT_SwitchInterface($pPlayer, $sIID_IMediaPlayer) Switch $sPlayerState Case "Playing" IMediaPlayer_Pause($pPlayer) Case Else IMediaPlayer_Play($pPlayer) EndSwitch EndFunc ;==>Play Func PlayerStateChange($pThis, $pPlayer, $pArgs) #forceref $pThis, $pPlayer, $pArgs $sPlayerState = _WinRT_GetEnum($mMediaPlayerState, IMediaPlayer_GetCurrentState($pPlayer)) ConsoleWrite("Player State: " & $sPlayerState & @CRLF) ;~ Local $pPlayButton = GetElementByName("PlayBtn") Switch $sPlayerState Case "Playing" ButtonSetGlyph($pPlayButton, "Pause") Case Else ButtonSetGlyph($pPlayButton, "Play") EndSwitch EndFunc ;==>PlayerStateChange Func TimerExp($pThis, $pSender, $pArgs) #forceref $pThis, $pSender, $pArgs If IMediaPlayerElement_GetIsFullWindow($pMediaPlayerElement) Then If Not $bAreCtrlsHidden Then HideControls(True) Local $pCursorFact = _WinRT_GetActivationFactory("Microsoft.UI.Input.InputCursor", $sIID_IInputCursorStaticsInterop) Local $hCursor = CreateHiddenCursor() Local $pInputCursor = IInputCursorStaticsInterop_CreateFromHCursor($pCursorFact, $hCursor) IUnknown_Release($pCursorFact) Local $pMediaPlayerElementCurs = $pMediaPlayerElement _WinRT_SwitchInterface($pMediaPlayerElementCurs, $sIID_IUIElementProtected) IUIElementProtected_SetProtectedCursor($pMediaPlayerElementCurs, $pInputCursor) IUnknown_Release($pInputCursor) EndIf EndIf IDispatcherTimer_Stop($pTimer) EndFunc ;==>TimerExp Func UIElementAssignAccel($pObj, $sVirtualKey, $iModifiers = $mVirtualKeyModifiers["None"]) Local $pAccel = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Input.KeyboardAccelerator") _WinRT_SwitchInterface($pAccel, $sIID_IKeyboardAccelerator) IKeyboardAccelerator_SetKey($pAccel, $mVirtualKey[$sVirtualKey]) IKeyboardAccelerator_SetModifiers($pAccel, $iModifiers) IKeyboardAccelerator_SetIsEnabled($pAccel, True) _WinRT_SwitchInterface($pObj, $sIID_IUIElement) Local $pAccels = IUIElement_GetKeyboardAccelerators($pObj) IVector_Append($pAccels, $pAccel) IUnknown_Release($pAccels) IUnknown_Release($pAccel) EndFunc ;==>UIElementAssignAccel Func UIElementAssignGridPos($pObj, $iRow, $iCol = -1, $iRowSpan = -1, $iColSpan = -1) Local $pProp_Fact = _WinRT_GetActivationFactory("Windows.Foundation.PropertyValue", $sIID_IPropertyValueStatics) Local $pGrid_Statics = _WinRT_GetActivationFactory("Microsoft.UI.Xaml.Controls.Grid", $sIID_IGridStatics) Local $pValue _WinRT_SwitchInterface($pObj, $sIID_IDependencyObject) If @error Then Return SetError(@error, @extended, False) If $iRow > -1 Then Local $pRowProp = IGridStatics_GetRowProperty($pGrid_Statics) $pValue = IPropertyValueStatics_CreateInt32($pProp_Fact, $iRow) IDependencyObject_SetValue($pObj, $pRowProp, $pValue) IUnknown_Release($pValue) IUnknown_Release($pRowProp) EndIf If $iCol > -1 Then Local $pColProp = IGridStatics_GetColumnProperty($pGrid_Statics) $pValue = IPropertyValueStatics_CreateInt32($pProp_Fact, $iCol) IDependencyObject_SetValue($pObj, $pColProp, $pValue) IUnknown_Release($pValue) IUnknown_Release($pColProp) EndIf If $iRowSpan > -1 Then Local $pRowSpanProp = IGridStatics_GetColumnSpanProperty($pGrid_Statics) $pValue = IPropertyValueStatics_CreateInt32($pProp_Fact, $iRowSpan) IDependencyObject_SetValue($pObj, $pRowSpanProp, $pValue) IUnknown_Release($pValue) IUnknown_Release($pRowSpanProp) EndIf If $iColSpan > -1 Then Local $pColSpanProp = IGridStatics_GetColumnSpanProperty($pGrid_Statics) $pValue = IPropertyValueStatics_CreateInt32($pProp_Fact, $iColSpan) IDependencyObject_SetValue($pObj, $pColSpanProp, $pValue) IUnknown_Release($pValue) IUnknown_Release($pColSpanProp) EndIf IUnknown_Release($pGrid_Statics) IUnknown_Release($pProp_Fact) Return True EndFunc ;==>UIElementAssignGridPos Func IInputCursorStaticsInterop_CreateFromHCursor($pThis, $hCursor) Local $vFailVal = False Local $pFunc = __WinRT_GetFuncAddress($pThis, 7) If @error Then Return SetError(@error, @extended, $vFailVal) If $hCursor And (Not IsPtr($hCursor)) Then Return SetError($ERROR_INVALID_PARAMETER, 0, $vFailVal) Local $aCall = DllCallAddress("long", $pFunc, "ptr", $pThis, "handle", $hCursor, "ptr*", 0) If @error Then Return SetError(__WinRT_GetDllError(), 0, $vFailVal) Return SetError($aCall[0], 0, $aCall[3]) EndFunc ;==>IInputCursorStaticsInterop_CreateFromHCursor Edit: minor fix
-
argumentum reacted to a post in a topic:
WinRT Object Libraries
-
Danyfirex reacted to a post in a topic:
WinRT Object Libraries
-
WildByDesign reacted to a post in a topic:
WinRT Object Libraries
-
I've just added one more zip - v1.7.1 same as above, just targeting WinAppSDK v2.0 instead of v1.8. Remember update your runtime! We want a x64 variant of a v2.0.x release for this on the stable channel. (so ATM that's this one!) Direct Links to the 2 packages... WinRT v1.7.1 (WinAppSDK v2.0 based) WinRT V1,7 (WinAppSDK v1.8 based)
-
WildByDesign reacted to a post in a topic:
WinRT - WinUI3
-
Access to the compositor still has value, so the exercise was worth while. It looks like you can do all sorts of fancy animations in there and such. At some point I'll dig into that a bit more, time permitting..
-
MattyD reacted to a post in a topic:
WinRT - WinUI3
-
argumentum reacted to a post in a topic:
WinRT Object Libraries
-
MattyD reacted to a post in a topic:
SNMP UDF rewrite
-
WildByDesign reacted to a post in a topic:
WinRT Object Libraries
-
Hello all, I've just added v1.7 to sourceforge. This is mainly because WinAppSDK v2.0 is now hit the "stable" channel, and I wanted to do a final build based on v1.8 of the SDK. So the next release from me will be based on v2.x. Main changes since last time are: Fixed issue around Windows.Graphics.SizeInt32 - its same issue we solved for Windows.UI.Color in the last release. For better compatibility, I've dropped the minimum runtime version down to v1.8.0 for _WinUI3_Startup() - This is a default setting that can be changed by passing parameters to the startup function. Added a WinRT_UWPIslands.au3 library to support KB input into UWP Xaml Islands (see UWP_TextBox.au3 example for usage) We can now deal with interface overrides as detailed here. Which means: we can also hook the "Application.OnLaunched()" event with the new _WinUI3_StartApp() func. This fixes a bunch of problems we were having with WinUI3. See the WinUI3_WindowBackdrops.au3 example for usage.
-
Hi all, Just updated the attachment - its a small internal change that helps settle things down if you're opening/closing multiple devices. Also we also now have funcs to set the internal parameters. _SNMP_SetMaxPacketLen(4096) ; Maximum SNMP packet size / msg buffer size. _SNMP_SetSNMPVersion(2) ; 1 or 2 is supported. (but you'll probably want 2) _SNMP_SetAdlibInterval(125) ; Listen/response polling interval. _SNMP_RetPrintSafeStr(True) ; Non-printing characters are replaced with "." if the OID datatype is a string. (whitespace chars are retained) _SNMP_RetTicksAsStr(False) ; TimeTicks are returned as a human readable string if true. Otherwise an integer is returned (100ths of a second). And here's a demo script that scans a subnet for printers, and reports on supplies to boot! #include "..\SNMPv2.au3" #include <GuiConstants.au3> ;-------------------------------------------------- ;Network to scan.. Global $sNetAddress = "10.0.0.0" Global $sNetMask = "255.255.255.0" Global $iTimeout = 250 ; Time to wait for SNMP response + processing time (ms)... Global $iBatchSize = 50 ; Max number of OIDs to return in one hit. Global $sCommunity = "public" ; If you start losing packets with high batch sizes, try increasing $__g_iMaxPktLen. ;More UDF Params... ;-------------------------------------------------- _SNMP_SetMaxPacketLen(4096) ; Maximum SNMP packet size / msg buffer size. _SNMP_SetSNMPVersion(2) ; must be 2 for GetBulk to work.. _SNMP_SetAdlibInterval(125) ; Listen/response polling interval. (don't go too low, it can lockup your script!) _SNMP_RetPrintSafeStr(True) ; Non-printing characters are replaced with "." if the OID datatype is a string. (whitespace chars are retained) _SNMP_RetTicksAsStr(True) ; Return human readable times. ;-------------------------------------------------- Global Const $sOID_sysLocation = "1.3.6.1.2.1.1.6" Global Const $sOID_hrDeviceTable = "1.3.6.1.2.1.25.3.2" Global Const $sOID_hrDeviceTableEntry = "1.3.6.1.2.1.25.3.2.1" Global Const $sOID_hrDeviceIndex = "1.3.6.1.2.1.25.3.2.1.1" Global Const $sOID_hrDeviceType = "1.3.6.1.2.1.25.3.2.1.2" Global Const $sOID_hrDeviceDescr = "1.3.6.1.2.1.25.3.2.1.3" Global Const $sOID_hrDeviceID = "1.3.6.1.2.1.25.3.2.1.4" Global Const $sOID_hrDeviceStatus = "1.3.6.1.2.1.25.3.2.1.5" Global Const $sOID_hrDeviceErrors = "1.3.6.1.2.1.25.3.2.1.6" Global Const $sOID_hrDevicePrinter = "1.3.6.1.2.1.25.3.1.5" Global Const $sOID_prtMarkerSuppliesTable = "1.3.6.1.2.1.43.11.1" Global Const $sOID_prtMarkerSuppliesEntry = "1.3.6.1.2.1.43.11.1.1" Global Const $sOID_prtMarkerSuppliesIndex = "1.3.6.1.2.1.43.11.1.1.1" Global Const $sOID_prtMarkerSuppliesMarkerIndex = "1.3.6.1.2.1.43.11.1.1.2" Global Const $sOID_prtMarkerSuppliesColorantIndex = "1.3.6.1.2.1.43.11.1.1.3" Global Const $sOID_prtMarkerSuppliesClass = "1.3.6.1.2.1.43.11.1.1.4" Global Const $sOID_prtMarkerSuppliesType = "1.3.6.1.2.1.43.11.1.1.5" Global Const $sOID_prtMarkerSuppliesDescription = "1.3.6.1.2.1.43.11.1.1.6" Global Const $sOID_prtMarkerSuppliesSupplyUnit = "1.3.6.1.2.1.43.11.1.1.7" Global Const $sOID_prtMarkerSuppliesMaxCapacity = "1.3.6.1.2.1.43.11.1.1.8" Global Const $sOID_prtMarkerSuppliesLevel = "1.3.6.1.2.1.43.11.1.1.9" Global $aSuppliesTable, $aDevTable, $sSysLoc, $sOID_Root Global $hProgressGUI, $idProgress, $idLabel, $idScanCancel, $idTV _Example() Func _Example() $hProgressGUI = GUICreate("Idle.", 300, 350, -1, -1, BitOR($WS_POPUP, $WS_CAPTION, $WS_SYSMENU), $WS_EX_COMPOSITED) $idProgress = GUICtrlCreateProgress(10, 10, 280, 40) $idScanCancel = GUICtrlCreateButton("Scan", 216, 58, 74, 23) $idLabel = GUICtrlCreateLabel("", 10, 60, 100, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE, $WS_BORDER)) $idTV = GUICtrlCreateTreeView(10, 100, 280, 240) GUISetState() Local $asIPAddresses = GetRange($sNetAddress, $sNetMask) GUICtrlSetLimit($idProgress, UBound($asIPAddresses), 0) GUICtrlSendMsg($idProgress, $PBM_SETRANGE, 0, BitOR(BitShift(UBound($asIPAddresses), -16), 0)) ControlClick($hProgressGUI, "", $idScanCancel) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idScanCancel GUICtrlSendMsg($idTV, $TVM_DELETEITEM, 0, $TVI_ROOT) GUICtrlSetData($idProgress, 0) GUICtrlSetData($idScanCancel, "Cancel") WinSetTitle($hProgressGUI, "", "Scanning...") If _Scan($asIPAddresses) Then ExitLoop EndSwitch WEnd GUIDelete($hProgressGUI) EndFunc Func _Scan($asIPAddresses) _SNMP_Startup() _SNMP_RegMsgHandler("_MsgHandler") Local $bExit = False For $i = 0 To UBound($asIPAddresses) - 1 _CheckPrinter($asIPAddresses[$i]) GUICtrlSetData($idProgress, $i+1) GUICtrlSetData($idLabel, $asIPAddresses[$i]) If $i = UBound($asIPAddresses) - 1 Then ControlClick($hProgressGUI, "", $idScanCancel) EndIf While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE $bExit = True ExitLoop 2 Case $idScanCancel GUICtrlSetData($idProgress, 0) GUICtrlSetData($idScanCancel, "Scan") WinSetTitle($hProgressGUI, "", "Idle.") ExitLoop 2 Case 0 If $i < UBound($asIPAddresses) - 1 Then ExitLoop EndSwitch WEnd Next _SNMP_Shutdown() Return $bExit EndFunc Func _Wait() Local $hTimer = TimerInit() Do Sleep(50) Until TimerDiff($hTimer) > $iTimeout EndFunc Func _CheckPrinter($sIPAddress) Local $iDevice = _SNMP_OpenDevice($sIPAddress) If @error Then Return ;Reset the tables. $aDevTable = 0 $aSuppliesTable = 0 ;$sOID_Root - Only read in SNMP data related to hrDeviceTable. $sOID_Root = $sOID_hrDeviceTable _SNMP_GetBulk($iDevice, $sOID_hrDeviceTable, $sCommunity, 1, $iBatchSize) _Wait() ;Give enough time for data to come back and be processed. Governed by $iTimeout. If Not UBound($aDevTable) Then Return _SNMP_CloseDevice($iDevice) ;Can't find device.. $sOID_Root = $sOID_sysLocation _SNMP_GetRequest($iDevice, $sOID_sysLocation & ".0", $sCommunity) _Wait() $sOID_Root = $sOID_prtMarkerSuppliesTable _SNMP_GetBulk($iDevice, $sOID_prtMarkerSuppliesTable, $sCommunity, 1, $iBatchSize) _Wait() Local $hTVNode = $idTV, $hTVNode2, $fLevel For $i = 0 To UBound($aDevTable) - 1 ;Check if hrDeviceIndex is a printer If $aDevTable[$i][1] <> $sOID_hrDevicePrinter Then ContinueLoop $hTVNode = GUICtrlCreateTreeViewItem($sIPAddress, $idTV) GUICtrlCreateTreeViewItem($aDevTable[$i][2], $hTVNode) GUICtrlCreateTreeViewItem($sSysLoc, $hTVNode) GUICtrlSetState($hTVNode, $GUI_EXPAND) ConsoleWrite("IP: " & $sIPAddress & @CRLF) ConsoleWrite("Device: " & $aDevTable[$i][2] & @CRLF) If $sSysLoc Then ConsoleWrite("Location: " & $sSysLoc & @CRLF) For $j = 0 To UBound($aSuppliesTable) - 1 If $aSuppliesTable[$j][0] <> $aDevTable[$i][0] Then ContinueLoop ConsoleWrite(" Consumable: " & $aSuppliesTable[$j][6] & @CRLF) $hTVNode2 = GUICtrlCreateTreeViewItem($aSuppliesTable[$j][6], $hTVNode) If IsString($aSuppliesTable[$j][9]) Then ConsoleWrite(" Level: " & $aSuppliesTable[$j][9] & @CRLF) GUICtrlCreateTreeViewItem($aSuppliesTable[$j][9], $hTVNode2) Else $fLevel = $aSuppliesTable[$j][9] / $aSuppliesTable[$j][8] ConsoleWrite(StringFormat(" Level: %d/%d (%d%%)\r\n", _ $aSuppliesTable[$j][9], $aSuppliesTable[$j][8], _ Int(100 * $fLevel))) GUICtrlCreateTreeViewItem(StringFormat("%d/%d (%d%%)", $aSuppliesTable[$j][9], $aSuppliesTable[$j][8], _ Int(100 * $fLevel)), $hTVNode2) If Not $aSuppliesTable[$j][9] Then GUICtrlSetColor(-1, 0xFF0000) EndIf GUICtrlSetState($hTVNode2, $GUI_EXPAND) Next ConsoleWrite(@CRLF) Next _SNMP_CloseDevice($iDevice) EndFunc Func _MsgHandler($iDevice, $dRawPacket, $avHeaders, $avData) Local $iBatchNum = $avHeaders[2][1] For $i = 0 To UBound($avData) - 1 ;Stop if we're at the end of the table If StringLeft($avData[$i][0], StringLen($sOID_Root)) <> $sOID_Root Then ExitLoop Switch $sOID_Root Case $sOID_hrDeviceTable _DevTableBuilder($avData[$i][0], $avData[$i][2], $i) Case $sOID_prtMarkerSuppliesTable _ConsumablesTableBuilder($avData[$i][0], $avData[$i][2], $i) Case $sOID_sysLocation $sSysLoc = $avData[$i][2] EndSwitch ;~ ConsoleWrite(StringFormat(" %10s | %50s %-15s %-20s", $avHeaders[3][1], $avData[$i][0], $avData[$i][1], $avData[$i][2]) & @CRLF) Next Local $bWalk = ($i = UBound($avData)) If $avData[UBound($avData) -1][1] = $SNMP_EXC_ENDOFMIB Then $bWalk = False ;Not at the end of the table, ask for more data. $iBatchNum += 1 If $bWalk Then _SNMP_GetBulk($iDevice, Default, Default, $iBatchNum, $iBatchSize) ;Get the next batch EndFunc Func _DevTableBuilder($sOID, $vData, $iRecord) ;Extract the hrDeviceIndex from the OID. ;I'm cheating - We're OK for this table, but this method won't work correctly for other tables with > 9 columns. ;We should stringsplit with "." and check the correct index. Local $sKey = StringTrimLeft($sOID, StringLen($sOID_hrDeviceIndex) + 1) Local $mEmptyMap[] Local Static $mDevIdx[] If Not $iRecord Then Local $mEmptyMap[] $mDevIdx = $mEmptyMap EndIf If Not UBound($aDevTable, 0) Then Dim $aDevTable[0][6] If Not MapExists($mDevIdx, $sKey) Then ;Index for this table is hrDeviceIndex - an integer. ;hrDeviceIndex will also will be at $sOID_hrDeviceIndex.hrDeviceIndex ; but we technically need a hrDeviceIndex to GetRequest directly! ; you could probably cycle through from 1 until there's no response though.. ; If the system has > 1 device indicies, usually the printer device will be 1. $mDevIdx[$sKey] = UBound($aDevTable) ReDim $aDevTable[UBound($aDevTable) + 1][6] EndIf Local $iDevIdx = $mDevIdx[$sKey] Switch StringLeft($sOID, StringLen($sOID_hrDeviceIndex)) Case $sOID_hrDeviceIndex $aDevTable[$iDevIdx][0] = $vData Case $sOID_hrDeviceType $aDevTable[$iDevIdx][1] = $vData Case $sOID_hrDeviceDescr $aDevTable[$iDevIdx][2] = $vData Case $sOID_hrDeviceID ;ProductID $aDevTable[$iDevIdx][3] = $vData Case $sOID_hrDeviceStatus $aDevTable[$iDevIdx][4] = $vData ;1 = unknown ;2 = running ;3 = warning ;4 = testing ;5 = down Case $sOID_hrDeviceErrors ;Error Counter $aDevTable[$iDevIdx][5] = $vData EndSwitch EndFunc Func _ConsumablesTableBuilder($sOID, $vData, $iRecord) ;Again, cheating with StringTrimLeft. Local $sKey = StringTrimLeft($sOID, StringLen($sOID_prtMarkerSuppliesIndex) + 1) Local Static $mSuppIdx[] If Not $iRecord Then Local $mEmptyMap[] $mSuppIdx = $mEmptyMap EndIf If Not UBound($aSuppliesTable, 0) Then Dim $aSuppliesTable[0][10] If Not MapExists($mSuppIdx, $sKey) Then ;Index for this table is hrDeviceIndex.prtMarkerSuppliesIndex $mSuppIdx[$sKey] = UBound($aSuppliesTable) ReDim $aSuppliesTable[UBound($aSuppliesTable) + 1][10] ;Store the hrDeviceIndex, so we can filter consubables per device later. ;StringTrimRight - This'll break if there are >9 consumables for the device. $aSuppliesTable[$mSuppIdx[$sKey]][0] = StringTrimRight($sKey, 2) EndIf Local $iSuppIdx = $mSuppIdx[$sKey] Switch StringLeft($sOID, StringLen($sOID_prtMarkerSuppliesIndex)) Case $sOID_prtMarkerSuppliesIndex $aSuppliesTable[$iSuppIdx][1] = $vData Case $sOID_prtMarkerSuppliesMarkerIndex $aSuppliesTable[$iSuppIdx][2] = $vData Case $sOID_prtMarkerSuppliesColorantIndex $aSuppliesTable[$iSuppIdx][3] = $vData Case $sOID_prtMarkerSuppliesClass $aSuppliesTable[$iSuppIdx][4] = $vData Case $sOID_prtMarkerSuppliesType $aSuppliesTable[$iSuppIdx][5] = $vData ; other = 1 ; unknown = 2 ; toner = 3 ; wasteToner = 4 ; ink = 5 ; inkCartridge = 6 ; inkRibbon = 7 ; wasteInk = 8 ; opc = 9 ; developer = 10 ; fuserOil = 11 ; solidWax = 12 ; ribbonWax = 13 ; wasteWax = 14 Case $sOID_prtMarkerSuppliesDescription $aSuppliesTable[$iSuppIdx][6] = $vData Case $sOID_prtMarkerSuppliesSupplyUnit $aSuppliesTable[$iSuppIdx][7] = $vData Case $sOID_prtMarkerSuppliesMaxCapacity Switch $vData Case -1 $aSuppliesTable[$iSuppIdx][8] = "Unlimited" Case -2 $aSuppliesTable[$iSuppIdx][8] = "Unknown" Case Else $aSuppliesTable[$iSuppIdx][8] = $vData EndSwitch Case $sOID_prtMarkerSuppliesLevel Switch $vData Case -1 $aSuppliesTable[$iSuppIdx][9] = "Unlimited" Case -2 $aSuppliesTable[$iSuppIdx][9] = "Unknown" Case -3 $aSuppliesTable[$iSuppIdx][9] = "Unknown (but not exhausted)" Case Else $aSuppliesTable[$iSuppIdx][9] = $vData EndSwitch EndSwitch EndFunc Func GetRange($sIP, $sNetMask) ;Generate array of IP addresses. Local $aIPRange[2][4], $iIP, $iMask $aIP = StringSplit($sIP, ".", 2) $aMask = StringSplit($sNetMask, ".", 2) For $i = 0 To 3 $iIP = BitShift($iIP, -8) $iMask = BitShift($iMask, -8) $iIP += Int($aIP[$i]) $iMask += Int($aMask[$i]) Next Local $iNet = BitAND($iIP, $iMask) Local $iFirst = $iNet + 1 Local $iBCast = BitOr($iNet, BitNot($iMask)) Local $iLast = $iBCast - 1 Local $asIPAddresses[($iLast - $iFirst) + 1] Local $sIP2, $iIP For $i = $iFirst To $iLast $iIP = $i $sIP2 = "" For $j = 1 To 4 $sIP2 = BitAND($iIP, 0xFF) & "." & $sIP2 $iIP = BitShift($iIP, 8) Next $asIPAddresses[$i - $iFirst] = StringTrimRight($sIP2, 1) Next Return $asIPAddresses EndFunc
-
Alright, I managed to get the layered window working in the end, but we run into the same trouble. The button background is part of the button - so we still get a square surrounding it. We can make the button background transparent and _SetNCBackdropType() will fill in the gaps with a material... but your mouse will simply click through that bit of the window. Comping together the 2 UI frameworks is confirmed a no-go. There's event a name for it: We can restrict where the button can paint by setting a region though. This looks great, but it won't help with things like labels - good luck with cutting holes around text! Func _CreateCloseButton($hWnd, $iX, $iY, $iWidth, $iHeight, $iStyle = -1, $iExStyle = -1) If $iStyle = -1 Then $iStyle = BitOR($WS_VISIBLE, $WS_CHILD) If $iExStyle = -1 Then $iExStyle = 0 $hButton = _WinAPI_CreateWindowEx($iExStyle, $WC_BUTTON, "Close", $iStyle, $iX, $iY, $iWidth, $iHeight, $hWnd, $IDCANCEL, _WinAPI_GetModuleHandle(0), 0) _SendMessage($hButton, $WM_SETFONT, _WinAPI_GetStockObject($DEFAULT_GUI_FONT), True) Local $hRgn = _WinAPI_CreateRoundRectRgn(1, 1, $iWidth, $iHeight, 4, 4) _WinAPI_SetWindowRgn($hButton, $hRgn, False) Return $hButton EndFunc
-
For sure, even if it does not end up being a solution to this specific issue, I would definitely like to see this layered windows method with the buttons. Gonna have to backtrack on that sorry! - I was doing something dumb🤦♂️ My current theory is that the WinRT compositor just paints last - after a widow's traditional paint cycle. If this is always True, neither WS_EX_COMPOSITED or WS_EX_LAYERED will be able to save us. The compositor will ultimately just paint its visual tree over the top. But I could be totally wrong about this too. Clipping children works because the parent is not allowed to paint into a child's region at all.. So we can't paint over a button - but we also can't paint a mica background behind it. It looks like you can do some very cool things with the compositor. But perhaps its not best suited to being a backdrop for win32 controls! How would you strip it before the window is created? Or would that mean avoiding the use of GUICreate and using CreateWindowEx API instead? It just boggles my mind on how to catch it early enough. Its just a sequence thing, not a race . AutoIt registers a window Class on startup named "AutoIt v3 GUI", and we get a window of this class by calling GUICreate(). We can happily query, modify, and re-register that class - but only while there's no AutoIt GUIs around. I haven't tested anything, but If you're just doing stock windows things I'd imagine it should be pretty safe. If its going to break it'll likely be around autoit-specific funcs that customize the look - so things like GuiSetBkColor etc.
-
Yeah you're right, the AutoIt GUI class does have CS_OWNDC. I'm still sussing things out - WS_EX_COMPOSITED was in the Microsoft example that I was trying to emulate, but it seems to work ok without it... Not sure if we need this to blend our Win32 buttons properly if clipping isn't the answer. If it turns out that WS_EX_COMPOSITED is required, we can strip the CS_OWNDC style from our GUI class before creating windows. Local $sAu3GUIClass = "AutoIt v3 GUI" Local $tInfo = _WinAPI_GetClassInfoEx($sAu3GUIClass, _WinAPI_GetModuleHandle(0)) $tInfo.Size = DllStructGetSize($tInfo) $tInfo.Style = 0x0B Local $tClassName = DllStructCreate("wchar name[257]") $tClassName.name = $sAu3GUIClass $tInfo.ClassName = DllStructGetPtr($tClassName) _WinAPI_UnregisterClass($sAu3GUIClass, _WinAPI_GetModuleHandle(0)) _WinAPI_RegisterClassEx($tInfo) RE clipping. - everything is clipped as a square, so our buttons with rounded corners are a bit ugly. If we can't get the 2 worlds working together nicely I've had some success using layered windows to get the buttons floating nicely on top. I doubt its the most efficient way of approaching things - but hey. I'll post an example of that in a little bit. I can't find much in the way of doco/examples around any of this, so its all very much "suck it and see" ATM
-
No problems. I found we also need $WS_CLIPCHILDREN in order to see controls too. Still need to confirm what the most "correct" way is to remove a backdrop. I'm just closing the backdrop controller atm, but not sure if we should be de-targeting a window's visual container first... Anyway - there's no crashy crashy when we tear down windows, so we can't be doing anything too bad! Edit: Added title bar effect. #include <GUIConstants.au3> #include <WindowsConstants.au3> #include "..\Include\WinRT.au3" #include "..\Include\WinRT_WinUI3.au3" #include "..\Include\Classes\Microsoft.UI.Composition.SystemBackdrops.MicaController.au3" #include "..\Include\Classes\Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicController.au3" #include "..\Include\Classes\Windows.UI.Composition.Desktop.DesktopWindowTarget.au3" #include "..\Include\Classes\Windows.System.DispatcherQueueController.au3" #include "..\Include\Classes\Windows.UI.Composition.Compositor.au3" #include "..\Include\Classes\Windows.UI.Composition.Visual.au3" Global Const $sIID_ICompositorDesktopInterop = "{29E691FA-4567-4DCA-B319-D0F207EB6807}" $__g_mIIDs[$sIID_ICompositorDesktopInterop] = "ICompositorDesktopInterop" Global Const $tagDispatcherQueueOptions = "struct;dword dwSize;dword threadType;dword apartmentType;endstruct" Global Const $DQTYPE_THREAD_DEDICATED = 1 Global Const $DQTYPE_THREAD_CURRENT = 2 Global Const $DQTAT_COM_NONE = 0 Global Const $DQTAT_COM_ASTA = 1 Global Const $DQTAT_COM_STA = 2 Global Const $DWMSBT_AUTO = 0 Global Const $DWMSBT_NONE = 1 Global Const $DWMSBT_MAINWINDOW = 2 Global Const $DWMSBT_TRANSIENTWINDOW = 3 Global Const $DWMSBT_TABBEDWINDOW = 4 Global $pDispatcher, $pCompositor Global $aObjects[0][4] _Init() _Main() _Cleanup() Func _Init() _WinRT_Startup() _WinUI3_Startup() $pDispatcher = _WinRT_CreateDispatcherQueueController() $pCompositor = _WinRT_ActivateInstance("Windows.UI.Composition.Compositor") EndFunc Func _Main() Local $iWindowCount = 1 Local $hGUI = GUICreate("System Backdrops", 240, 100, -1, -1, BitOR($WS_OVERLAPPED, $WS_CAPTION, $WS_SYSMENU)) Local $idCreateMica = GUICtrlCreateButton("Mica", 20, 20, 60, 60) Local $idCreateMicaAlt = GUICtrlCreateButton("Mica Alt", 90, 20, 60, 60) Local $idCreateAcrylic = GUICtrlCreateButton("Acrylic", 160, 20, 60, 60) GUISetState() Local $aMsg While 1 $aMsg = GUIGetMsg($GUI_EVENT_ARRAY) Switch $aMsg[0] Case $GUI_EVENT_CLOSE DeleteWin($aMsg[1]) $iWindowCount -= 1 Case $idCreateMica _MicaWindow(200, 100) $iWindowCount += 1 Case $idCreateMicaAlt _MicaWindow(200, 100, True) $iWindowCount += 1 Case $idCreateAcrylic _AcrylicWindow(200, 100) $iWindowCount += 1 EndSwitch If Not $iWindowCount Then ExitLoop WEnd EndFunc Func _MicaWindow($iWidth, $iHeight, $bAlternate = False) ReDim $aObjects[UBound($aObjects) + 1][4] Local $iIdx = UBound($aObjects) - 1 Local $hGUI = GUICreate($bAlternate ? "MicaAlt" : "Mica", $iWidth, $iHeight, -1, -1, BitOR($WS_OVERLAPPED, $WS_CAPTION, $WS_SYSMENU, $WS_CLIPCHILDREN), $WS_EX_COMPOSITED) _SetNCBackdropType($hGUI, $bAlternate ? $DWMSBT_TABBEDWINDOW : $DWMSBT_MAINWINDOW) _CreateCloseButton($hGUI, $iWidth - 90, $iHeight - 35, 80, 25) _WinRT_SwitchInterface($pCompositor, $sIID_ICompositorDesktopInterop) Local $pTarget = ICompositorDesktopInterop_CreateDesktopWindowTarget($pCompositor, $hGUI, False) _WinRT_SwitchInterface($pCompositor, $sIID_ICompositor) Local $pRoot = ICompositor_CreateContainerVisual($pCompositor) _WinRT_SwitchInterface($pTarget, $sIID_ICompositionTarget) ICompositionTarget_SetRoot($pTarget, $pRoot) Local $pSysBkdropController = _WinRT_ActivateInstance("Microsoft.UI.Composition.SystemBackdrops.MicaController") _WinRT_SwitchInterface($pSysBkdropController, $sIID_IMicaController2) IMicaController2_SetKind($pSysBkdropController, $bAlternate ? $mMicaKind["BaseAlt"] : $mMicaKind["Base"]) _WinRT_SwitchInterface($pSysBkdropController, $sIID_ISystemBackdropController) _WinRT_SwitchInterface($pTarget, $sIID_IDesktopWindowTarget) ISystemBackdropController_SetTarget($pSysBkdropController, _WinUI3_GetWindowIdFromWindow($hGUI), $pTarget) GUISetState(@SW_SHOW, $hGUI) $aObjects[$iIdx][0] = $hGUI $aObjects[$iIdx][1] = $pSysBkdropController $aObjects[$iIdx][2] = $pRoot $aObjects[$iIdx][3] = $pTarget EndFunc Func _AcrylicWindow($iWidth, $iHeight) ReDim $aObjects[UBound($aObjects) + 1][4] Local $iIdx = UBound($aObjects) - 1 Local $hGUI = GUICreate("Acrylic", $iWidth, $iHeight, -1, -1, BitOR($WS_OVERLAPPED, $WS_CAPTION, $WS_SYSMENU, $WS_CLIPCHILDREN), $WS_EX_COMPOSITED) _SetNCBackdropType($hGUI, $DWMSBT_TRANSIENTWINDOW) _CreateCloseButton($hGUI, $iWidth - 90, $iHeight - 35, 80, 25) _WinRT_SwitchInterface($pCompositor, $sIID_ICompositorDesktopInterop) Local $pTarget = ICompositorDesktopInterop_CreateDesktopWindowTarget($pCompositor, $hGUI, False) _WinRT_SwitchInterface($pCompositor, $sIID_ICompositor) Local $pRoot = ICompositor_CreateContainerVisual($pCompositor) _WinRT_SwitchInterface($pTarget, $sIID_ICompositionTarget) ICompositionTarget_SetRoot($pTarget, $pRoot) Local $pSysBkdropController = _WinRT_ActivateInstance("Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicController") _WinRT_SwitchInterface($pSysBkdropController, $sIID_ISystemBackdropController) _WinRT_SwitchInterface($pTarget, $sIID_IDesktopWindowTarget) ISystemBackdropController_SetTarget($pSysBkdropController, _WinUI3_GetWindowIdFromWindow($hGUI), $pTarget) $aObjects[$iIdx][0] = $hGUI $aObjects[$iIdx][1] = $pSysBkdropController $aObjects[$iIdx][2] = $pRoot $aObjects[$iIdx][3] = $pTarget GUISetState(@SW_SHOW, $hGUI) EndFunc Func DeleteWin($hWnd) For $i = 0 To UBound($aObjects) - 1 If $hWnd = $aObjects[$i][0] Then For $j = 1 To UBound($aObjects, 2) - 1 _WinRT_SwitchInterface($aObjects[$i][$j], $sIID_IClosable) IClosable_Close($aObjects[$i][$j]) Next $aObjects[$i][0] = 0 EndIf Next GUIDelete($hWnd) EndFunc Func _Cleanup() _WinRT_SwitchInterface($pCompositor, $sIID_IClosable) IClosable_Close($pCompositor) IUnknown_Release($pDispatcher) _WinRT_Shutdown() _WinUI3_Shutdown() EndFunc Func _WinRT_CreateDispatcherQueueController() Local $tOptions = DllStructCreate($tagDispatcherQueueOptions) $tOptions.dwSize = DllStructGetSize($tOptions) $tOptions.threadType = $DQTYPE_THREAD_CURRENT $tOptions.apartmentType = $DQTAT_COM_NONE Local $aCall = DllCall("CoreMessaging.dll", "long", "CreateDispatcherQueueController", "struct*", $tOptions, "ptr*", 0) Return SetError($aCall[0], 0, $aCall[2]) EndFunc Func ICompositorDesktopInterop_CreateDesktopWindowTarget($pThis, $hTarget, $bIsTopmost) Local $vFailVal = False Local $pFunc = __WinRT_GetFuncAddress($pThis, 4) If @error Then Return SetError(@error, @extended, $vFailVal) If $hTarget And Not IsHWnd($hTarget) Then Return SetError($ERROR_INVALID_PARAMETER, 0, $vFailVal) Local $aCall = DllCallAddress("ulong", $pFunc, "ptr", $pThis, "hwnd", $hTarget, "bool", ($bIsTopmost = True), "ptr*", 0) If @error Then Return SetError(__WinRT_GetDllError(), 0, $vFailVal) Return SetError($aCall[0], 0, $aCall[4]) EndFunc ;==>ICompositorDesktopInterop_CreateDesktopWindowTarget Func _CreateCloseButton($hWnd, $iX, $iY, $iWidth, $iHeight, $iStyle = -1, $iExStyle = -1) If $iStyle = -1 Then $iStyle = BitOR($WS_VISIBLE, $WS_CHILD) If $iExStyle = -1 Then $iExStyle = 0 $hButton = _WinAPI_CreateWindowEx($iExStyle, $WC_BUTTON, "Close", $iStyle, $iX, $iY, $iWidth, $iHeight, $hWnd, $IDCANCEL, _WinAPI_GetModuleHandle(0), 0) $hButton = _SendMessage($hButton, $WM_SETFONT, _WinAPI_GetStockObject($DEFAULT_GUI_FONT), True) Return $hButton EndFunc Func _SetNCBackdropType($hWnd, $iBackdropType) Local $aCall = DllCall("Dwmapi.dll", "long", "DwmSetWindowAttribute", "hwnd", $hWnd, "dword", $DWMWA_SYSTEMBACKDROP_TYPE, "dword*", $iBackdropType, "dword", 4) Return SetError($aCall[0], 0, $aCall[0] = $S_OK) EndFunc
-
@WildByDesign, this one's for you mate, Mica in a normal win32 window without the extended frame business #include <GUIConstants.au3> #include <WindowsConstants.au3> #include "..\Include\WinRT.au3" #include "..\Include\WinRT_WinUI3.au3" #include "..\Include\Classes\Microsoft.UI.Composition.SystemBackdrops.MicaController.au3" #include "..\Include\Classes\Microsoft.UI.Composition.SystemBackdrops.DesktopAcrylicController.au3" #include "..\Include\Classes\Windows.UI.Composition.Desktop.DesktopWindowTarget.au3" #include "..\Include\Classes\Windows.System.DispatcherQueueController.au3" #include "..\Include\Classes\Windows.UI.Composition.Compositor.au3" #include "..\Include\Classes\Windows.UI.Composition.Visual.au3" Global Const $sIID_ICompositorDesktopInterop = "{29E691FA-4567-4DCA-B319-D0F207EB6807}" $__g_mIIDs[$sIID_ICompositorDesktopInterop] = "ICompositorDesktopInterop" Global Const $tagDispatcherQueueOptions = "struct;dword dwSize;dword threadType;dword apartmentType;endstruct" Global Const $DQTYPE_THREAD_DEDICATED = 1 Global Const $DQTYPE_THREAD_CURRENT = 2 Global Const $DQTAT_COM_NONE = 0 Global Const $DQTAT_COM_ASTA = 1 Global Const $DQTAT_COM_STA = 2 _Init() _Main() _Cleanup() Func _Init() _WinRT_Startup() _WinUI3_Startup() EndFunc Func _Main() Local $hGUI = GUICreate("Mica", 400, 200, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) Local $pDispatcher = _WinRT_CreateDispatcherQueueController() Local $pCompositor = _WinRT_ActivateInstance("Windows.UI.Composition.Compositor") _WinRT_SwitchInterface($pCompositor, $sIID_ICompositorDesktopInterop) Local $pTarget = ICompositorDesktopInterop_CreateDesktopWindowTarget($pCompositor, $hGUI, False) _WinRT_SwitchInterface($pCompositor, $sIID_ICompositor) Local $pRoot = ICompositor_CreateContainerVisual($pCompositor) _WinRT_SwitchInterface($pTarget, $sIID_ICompositionTarget) ICompositionTarget_SetRoot($pTarget, $pRoot) _WinRT_DisplayError() Local $pMicaController = _WinRT_ActivateInstance("Microsoft.UI.Composition.SystemBackdrops.MicaController") _WinRT_SwitchInterface($pMicaController, $sIID_IMicaController2) IMicaController2_SetKind($pMicaController, $mMicaKind["Base"]) ; OR $mMicaKind["BaseAlt"] _WinRT_SwitchInterface($pMicaController, $sIID_ISystemBackdropController) _WinRT_SwitchInterface($pTarget, $sIID_IDesktopWindowTarget) ISystemBackdropController_SetTarget($pMicaController, _WinUI3_GetWindowIdFromWindow($hGUI), $pTarget) GUISetState() Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _WinRT_SwitchInterface($pMicaController, $sIID_IClosable) IClosable_Close($pMicaController) _WinRT_SwitchInterface($pRoot, $sIID_IClosable) IClosable_Close($pRoot) _WinRT_SwitchInterface($pTarget, $sIID_IClosable) IClosable_Close($pTarget) _WinRT_SwitchInterface($pCompositor, $sIID_IClosable) IClosable_Close($pCompositor) IUnknown_Release($pDispatcher) EndFunc Func _Cleanup() _WinRT_Shutdown() _WinUI3_Shutdown() EndFunc Func _WinRT_CreateDispatcherQueueController() Local $tOptions = DllStructCreate($tagDispatcherQueueOptions) $tOptions.dwSize = DllStructGetSize($tOptions) $tOptions.threadType = $DQTYPE_THREAD_CURRENT $tOptions.apartmentType = $DQTAT_COM_NONE Local $aCall = DllCall("CoreMessaging.dll", "long", "CreateDispatcherQueueController", "struct*", $tOptions, "ptr*", 0) Return SetError($aCall[0], 0, $aCall[2]) EndFunc Func ICompositorDesktopInterop_CreateDesktopWindowTarget($pThis, $hTarget, $bIsTopmost) Local $vFailVal = False Local $pFunc = __WinRT_GetFuncAddress($pThis, 4) If @error Then Return SetError(@error, @extended, $vFailVal) If $hTarget And Not IsHWnd($hTarget) Then Return SetError($ERROR_INVALID_PARAMETER, 0, $vFailVal) Local $aCall = DllCallAddress("ulong", $pFunc, "ptr", $pThis, "hwnd", $hTarget, "bool", ($bIsTopmost = True), "ptr*", 0) If @error Then Return SetError(__WinRT_GetDllError(), 0, $vFailVal) Return SetError($aCall[0], 0, $aCall[4]) EndFunc ;==>ICompositorDesktopInterop_CreateDesktopWindowTarget
-
MattyD reacted to a post in a topic:
Using ObjCreateInterface() and ObjectFromTag() Functions
-
Using ObjCreateInterface() and ObjectFromTag() Functions
MattyD replied to LarsJ's topic in AutoIt Example Scripts
Beaten to the punch! Yep, Dany's on the money. But just generally - if we had needed to switch interfaces, ObjCreateInterface does a QI and Release on an object pointers. Local $oICoreWebView2_8 = ObjCreateInterface($pCoreWebView2, $sIID_ICoreWebView2_8, $dtag_ICoreWebView2_8) We just need to be mindful of the ref count. $oICoreWebView will release itself when it goes out of scope - but the ptr won't. So for eg. If we want $pCoreWebView2 to outlive $oICoreWebView, then we should AddRef the object.