В этом коде для примера взято расширение ".bat"
Функция "_WinAPI_AssocQueryString" с помощью других функций находит "Путь" и "Номер ресурса"
У меня это выглядит так:
Путь: C:\WINDOWS\System32\shell.dll
Индекс: -153
код работает так :
По рассширению (в данном случае ".bat") в окно выводится "Путь" и "Номер ресурса" а также
функцией "GUICtrlCreateIcon" выводится иконка взятая по этому адресу.
Для сравнения рядом с программой (лучше на рабочем столе)
появляется пустой файл ".bat" Дальше функция заточена так что с помощью функции "_FileExtractIcon"
она должна скопировать по этому адресу иконку в формате ".ico" и положить её там же и если иконка скопируется то она
появится в окне чуть правее первой иконки. Только как я понимаю функция "_FileExtractIcon"
не корректно работает с "Номером ресурса -153"
Она воспринимает его как индекс ну и как результат копируется иконка с "индексом -153" . А она совсем другая.
Не подскажете как исправить эту проблему
Функция "_WinAPI_AssocQueryString" с помощью других функций находит "Путь" и "Номер ресурса"
У меня это выглядит так:
Путь: C:\WINDOWS\System32\shell.dll
Индекс: -153
код работает так :
По рассширению (в данном случае ".bat") в окно выводится "Путь" и "Номер ресурса" а также
функцией "GUICtrlCreateIcon" выводится иконка взятая по этому адресу.
Для сравнения рядом с программой (лучше на рабочем столе)
появляется пустой файл ".bat" Дальше функция заточена так что с помощью функции "_FileExtractIcon"
она должна скопировать по этому адресу иконку в формате ".ico" и положить её там же и если иконка скопируется то она
появится в окне чуть правее первой иконки. Только как я понимаю функция "_FileExtractIcon"
не корректно работает с "Номером ресурса -153"
Она воспринимает его как индекс ну и как результат копируется иконка с "индексом -153" . А она совсем другая.
Не подскажете как исправить эту проблему
Код:
#Include <WinAPIEx.au3>
Global $aaa = "bat"
Global $bbb = "." & $aaa
Global $aSad[1]
$GUI = GUICreate($aaa, 400, 250, 100, 250)
$sIcon = _WinAPI_AssocQueryString($bbb, $ASSOCSTR_DEFAULTICON)
$aIcon = _WinAPI_PathParseIconLocation($sIcon)
$put = _WinAPI_PathUnquoteSpaces($aIcon[0])
$ind = $aIcon[1]
GUICtrlCreateLabel("Путь: " & $put,10, 150 ,380 ,40)
GUICtrlCreateLabel("Индекс: " & $ind ,10, 190 ,380 ,20)
GUICtrlCreateIcon($put,-($ind + ($ind > -1)), 100, 50, 48, 48)
GUISetState()
$file = FileOpen($bbb,2)
_FileExtractIcon($put,-($ind + ($ind > -1)), $aaa & ".ico")
GUICtrlCreateIcon($aaa & ".ico",0, 250, 50, 48, 48)
While 1
$iMsg = GUIGetMsg()
Switch $iMsg
Case -3
FileDelete ($bbb)
FileDelete ($aaa & ".ico")
Exit
EndSwitch
WEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func _FileExtractIcon($sInFile, $iIcon, $sOutIco, $iPath = 0)
Local Const $LOAD_LIBRARY_AS_DATAFILE = 0x00000002
Local Const $RT_ICON = 3
Local Const $RT_GROUP_ICON = 14
Local $hInst, $iGN = "", $sData, $sDByte, $sHdr, $aHdr, $iCnt, $Offset, $FO, $FW, $iCrt = 18
If $iPath = 1 Then $iCrt = 26 ;+8, to create directory structure
If Not FileExists($sInFile) Then Return SetError(1, 0, 0)
If Not IsInt($iIcon) Then Return SetError(2, 0, 0)
$hInst = _LoadLibraryEx($sInFile, $LOAD_LIBRARY_AS_DATAFILE)
If Not $hInst Then Return SetError(3, 0, 0)
_ResourceEnumNames($hInst, $RT_GROUP_ICON)
For $i = 1 To $aSad[0]
If $i = StringReplace($iIcon, "-", "") Then
$iGN = $aSad[$i]
ExitLoop
EndIf
Next
Dim $aSad[1]
If $iGN = "" Then
_FreeLibrary($hInst)
Return SetError(4, 0, 0)
EndIf
$sData = _GetIconResource($hInst, $iGN, $RT_GROUP_ICON)
If @error Then
_FreeLibrary($hInst)
Return SetError(5, 0, 0)
EndIf
$sHdr = BinaryMid($sData, 1, 6)
$aHdr = StringRegExp(StringTrimLeft(BinaryMid($sData, 7), 2), "(.{28})", 3)
$iCnt = UBound($aHdr)
$Offset = ($iCnt * 16) + 6
For $i = 0 To $iCnt - 1
$sDByte = Dec(_StringReverseBytes(StringMid($aHdr[$i], 17, 8)))
$sHdr &= StringTrimRight($aHdr[$i], 4) & _StringReverseBytes(Hex($Offset))
$Offset += $sDByte
Next
For $i = 0 To $iCnt - 1
$sData = _GetIconResource($hInst, "#" & Dec(_StringReverseBytes(StringRight($aHdr[$i], 4))), $RT_ICON)
If @error Then
_FreeLibrary($hInst)
Return SetError(6, 0, 0)
EndIf
$sHdr &= StringTrimLeft($sData, 2)
Next
_FreeLibrary($hInst)
$FO = FileOpen($sOutIco, $iCrt)
If $FO = -1 Then Return SetError(7, 0, 0)
$FW = FileWrite($FO, $sHdr)
If $FW = 0 Then
FileClose($FO)
Return SetError(8, 0, 0)
EndIf
FileClose($FO)
Return SetError(0, 0, 1)
EndFunc ;==>_FileExtractIcon
; ========================================================================================================
; Internal Helper Functions from this point on
; ========================================================================================================
Func _GetIconResource($hModule, $sResName, $iResType)
Local $hFind, $aSize, $hLoad, $hLock, $tRes, $sRet
$hFind = DllCall("kernel32.dll", "int", "FindResource", "int", $hModule, "str", $sResName, "long", $iResType)
If @error Or Not $hFind[0] Then Return SetError(1, 0, 0)
$aSize = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hModule, "int", $hFind[0])
If @error Or Not $aSize[0] Then Return SetError(2, 0, 0)
$hLoad = DllCall("kernel32.dll", "int", "LoadResource", "int", $hModule, "int", $hFind[0])
If @error Or Not $hLoad[0] Then Return SetError(3, 0, 0)
$hLock = DllCall("kernel32.dll", "int", "LockResource", "int", $hLoad[0])
If @error Or Not $hLock[0] Then
_FreeResource($hLoad[0])
Return SetError(4, 0, 0)
EndIf
$tRes = DllStructCreate("byte[" & $aSize[0] & "]", $hLock[0])
If Not IsDllStruct($tRes) Then
_FreeResource($hLoad[0])
Return SetError(5, 0, 0)
EndIf
$sRet = DllStructGetData($tRes, 1)
If $sRet = "" Then
_FreeResource($hLoad[0])
Return SetError(6, 0, 0)
EndIf
_FreeResource($hLoad[0])
Return $sRet
EndFunc ;==>_GetIconResource
Func _LoadLibraryEx($sFile, $iFlag)
Local $aRet = DllCall("Kernel32.dll", "hwnd", "LoadLibraryExW", "wstr", $sFile, "hwnd", 0, "int", $iFlag)
Return $aRet[0]
EndFunc ;==>_LoadLibraryEx
Func _FreeLibrary($hModule)
DllCall("Kernel32.dll", "hwnd", "FreeLibrary", "hwnd", $hModule)
EndFunc ;==>_FreeLibrary
Func _FreeResource($hglbResource)
DllCall("kernel32.dll", "int", "FreeResource", "int", $hglbResource)
EndFunc ;==>_FreeResource
; Just a Reverse string byte function (smashly style..lol)
Func _StringReverseBytes($sByte)
Local $aX = StringRegExp($sByte, "(.{2})", 3), $sX = ''
For $i = UBound($aX) - 1 To 0 Step -1
$sX &= $aX[$i]
Next
Return $sX
EndFunc ;==>_StringReverseBytes
Func _ResourceEnumNames($hModule, $iType)
Local $aRet, $xCB
If Not $hModule Then Return SetError(1, 0, 0)
$xCB = DllCallbackRegister('__ResourceEnumNamesProc', 'int', 'int_ptr;int_ptr;int_ptr;int_ptr')
$aRet = DllCall('kernel32.dll', 'int', 'EnumResourceNamesW', 'ptr', $hModule, 'int', $iType, 'ptr', DllCallbackGetPtr($xCB), 'ptr', 0)
DllCallbackFree($xCB)
If $aRet[0] <> 1 Then Return SetError(2, 0, 0)
Return SetError(0, 0, 1)
EndFunc ;==>_ResourceEnumNames
Func __ResourceEnumNamesProc($hModule, $pType, $pName, $lParam)
Local $aSize = DllCall('kernel32.dll', 'int', 'GlobalSize', 'ptr', $pName), $tBuf
If $aSize[0] Then
$tBuf = DllStructCreate('wchar[' & $aSize[0] & ']', $pName)
ReDim $aSad[UBound($aSad) + 1]
$aSad[0] += 1
$aSad[UBound($aSad) - 1] = DllStructGetData($tBuf, 1)
Else
ReDim $aSad[UBound($aSad) + 1]
$aSad[0] += 1
$aSad[UBound($aSad) - 1] = "#" & $pName
EndIf
Return 1
EndFunc ;==>__ResourceEnumNamesProc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;