Adding data to the program resources
Previous Top Next

Adding a sound:

; Example - Adding a sound file

; Add the file
#AutoIt3Wrapper_Res_File_Add=C:\WINDOWS\Media\tada.wav, SOUND, MYWAV

Global Const $SND_RESOURCE = 0x00040004
Global Const $SND_ASYNC = 1

; Play the file - the script will pause as it sounds
DllCall("winmm.dll", "int", "PlaySound", "str", "MYWAV", "hwnd", 0, "int", $SND_RESOURCE)
; Play the file again, but this time the script continues
DllCall("winmm.dll", "int", "PlaySound", "str", "MYWAV", "hwnd", 0, "int", BitOR($SND_RESOURCE, $SND_ASYNC))

For $n = 1 To 100
    Sleep(15)
    ToolTip("Asynch! " & $n)
Next

Adding a string:

First create a file like this:

# string ID = WORD (16 bits):
# first 4 bits = string index in the block, 0-15
# top 12 bits = block ID - 1
# blocks must start at 1, so top 12 bits equal to 0 is block 1
#
# the section heading is the language to update
# be aware that AutoIt uses several string blocks in the UK language 2057 for built-in strings
#
[0]
0=first string in first block
1=second string in first block
15=last string in first block
32=first string in third block
33=second string in third block

[2057]
0=this is UK string 1
1=this is UK string 2

And save it as "test_rt_string.ini" in the same folder as the script.  You can then add it to the resources like this:

#AutoIt3Wrapper_Res_File_Add=test_rt_string.ini, RT_STRING

Adding a file:

Files are stored in the RT_RCDATA section and are usually stored byte for byte.  If the section value is set to -10 (RT_RCDATA is internally evaluated as 10) then the file is compressed before being added:

#AutoIt3Wrapper_Res_File_Add=file_name, RT_RCDATA     : UNCOMPRESSED
#AutoIt3Wrapper_Res_File_Add=file_name, 10            ; UNCOMPRESSED
#AutoIt3Wrapper_Res_File_Add=file_name, -10           ; COMPRESSED

When the file is required it can be extracted using this code. Set the $isCompressed parameter to match the Res_File_Add directive:

#include <WinAPIRes.au3>
#include <WinAPIInternals.au3>

Func _FileInstallFromResource($sResName, $sDest, $isCompressed = False, $iUncompressedSize = Default)
    Local $bBytes = _GetResourceAsBytes($sResName, $isCompressed, $iUncompressedSize)
    If @error Then Return SetError(@error, 0, 0)
    FileDelete($sDest)
    FileWrite($sDest, $bBytes)
EndFunc

Func _GetResourceAsBytes($sResName, $isCompressed = False, $iUncompressedSize = Default)

    Local $hMod = _WinAPI_GetModuleHandle(Null)
    Local $hRes = _WinAPI_FindResource($hMod, 10, $sResName)
    If @error Or Not $hRes Then Return SetError(1, 0, 0)
    Local $dSize = _WinAPI_SizeOfResource($hMod, $hRes)
    If @error Or Not $dSize Then Return SetError(2, 0, 0)
    Local $hLoad = _WinAPI_LoadResource($hMod, $hRes)
    If @error Or Not $hLoad Then Return SetError(3, 0, 0)
    Local $pData = _WinAPI_LockResource($hLoad)
    If @error Or Not $pData Then Return SetError(4, 0, 0)
    Local $tBuffer = DllStructCreate("byte[" & $dSize & "]")
    _WinAPI_MoveMemory(DllStructGetPtr($tBuffer), $pData, $dSize)
    If $isCompressed Then
        Local $oBuffer
       _WinAPI_LZNTDecompress($tBuffer, $oBuffer, $iUncompressedSize)
        If @error Then Return SetError(5, 0, 0)
        $tBuffer = $oBuffer
    EndIf
    Return DllStructGetData($tBuffer, 1)
EndFunc

Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iUncompressedSize = Default)
    ; if no uncompressed size given, use 16x the input buffer
    If $iUncompressedSize = Default Then $iUncompressedSize = 16 * DllStructGetSize($tInput)
    Local $tBuffer, $ret
    $tOutput = 0
    $tBuffer = DllStructCreate("byte[" & $iUncompressedSize & "]")
    If @error Then Return SetError(1, 0, 0)
    $ret = DllCall("ntdll.dll", "long", "RtlDecompressBuffer", "ushort", 2, "struct*", $tBuffer, "ulong", $iUncompressedSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0)
    If @error Then Return SetError(2, 0, 0)
    If $ret[0] Then Return SetError(3, $ret[0], 0)
    $tOutput = DllStructCreate("byte[" & $ret[6] & "]")
    If Not _WinAPI_MoveMemory(DllStructGetPtr($tOutput), DllStructGetPtr($tBuffer), $ret[6]) Then
        $tOutput = 0
        Return SetError(4, 0, 0)
    EndIf
    Return $ret[6]
EndFunc