Popular Post MattyD Posted April 30 Popular Post Posted April 30 (edited) Hi all, I'll try to keep this succinct... Since windows 10 1903 it has been possible to embed UWP controls (i.e. XAML controls) in win32 apps. The container that holds a XAML control is a XAML Island. For non-legacy media playback, Microsoft tells us to use the WinRT MediaPlayer object with the MediaPlayerElement control. MediaPlayerElement is the UI & video rendering component of the player (the XAML control). The other MediaPlayer object is the bones of the player which you attach to the control. To get this working you annoyingly need to add the maxversiontested element to the application manifest. There's script in the zip which will copy AutoIt.exe (or AutoIt_x64.exe if you're using it) and update its manifest. If you replace the original file with the modified one, you should be able to successfully run the example with the F5 key. Or here's a screenshot if you just want to see the result! PS. As an aside, Another way of approaching modern playback is via MediaEngine which we've recently attempted to get going. This approach doesn't play well with autoit though, and you need to do ungodly things to prevent callbacks from crashing your script! MediaPlayer.zip Edited May 1 by MattyD Gianni, mLipok, argumentum and 4 others 7
SOLVE-SMART Posted April 30 Posted April 30 Well done @MattyD, thank you 👍 . Oberviously you had to generate (write) many code. What bothers me a little bit are the many dependencies that you have to include in the projects, "just" to use WinRT MediaPlayer object or XAML controls. I know there are not much alternatives, but this is the point why I would not use it 😔 . Spoiler Don't get me wrong, I appreciate the work and the solution for the use case, but I don't really like it. Best regards Sven ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet, 🔗 autoit-webdriver-boilerplate Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
MattyD Posted April 30 Author Posted April 30 (edited) yeah fair enough, totally get where you're coming from. Just to explain though - this uses libraries from the WinRT project which literally has thousands of objects wrapped. The folder structure is a way for me to drop objects in and out of a project without definitions getting in the way of each other. So we could probably boil all this down to a single header - but it will only be useful for this implementation. So the setup is more for me I guess! There are Interface tags in all the interface libraries. So for a more traditional approach with ObjCreateInterface() I'd probably extract all those and dump them into its own include file. You'd would also lose the benefits of things like calltips, and a few other perks but you gain a bit more simplicity with the file structure. Edited April 30 by MattyD SOLVE-SMART 1
SOLVE-SMART Posted April 30 Posted April 30 Thanks for the explanation - understood. Sound reasonably. 57 minutes ago, MattyD said: There are Interface tags in all the interface libraries. So for a more traditional approach with ObjCreateInterface() I'd probably extract all those and dump them into its own include file. You'd would also lose the benefits of things like calltips, and a few other perks but you gain a bit more simplicity with the file structure. You're right. On a second thought, I personally have no use case for it at all, but it's still useful, no question 👍 . Off-topic: Spoiler In the nearly past we (as community) tried to enhance AutoIt GUIs by several things (WebViews, WinRT, embedding web code and others). It's nice to have possibilites and showcases of how such things can be achieved, but for me AutoIt isn't the right approach for such problems/challenges. But this is of course just me. For private projects it's nice and I do often tryouts for such scenarios, but in my profession I (hopefully) choose the right tooling/framework for the goal/problem/challange. Personally I really would love to see AutoIt enhancing by cross platform functionality and some other features or beeing open source, but this will not happen. So more and more people will leave AutoIt behind in the future. Anyway, just few thoughts. Again: Thanks for the showcase and the effort @MattyD 👌 . Best regards Sven ==> AutoIt related: 🔗 GitHub, 🔗 Discord Server, 🔗 Cheat Sheet, 🔗 autoit-webdriver-boilerplate Spoiler 🌍 Au3Forums 🎲 AutoIt (en) Cheat Sheet 📊 AutoIt limits/defaults 💎 Code Katas: [...] (comming soon) 🎭 Collection of GitHub users with AutoIt projects 🐞 False-Positives 🔮 Me on GitHub 💬 Opinion about new forum sub category 📑 UDF wiki list ✂ VSCode-AutoItSnippets 📑 WebDriver FAQs 👨🏫 WebDriver Tutorial (coming soon)
MattyD Posted May 1 Author Posted May 1 Hi all, just a quick one I've updated the zip in post #1 - its the same thing, but I've included a tool so you can easily update that application manifest. Gianni 1
Gianni Posted May 1 Posted May 1 (edited) Hi @MattyD I replaced the original autoit3.exe file with the modified version generated by your script (..?! you know things that I obviously don't know) and in this way MediaPlayer.au3 works. Then I tried to compile MediaPlayer.au3 but the generated executable does not work (the autoit3.exe file after compilation is still the modified one). Is there any trick to be able to compile MediaPlayer.au3 into a working executable and then restore the original autoit3.exe file in the AutoIt folder? Bye and thanks Edited May 1 by Gianni Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
MattyD Posted May 1 Author Posted May 1 Yeah, there's a couple of options really, You could just modify that "update manifest.au3" so it replaces the resource in your compiled script (rather than @autoitexe). But my original approach was to modify AutoItWrapper.au3. On line 2670 I inserted this. FileWriteLine($hTempFile2, ' <maxversiontested Id="10.0.18362.1" />') Then in your script, you need the following directive to trigger that bit of code: #Autoit3Wrapper_Res_Compatibility=Win10 I don't think the actual build number is critical - I'd imagine things should be OK so long as the build is after win10 1903. Win10 22H2 is 10.0.19045.0 if you wanted to specify something more current! Gianni and argumentum 1 1
Gianni Posted May 1 Posted May 1 I applied the patch to the compiled executable file instead of AutoIt3.exe and that worked. Thanks MattyD 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
argumentum Posted May 1 Posted May 1 (edited) On 5/1/2025 at 7:54 AM, MattyD said: But my original approach was to modify AutoItWrapper.au3. On line 2670 I inserted this. In my version of it does not fall under that line. ... ... If StringInStr($INP_Res_Compatibility, "Win10") Then ; https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests#maxversiontested FileWriteLine($hTempFile2, ' <!-- Windows 10, version 1903 -->') FileWriteLine($hTempFile2, ' <maxversiontested Id="10.0.18362.1" />') FileWriteLine($hTempFile2, ' <!--The ID below indicates application support for Windows Vista -->') ... ... This will be easier to find as beta versions come out. Thank you for the food code Edited May 5 by argumentum better MattyD 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted May 2 Posted May 2 (edited) ...a bunch of nonsense but kept for hysterical historical purposes Spoiler I was looking at the color picker you posted and compiled it with the above but it should be runed as script to read the console. Did I rename the @AutoItExe and get over with it ?, no..., that's too easy I patched AutoItWrapper.au3 because that is fun Spoiler expandcollapse popup... ... $ProcessBar_Title = "(" & $VERSION & ") Processing : " & StringTrimLeft($ScriptFile_In, StringInStr($ScriptFile_In, "\", 0, -1)) ; set AutoIt3.Exe to the AutoIt3dir specified on the commandline when supplied If $AutoIt3_PGM <> "" Then ; use the autoit3.exe defined by the #autoit3wrapper_autoit3 directive Global $sDrive = "", $sDir = "", $sFileName = "", $sExtension = "" _PathSplit($AutoIt3_PGM, $sDrive, $sDir, $sFileName, $sExtension) $CurrentAutoIt_InstallDir = $sDrive & StringTrimRight($sDir, 1) ElseIf $CurrentAutoIt_InstallDir <> "" And FileExists($CurrentAutoIt_InstallDir & "\autoit3" & ($Option = "ModRun" ? "-Mod" : "") & ".exe") Then If @OSArch <> "x86" And $INP_UseX64 = "y" And FileExists($CurrentAutoIt_InstallDir & "\autoit3_x64" & ($Option = "ModRun" ? "-Mod" : "") & ".exe") Then $AutoIt3_PGM = $CurrentAutoIt_InstallDir & "\autoit3_x64" & ($Option = "ModRun" ? "-Mod" : "") & ".exe" Else $AutoIt3_PGM = $CurrentAutoIt_InstallDir & "\autoit3" & ($Option = "ModRun" ? "-Mod" : "") & ".exe" EndIf Else If @OSArch <> "x86" And $INP_UseX64 = "y" And FileExists($CurrentAutoIt_InstallDir & "\autoit3_x64" & ($Option = "ModRun" ? "-Mod" : "") & ".exe") Then $AutoIt3_PGM = $CurrentAutoIt_InstallDir & "\autoit3_x64" & ($Option = "ModRun" ? "-Mod" : "") & ".exe" Else $AutoIt3_PGM = $CurrentAutoIt_InstallDir & "\autoit3" & ($Option = "ModRun" ? "-Mod" : "") & ".exe" EndIf EndIf ... ... #Region ;Run the Script If $Option = "Run" Or $Option = "RunAdmin" Or $Option = "ModRun" Then ; 2025.05.02 ProgressOff() ... ... Opt("GUICoordMode", 1) ; 2025.05.02 Local $h_Form = GUICreate("AutoIt3Wrapper GUI to Compile AutotIt3 Script (ver " & $VERSION & ")", 700, 525, (@DesktopWidth - 650) / 2, (@DesktopHeight - 500) / 2) Local $h_File = GUICtrlCreateMenu("&File") Local $h_Exit = GUICtrlCreateMenuItem("&Exit", $h_File) ... ... Local $H_RUN = GUICtrlCreateButton("&Run", 90, 445, 70, 30) ; 2025.05.02 Local $H_RUN_OptionsContext = GUICtrlCreateContextMenu(GUICtrlCreateDummy()) Local $H_RUN_ContextRunNormal = GUICtrlCreateMenuItem("Run &Normal", $H_RUN_OptionsContext) Local $H_RUN_ContextRunMod = GUICtrlCreateMenuItem("Run &Mod", $H_RUN_OptionsContext) Local $H_COMPILE = GUICtrlCreateButton("&Compile", 170, 445, 70, 30) ... ... ; Change Target program clicked Switch $rc Case $H_RUN ; 2025.05.02 ShowMenu($h_Form, $g_rc, $H_RUN_OptionsContext) Case $tab ... ... Switch $g_rc Case $H_AU3CHECK $g_Option = "Au3Check" Case $H_RUN_ContextRunNormal $g_Option = "Run" Case $H_RUN_ContextRunMod $g_Option = "ModRun" Case $H_COMPILE $g_Option = "Compile" ... ... #EndRegion ### FMIPC ### ; 2025.05.02 ; Show a menu in a given GUI window which belongs to a given GUI ctrl Func ShowMenu($hWnd, $idCtrl, $idContext) ; Local $aPos, $x, $y Local $hMenu = GUICtrlGetHandle($idContext) $aPos = ControlGetPos($hWnd, "", $idCtrl) $x = $aPos[0] $y = $aPos[1] + $aPos[3] ClientToScreen($hWnd, $x, $y) TrackPopupMenu($hWnd, $hMenu, $x, $y) EndFunc ;==>ShowMenu ; Convert the client (GUI) coordinates to screen (desktop) coordinates Func ClientToScreen($hWnd, ByRef $x, ByRef $y) Local $tPoint = DllStructCreate("int;int") DllStructSetData($tPoint, 1, $x) DllStructSetData($tPoint, 2, $y) DllCall("user32.dll", "int", "ClientToScreen", "hwnd", $hWnd, "struct*", $tPoint) $x = DllStructGetData($tPoint, 1) $y = DllStructGetData($tPoint, 2) ; release Struct not really needed as it is a local $tPoint = 0 EndFunc ;==>ClientToScreen ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) Func TrackPopupMenu($hWnd, $hMenu, $x, $y) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ;==>TrackPopupMenu ..and those are the edits to run the "-mod" added executables without making the change permanent. Ctrl - F7 as if to compile and click run. You'll now find a "Run normal" and "Run mod" To me is easier to do it this way 🤪 ... so, yes. Use the solution below Edited May 3 by argumentum oops MattyD 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted May 3 Posted May 3 even awesome-er would be to just declare the exe to use: #AutoIt3Wrapper_AutoIt3=D:\Utilities\AutoIt3\autoit3_x64-Mod.exe ; replace with your path and that is something that didn't come to mind at the time so, I'll remove the patch as is obviously not needed. MattyD 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
WildByDesign Posted Wednesday at 03:15 PM Posted Wednesday at 03:15 PM Since my line of work is in the computer security world, I am not a big fan of patching binaries and invalidating digital signatures. But I am a big fan of the work that you do for the AutoIt community, Matty. And I am curious about this project as well. Therefore, I wanted to provide an alternative way to do this without invalidating the digital signatures of the binaries. You need to drop the two manifest files into your AutoIt directory alongside the matching binaries. Pre-Win10, this would have been enough. However, in Win10/Win11 they made it so that you could not use manifest files within %WINDIR%, %PROGRAMFILES% or %PROGRAMFILES(X86)% directories and subdirectories. To allow, run the following from an elevated command prompt: REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide /v PreferExternalManifest /t REG_DWORD /d 1 /f There is no need to reboot after this change. To disallow, run the following from an elevated command prompt: REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide /v PreferExternalManifest /t REG_DWORD /d 0 /f Cheers! AutoIt3.exe.manifest AutoIt3_x64.exe.manifest MattyD 1
WildByDesign Posted Wednesday at 05:16 PM Posted Wednesday at 05:16 PM (edited) I figured out how to change the dimensions of the video and fullscreen and so on. I am really impressed at how low the CPU usage is with this, especially when resizing the video. Does anyone know how to make the MediaPlayer.au3 example script do autoplay and repeat/loop of the video? EDIT: I figured out the AutoPlay so far. ;Initiate AutoPlay IMediaPlayer_SetAutoPlay($pPlayer, True) I added that right before the Do Until loop. EDIT2: Adding repeat/looping was easy as well. ;Allow video to repeat/loop IMediaPlayer_SetIsLoopingEnabled($pPlayer, True) This was also added right before the Do Until loop. Edited Wednesday at 08:55 PM by WildByDesign
WildByDesign Posted Wednesday at 09:03 PM Posted Wednesday at 09:03 PM (edited) And with that, thanks to @MattyD and @UEZ for the WorkerW code, we have GPU accelerated desktop wallpaper videos. On line 24, you just have to add a path to an MP4 video or any video that MediaPlayerElement supports. CPU usage is lower than all of the animated GIF scripts in the forum, even while stretching the video when necessary. Spoiler expandcollapse popup#include <GUIConstants.au3> #include <winapi.au3> #include "Include\WinRT.au3" #include "Include\Classes\Windows.UI.Xaml.Hosting.WindowsXamlManager.au3" #include "Include\Classes\Windows.UI.Xaml.Hosting.DesktopWindowXamlSource.au3" #include "Include\Interfaces\IDesktopWindowXamlSourceNative.au3" #include "Include\Classes\Windows.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.Playback.MediaPlayer.au3" ;Code by UEZ build 2025-07-18 beta #include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIGdi.au3> #include <Array.au3> #include <GDIPlus.au3> DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -4) Global $sTestFile = @ScriptDir & "\bloom.mp4" _WinRT_Startup() Global $aPrimary = GetPrimaryMonitorCoords() If @error Then Exit MsgBox(16, "Error", "Unable to get primary monitor") Global $hProgman = WinGetHandle("[CLASS:Progman]"), $hWorkerW, $i If Not $hProgman Then Exit MsgBox(16, "ERROR", "Couldn't find Progman", 30) _WinAPI_SendMessageTimeout($hProgman, 0x052C, 13, 1, 250, $SMTO_NORMAL) Global $hWorkerW = _WinAPI_FindWindowEx($hProgman, 0, "WorkerW", "") If $hWorkerW = 0 Then Exit MsgBox(16, "ERROR", "Couldn't find WorkerW under Progman", 30) Local $aOrigin = GetDesktopOrigin() Local $iX = $aPrimary[0] - $aOrigin[0] Local $iY = $aPrimary[1] - $aOrigin[1] ;Startup XAML Host Local $pXamlMgr_Fact = _WinRT_GetActivationFactory("Windows.UI.Xaml.Hosting.WindowsXamlManager", $sIID_IWindowsXamlManagerStatics) Local $pWindowsXamlManager = IWindowsXamlManagerStatics_InitializeForCurrentThread($pXamlMgr_Fact) ;Create Container Local $pDesktopWinXamlSrc_Fact = _WinRT_GetActivationFactory("Windows.UI.Xaml.Hosting.DesktopWindowXamlSource", $sIID_IDesktopWindowXamlSourceFactory) Local $pInnerInterface $pDesktopWinXamlSrc = IDesktopWindowXamlSourceFactory_CreateInstance($pDesktopWinXamlSrc_Fact, 0, $pInnerInterface) ;Create XAML control Local $pMediaPlayerElement_Fact = _WinRT_GetActivationFactory("Windows.UI.Xaml.Controls.MediaPlayerElement", $sIID_IMediaPlayerElementFactory) Local $pMediaPlayerElement = IMediaPlayerElementFactory_CreateInstance($pMediaPlayerElement_Fact, 0, $pInnerInterface) IDesktopWindowXamlSource_SetContent($pDesktopWinXamlSrc, $pMediaPlayerElement) ;Attach control to the container. ;IMediaPlayerElement_SetAreTransportControlsEnabled($pMediaPlayerElement, 1) Global $hGUI = GUICreate("Desktop Video", $aPrimary[4], $aPrimary[5], $iX, $iY, $WS_POPUP, $WS_EX_TOOLWINDOW) ;GUISetBkColor(0xff00ff) _WinAPI_SetParent($hGUI, $hWorkerW) _WinAPI_SetWindowPos($hGUI, $HWND_BOTTOM, 0, 0, 0, 0, BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE)) _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_LAYERED, $WS_EX_TRANSPARENT)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0, 255, $LWA_ALPHA) GUISetState(@SW_SHOWNOACTIVATE, $hGUI) ;Attach the container to our GUI. Local $pDesktopWinXamlSrcNative = IUnknown_QueryInterface($pDesktopWinXamlSrc, $sIID_IDesktopWindowXamlSourceNative) IDesktopWindowXamlSourceNative_AttachToWindow($pDesktopWinXamlSrcNative, $hGUI) ;Position and show the island - (by default, the width and hight are 0) Local $hIsland = IDesktopWindowXamlSourceNative_GetWindowHandle($pDesktopWinXamlSrcNative) IUnknown_Release($pDesktopWinXamlSrcNative) _WinAPI_SetWindowPos($hIsland, $HWND_TOP, $iX, $iY, $aPrimary[4], $aPrimary[5], $SWP_SHOWWINDOW) ;Prepare our test video. Local $pFileFact = _WinRT_GetActivationFactory("Windows.Storage.StorageFile", $sIID_IStorageFileStatics) Local $pAsync = IStorageFileStatics_GetFileFromPathAsync($pFileFact, $sTestFile) Local $pFile = _WinRT_WaitForAsync($pAsync, "ptr*") Local $pMediaSrcFact = _WinRT_GetActivationFactory("Windows.Media.Core.MediaSource", $sIID_IMediaSourceStatics) Local $pMediaSrc = IMediaSourceStatics_CreateFromStorageFile($pMediaSrcFact, $pFile) ;Setup the player obj, load the test file Local $pPlayer = _WinRT_ActivateInstance("Windows.Media.Playback.MediaPlayer") Local $pPlayer_Src = IUnknown_QueryInterface($pPlayer, $sIID_IMediaPlayerSource) IMediaPlayerSource_SetMediaSource($pPlayer_Src, $pMediaSrc) IUnknown_Release($pPlayer_Src) ;Attach the player obj to the XAML control. IMediaPlayerElement_SetMediaPlayer($pMediaPlayerElement, $pPlayer) ;Initiate AutoPlay IMediaPlayer_SetAutoPlay($pPlayer, True) ;Allow video to repeat/loop IMediaPlayer_SetIsLoopingEnabled($pPlayer, True) While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd IClosable_Close(IUnknown_QueryInterface($pPlayer, $sIID_IClosable)) IClosable_Close(IUnknown_QueryInterface($pDesktopWinXamlSrc, $sIID_IClosable)) IClosable_Close(IUnknown_QueryInterface($pWindowsXamlManager, $sIID_IClosable)) _WinRT_Shutdown() GUIDelete($hGUI) Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc ;==>_WinAPI_FindWindowEx Func GetPrimaryMonitorCoords() Local $tPoint = DllStructCreate("int x;int y") $tPoint.x = 0 $tPoint.y = 0 Local $hMonitor = _WinAPI_MonitorFromPoint($tPoint, $MONITOR_DEFAULTTOPRIMARY) If Not $hMonitor Then Return SetError(1, 0, 0) Local $tMI = DllStructCreate("dword cbSize;long rcMonitor[4];long rcWork[4];dword dwFlags") DllStructSetData($tMI, "cbSize", DllStructGetSize($tMI)) Local $aCall = DllCall("user32.dll", "bool", "GetMonitorInfoW", "handle", $hMonitor, "ptr", DllStructGetPtr($tMI)) If @error Or Not $aCall[0] Then Return SetError(2, 0, 0) Local $iLeft = $tMI.rcMonitor(1) Local $iTop = $tMI.rcMonitor(2) Local $iRight = $tMI.rcMonitor(3) Local $iBottom = $tMI.rcMonitor(4) Local $iWidth = $iRight - $iLeft Local $iHeight = $iBottom - $iTop Local $a[6] = [$iLeft, $iTop, $iRight, $iBottom, $iWidth, $iHeight] Return $a EndFunc ;==>GetPrimaryMonitorCoords Func GetDesktopOrigin() Local $minX = 0, $minY = 0, $x, $y Local $i = 0, $tDevice, $aRet, $tDevMode, $aED While True $tDevice = DllStructCreate("dword cb; char DeviceName[32]; char DeviceString[128]; dword StateFlags; char DeviceID[128]; char DeviceKey[128]") $tDevice.cb = DllStructGetSize($tDevice) $aRet = DllCall("user32.dll", "bool", "EnumDisplayDevicesA", "ptr", 0, "dword", $i, "ptr", DllStructGetPtr($tDevice), "dword", 0) If @error Or Not $aRet[0] Then ExitLoop If BitAND($tDevice.StateFlags, 1) Then $tDevMode = DllStructCreate( _ "byte dmDeviceName[32]; word dmSpecVersion; word dmDriverVersion; word dmSize; word dmDriverExtra; dword dmFields;" & _ "long dmPositionX; long dmPositionY; dword dmDisplayOrientation; dword dmDisplayFixedOutput;" & _ "short dmColor; short dmDuplex; short dmYResolution; short dmTTOption; short dmCollate; char dmFormName[32];" & _ "ushort dmLogPixels; dword dmBitsPerPel; dword dmPelsWidth; dword dmPelsHeight;" & _ "dword dmDisplayFlags; dword dmDisplayFrequency; dword dmICMMethod; dword dmICMIntent;" & _ "dword dmMediaType; dword dmDitherType; dword dmReserved1; dword dmReserved2; dword dmPanningWidth; dword dmPanningHeight") $tDevMode.dmSize = DllStructGetSize($tDevMode) $aED = DllCall("user32.dll", "bool", "EnumDisplaySettingsA", "str", $tDevice.DeviceName, "dword", -1, "ptr", DllStructGetPtr($tDevMode)) If Not @error And $aED[0] Then $x = $tDevMode.dmPositionX $y = $tDevMode.dmPositionY If $x < $minX Then $minX = $x If $y < $minY Then $minY = $y EndIf EndIf $i += 1 WEnd Local $a[2] = [$minX, $minY] Return $a EndFunc ;==>GetDesktopOrigin Animated Wallpaper: Spoiler bloom.mp4 Edited Wednesday at 10:56 PM by WildByDesign Added bloom.mp4 MattyD 1
MattyD Posted Thursday at 04:41 AM Author Posted Thursday at 04:41 AM nice Its a bit off-topic - but I don't think we can do a "proper" full screen player via XAML islands. (It can obviously be simulated though) from: https://learn.microsoft.com/en-us/windows/apps/desktop/modernize/xaml-islands/xaml-islands Quote 🚫 The MediaPlayer control and MediaPlayerElement host control are not supported in full screen mode. If i have time over the weekend I'll try the WinUI3 version. We'll see if it that fares any better... WildByDesign 1
WildByDesign Posted Friday at 12:00 AM Posted Friday at 12:00 AM (edited) I was able to figure out a lot of neat things thanks to you making all of the functions available. There are two functions related to TimeSpan values that I don't understand and I was hoping you would be able to help me to understand them better. IMediaPlayer_SetPosition($pThis, $iValue) I would like to be able to set the position in seconds. But from looking up the MS docs on it, it's looking for a TimeSpan value and I don't know how to convert to TimeSpan. IMediaPlayer_GetNaturalDuration($pThis) I would like to get the duration of the video file and I assume that is what GetNaturalDuration is for. However, again, it's supposed to provide a TimeSpan value according to the docs and I have no idea how to convert TimeSpan back to seconds. If you are able to help with those two, I would really appreciate it. EDIT: I was able to figure out the first one for setting the position in seconds. It seems to go by ticks, and there are 10 million ticks in each second. ; Set video to 2 second position IMediaPlayer_SetPosition($pPlayer, 10000000 * 2) Edited Friday at 09:46 AM by WildByDesign
MattyD Posted Friday at 11:59 AM Author Posted Friday at 11:59 AM (edited) yeah it will be the same, in 100-nanosecond units. But - the video must be loaded for the function to return a value... So if you call GetNaturalDuration prematurely - i.e. while the video is still loading, it will return 0. You should be able to register an event handler (aka delegate) so you'll know when the player is ready though. Id say IMediaPlayer_AddHdlrMediaOpened is probably what you're after. With newer versions of WinRT.au3 you can do this pretty easily! Check out: https://www.autoitscript.com/forum/topic/212974-winrt-winui3/#findComment-1545648 I'd try grabbing a copy of "winrt.au3" and "winrtcore.au3" from that post, or another one further down in that thread... PS. Let me know if you're after any extra class libraries etc for your project, and I'll run them up for you! Edited Friday at 12:19 PM by MattyD WildByDesign 1
WildByDesign Posted Friday at 01:21 PM Posted Friday at 01:21 PM 1 hour ago, MattyD said: You should be able to register an event handler (aka delegate) so you'll know when the player is ready though. Id say IMediaPlayer_AddHdlrMediaOpened is probably what you're after. With newer versions of WinRT.au3 you can do this pretty easily! I don't feel like I have a good enough understanding of this WinRT functionality to implement an event handler for this. It's definitely above my skill level. For now, I've just used another non-WinRT function to obtain the media file properties and get the length that way. It seems to work well enough for .mp4 and .mkv from what I've tested so far. 1 hour ago, MattyD said: I'd try grabbing a copy of "winrt.au3" and "winrtcore.au3" from that post, or another one further down in that thread... PS. Let me know if you're after any extra class libraries etc for your project, and I'll run them up for you! Thank you. I did as you suggested and grabbed the latest (including classes, interfaces, etc.) and updated the ones that I was using. Everything is working well and I am excited to continue exploring the possibilities with this. Thanks again for bringing all of this more modern functionality (incl. WinUI3 in other thread) to AutoIt. Lots to explore. By the way, compiled binaries fail without <maxversiontested Id="10.0.18362.1"/>. So I ended up modifying AutoIt3Wrapper.au3 to include: FileWriteLine($hTempFile2, ' <maxversiontested Id="10.0.18362.1"/>') I added it to the Compatibility/Manifest area in the "Win10" section. This allows compiled binaries to work now. Do you think that we should request that this be added to the actual AutoIt3Wrapper.au3 script? Or maybe as an additional option?
MattyD Posted Saturday at 02:53 AM Author Posted Saturday at 02:53 AM (edited) 13 hours ago, WildByDesign said: Do you think that we should request that this be added to the actual AutoIt3Wrapper.au3 script? Or maybe as an additional option? That's probably a question for @Jos. I'd say its unlikely to get up, but there's no harm in asking. So that event handler would look something like this: Func MediaOpened($pThis, $pSender, $pArgs) _WinRT_SwitchInterface($pSender, $sIID_IMediaPlayer) ;might be unnecessary, but ensures we're on the correct interface! ConsoleWrite("Duration: " & IMediaPlayer_GetNaturalDuration($pSender) / 10000000 & " Seconds" & @CRLF) EndFunc To register it: before calling IMediaPlayerSource_SetMediaSource() Local $pHdlr_MediaOpened = _WinRT_CreateDelegate("MediaOpened") Local $iHdlr_MediaOpenedTkn = IMediaPlayer_AddHdlrMediaOpened($pPlayer, $pHdlr_MediaOpened) _WinRT_DisplayError() And teardown on exit: IMediaPlayer_RemoveHdlrMediaOpened($pPlayer, $iHdlr_MediaOpenedTkn) _WinRT_DestroyDelegate($pHdlr_MediaOpened) This usually works a treat.. but it seems that this object actually checks that our delegate is a Windows.Foundation.TypedEventHandler`2<Windows.Media.Playback.MediaPlayer, System.Object>. So registration is failing here. Resolving the IID for this is a bit complex, and I'm close - but not there yet. I gather it should be: {F1A6A51E-D078-5C40-BA3F-348870BA5C87}. So as a quick and dirty, we can modify __QueryInterface() in winRT.au3 so the IID is always "found"... Func __QueryInterface($pThis, $pIID, $ppObj) Local $hResult = $S_OK If Not $ppObj Then $hResult = $E_POINTER ElseIf _WinAPI_StringFromGUID($pIID) = $sIID_IUnknown Then DllStructSetData(DllStructCreate("ptr", $ppObj), 1, $pThis) __AddRef($pThis) ElseIf _WinAPI_StringFromGUID($pIID) = "{F1A6A51E-D078-5C40-BA3F-348870BA5C87}" Then DllStructSetData(DllStructCreate("ptr", $ppObj), 1, $pThis) __AddRef($pThis) Else $hResult = $E_NOINTERFACE EndIf Return $hResult EndFunc Edited Saturday at 02:55 AM by MattyD
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now