Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата assch:
интересно что за ошибка вылезает в этой функции »
Там должно быть описание ошибки. В любом случае это указывает на непредусмотреность числа элементов в масссиве.

Вот исправленная версия, ошибок не будет, но иконку не вытаскивает, мне кажется в этом случае можно использовать упрощонную версию, там всё ровно не заметно чёрного фона:

Код: Выделить весь код
#include-once
#include <GDIPlus.au3>
#include <WinAPI.au3>

Global $a__EN[1]

$sSrc = @DesktopDir & "\crack.exe"
$sDest = @DesktopDir & "\crack.ico"

$iRet = _FileExtractIcon($sSrc, -1, $sDest)
If @error Then _FileExtractIconSimple($sSrc, $sDest, -1)

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 $a__EN[0]
		If $i = StringReplace($iIcon, "-", "") Then
			$iGN = $a__EN[$i]
			ExitLoop
		EndIf
	Next
	Dim $a__EN[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

Func _FileExtractIconSimple($sSrcFileIcon, $sOutFileIcon, $iIndex = 0)
	Local $aRet, $hIcon, $pBitmapdll, $pBitmap
	
	If $iIndex < 0 Then
		$iIndex = ($iIndex * -1)
	EndIf
	
	$aRet = DllCall("shell32.dll", "long", "ExtractAssociatedIcon", "int", 0, "str", $sSrcFileIcon, "int*", $iIndex - 1)
	$hIcon = $aRet[0]
	
	_GDIPlus_Startup()
	
	$pBitmapdll = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromHICON", "ptr", $hIcon, "int*", 0)
	$pBitmap = $pBitmapdll[2]
	
	_WinAPI_DestroyIcon($hIcon)
	_GDIPlus_ImageSaveToFileEx($pBitmap, $sOutFileIcon, "{557CF400-1A04-11D3-9A73-0000F81EF32E}")
	_GDIPlus_ImageDispose($pBitmap)
	
	_GDIPlus_Shutdown()
	
	Return 1
Endfunc

; ========================================================================================================
; 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 $a__EN[UBound($a__EN) + 1]
		$a__EN[0] += 1
		$a__EN[UBound($a__EN) - 1] = DllStructGetData($tBuf, 1)
	Else
		ReDim $a__EN[UBound($a__EN) + 1]
		$a__EN[0] += 1
		$a__EN[UBound($a__EN) - 1] = "#" & $pName
	EndIf
	Return 1
EndFunc   ;==>__ResourceEnumNamesProc
и кстати как раз таки эту тему можно было продолжить обсуждать в первой, т.к оно напрямую связано.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 15:55, 23-07-2010 | #2