Jump to content

Recommended Posts

Posted (edited)

GUICtrlCreateAvi(@SystemDir & "\shell32.dll", 165,  is no longer there ( welcome to the future ). But we can use the one we have:

#include <GUIConstantsEx.au3>

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $hGUI = GUICreate("Example", 300, 200)

    ; Create an animation control.
;~     Local $idAvi_Animation = GUICtrlCreateAvi(@SystemDir & "\shell32.dll", 165, 15, 0, 300)
    Local $idAvi_Animation = GUICtrlCreateAvi(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1) - 1) & "\Examples\GUI\sampleAVI.avi", 0, 20, 20, 300, 300)
    Local $idBtn_Start = GUICtrlCreateButton("Start", 60, 150, 85, 25)
    Local $idBtn_Stop = GUICtrlCreateButton("Stop", 160, 150, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $idBtn_Start ; Start the animation.
                GUICtrlSetState($idAvi_Animation, $GUI_AVISTART)

            Case $idBtn_Stop ; Stop the animation.
                GUICtrlSetState($idAvi_Animation, $GUI_AVISTOP)

        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

so that the example will show something in Win11

..another option:

Spoiler
#include <GUIConstantsEx.au3>

Example()

Func Example()
    ; Create a GUI with various controls.
    Local $idAvi_Animation, $hGUI = GUICreate("Example", 300, 200)

    ; Create an animation control.
    If _InspectAVIResource(@SystemDir & "\shell32.dll", 165) > 1 Then
        $idAvi_Animation = GUICtrlCreateAvi(@SystemDir & "\shell32.dll", 165, 15, 0, 300)
    Else
        $idAvi_Animation = GUICtrlCreateAvi(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1) - 1) & "\Examples\GUI\sampleAVI.avi", 0, 20, 20, 300, 300)
    EndIf
    Local $idBtn_Start = GUICtrlCreateButton("Start", 60, 150, 85, 25)
    Local $idBtn_Stop = GUICtrlCreateButton("Stop", 160, 150, 85, 25)

    ; Display the GUI.
    GUISetState(@SW_SHOW, $hGUI)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $idBtn_Start ; Start the animation.
                GUICtrlSetState($idAvi_Animation, $GUI_AVISTART)

            Case $idBtn_Stop ; Stop the animation.
                GUICtrlSetState($idAvi_Animation, $GUI_AVISTOP)

        EndSwitch
    WEnd

    ; Delete the previous GUI and all controls.
    GUIDelete($hGUI)
EndFunc   ;==>Example

Func _InspectAVIResource($sModulePath, $vResID)
    Local Const $LOAD_LIBRARY_AS_DATAFILE = 0x00000002

    ; Load module
    Local $aRet = DllCall("kernel32.dll", "handle", "LoadLibraryExW", "wstr", $sModulePath, "ptr", 0, "dword", $LOAD_LIBRARY_AS_DATAFILE)
    If @error Or Not $aRet[0] Then Return ConsoleWrite("Failed to load DLL" & @CRLF)
    Local $hModule = $aRet[0]

    ; Find resource
    Local $sTypeID = IsInt($vResID) ? Ptr($vResID) : $vResID
    $aRet = DllCall("kernel32.dll", "handle", "FindResourceW", "handle", $hModule, "ptr", $sTypeID, "wstr", "AVI")
    If @error Or Not $aRet[0] Then
        DllCall("kernel32.dll", "bool", "FreeLibrary", "handle", $hModule)
        Return SetError(1, 0, 0) ; ConsoleWrite("Resource handle not found." & @CRLF)
    EndIf
    Local $hResInfo = $aRet[0]

    ; Get total size in bytes
    $aRet = DllCall("kernel32.dll", "dword", "SizeofResource", "handle", $hModule, "handle", $hResInfo)
    Local $iTotalSize = $aRet[0]

    ; Lock memory buffer
    $aRet = DllCall("kernel32.dll", "handle", "LoadResource", "handle", $hModule, "handle", $hResInfo)
    Local $hResData = $aRet[0]
    $aRet = DllCall("kernel32.dll", "ptr", "LockResource", "handle", $hResData)
    Local $pBuffer = $aRet[0]

    ; Parse RIFF Container (Bytes 0..11)
    Local $tRIFF = DllStructCreate("char magic[4]; dword size; char type[4]", $pBuffer)
    Local $sMagic = DllStructGetData($tRIFF, "magic")
    Local $sType = DllStructGetData($tRIFF, "type")

    ; Parse Main AVI Header 'avih' (Bytes 24..51)
    Local $tAVIH = DllStructCreate("char chunkId[4]; dword chunkSize; dword uSecPerFrame; dword maxBytes; dword padding; dword flags; dword totalFrames", $pBuffer + 24)
    Local $sChunkID = DllStructGetData($tAVIH, "chunkId")
    Local $iFrames = DllStructGetData($tAVIH, "totalFrames")

;~  ConsoleWrite("Container Type: " & $sMagic & " / " & $sType & @CRLF)
;~  ConsoleWrite("Resource Size : " & $iTotalSize & " bytes" & @CRLF)
;~  ConsoleWrite("Header Chunk  : " & $sChunkID & @CRLF)
;~  ConsoleWrite("Frame Count   : " & $iFrames & @CRLF)

    DllCall("kernel32.dll", "bool", "FreeLibrary", "handle", $hModule)
    Return $iFrames
EndFunc   ;==>_InspectAVIResource

 

to keep it compatible with older systems but it needs more testing
Tested in Win7 and shows 31 frames vs. 1 frame in Win11

Spoiler
The deprecation and removal of system AVI resources from shell32.dll happened in two distinct phases:
 
1. The Feature Deprecation (Windows Vista)
Microsoft stopped using shell32.dll AVI animations inside Windows Explorer starting with Windows Vista. The OS shifted away from the legacy Win32 SysAnimate32 control to modern WPF, Direct2D, and UIFILE progress dialogs. However, the physical .avi data was kept inside shell32.dll through Windows Vista and Windows 7 so legacy 32-bit software could still load them.
 
2. The Resource Payload Stripping (Windows 8 & Windows 10)
During Windows 8 and early Windows 10 builds, Microsoft gutted the actual video data from shell32.dll to reduce system DLL file sizes:
 
  • Dummy Container Headers: Instead of deleting the resource entries outright (which would break legacy resource lookup calls), Microsoft replaced the video streams with 1-frame dummy RIFF headers.
  • Windows 10 v1903 (May 2019 Update): System resources were decoupled from System32\shell32.dll and moved into C:\Windows\SystemResources\shell32.dll.mun, rendering shell32.dll a shell wrapper with stubbed resources.

Timeline Overview

Windows Version AVI Status in shell32.dll Behavior in AutoIt / Win32
Windows XP Fully Functional AVI animations played natively in Explorer and custom scripts.
Windows Vista / 7 Deprecated by OS Explorer stopped using them, but third-party apps could still play the DLL resources.
Windows 8 / 10 Stripped to 1-Frame Stubs Resource IDs exist, but video frames are zeroed out or reduced to 1 static frame.
Windows 10 1903+ / 11 Moved to .mun / Empty Stubs GUICtrlCreateAvi fails to play because no playable video data exists.
For modern Windows support, bundle local uncompressed .avi files alongside your script or transition to animated GIFs using GDI+.

..and the why/when above

Edited by argumentum
more

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

Posted
31 minutes ago, argumentum said:

GUICtrlCreateAvi(@SystemDir & "\shell32.dll", 165,  is no longer there ( welcome to the future ).

From the help file, the following standard UDF functions also use that missing resource and would therefore need updated example code:

_GUICtrlAVI_Create  Example 2
_GUICtrlAVI_OpenEx  Example 1
_GUICtrlAVI_Play    Example 1 and Example 2
_GUICtrlAVI_Seek    Example 1 and Example 2
_GUICtrlAVI_Show    Example 1 and Example 2
_GUICtrlAVI_Stop    Example 1 and Example 2

Although it's possible that it could be used in more examples as well but that is what I was able to find without a thorough search.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...