Artem_Buero
Дата: Суббота, 07.06.2014, 10:21 | Сообщение # 1
Сообщений: 4223
Статус: Offline
В общем вряд-ли эта функция пригодится для каких-то разработках ,но функция довольно интересная. Вас код функции:
Код
GetIconFromResource(dest, source, idx) { ; info: http://msdn.microsoft.com/en-us/library/ms997538.aspx SetBatchLines, -1 if !hModule := Validation(dest, source, idx) Return for key, handle in FindGroup(source, idx, hModule) { pGroupInfo := GetResData(hModule, handle) if !IsObject(DataArray := CreateDataArray(hModule, pGroupInfo, CountIcons, size, idx ? idx : A_Index)) { if (DataArray = 6) continue else break } pData := CreateDataBuff(DataArray, pGroupInfo, CountIcons, size) res := Data2icoFile(pData, dest, size, idx) } until !res DllCall("FreeLibrary", Ptr, hModule) } Validation(dest, source, idx) { if !((idx + 1) > 0 && source := ValidateName(source)) Return static dwFlags := (LOAD_LIBRARY_AS_DATAFILE := 0x2 | LOAD_LIBRARY_AS_IMAGE_RESOURCE := 0x20) if !hModule := DllCall("LoadLibraryEx", Str, source, Ptr, 0, UInt, dwFlags, Ptr) Return, 0, DllCall("MessageBox", Ptr, 0, Str, "Невозможно загрузить указанный модуль!`nОшибка " A_LastError, Str, "", UInt, 0) Return hModule } ValidateName(FilePath) { SplitPath, FilePath,,, ext if !(ext ~= "i)exe|dll") && Error := "Допустимы только dll и exe файлы" Return, 0, DllCall("MessageBox", Ptr, 0, Str, Error, Str, "", UInt, 0) if !FileExist(FilePath) { EnvGet, PathVar, Path Loop, parse, PathVar, `; continue until FileExist(p := RTrim(A_LoopField, "\") . "\" . FilePath) && (FilePath := p) && found := 1 if !found && Text := "Файл " FilePath " не найден" Return, 0, DllCall("MessageBox", Ptr, 0, Str, Text, Str, "", UInt, 0) } Return FilePath } FindGroup(source, idx, hModule) { Names := [idx, 0] DllCall("EnumResourceNames", Ptr, hModule, UInt, RT_GROUP_ICON := 14 , Ptr, RegisterCallback("EnumGroupIconProc", "Fast", 4), Ptr, pNames := Object(Names)) ObjRelease(pNames) if (Names.3 = "") && Text := idx ? "Иконка " . idx . " в файле " . source . " не найдена" : "Иконки в файле " . source . " не найдены" Return, 0, DllCall("MessageBox", Ptr, 0, Str, Text, Str, "", UInt, 0) Names.Remove(1, 2) for i, Name in Names Names[i] := DllCall("FindResource", Ptr, hModule, Name + 1 ? "UInt" : "Str", Name, UInt, RT_GROUP_ICON, Ptr) Return Names } EnumGroupIconProc(hModule, Type, Name, lp) { (Name>>16) ? Name := LTrim(StrGet(Name+0), "#") obj := Object(lp) if !obj.1 obj.Insert(Name) else if ((obj.2 += 1) = obj.1) Return, 0, obj.3 := Name Return 1 } GetResData(hModule, hRes) { hData := DllCall("LoadResource", Ptr, hModule, Ptr, hRes, Ptr) Return DllCall("LockResource", Ptr, hData, Ptr) } CreateDataArray(hModule, pIconGroup, ByRef CountIcons, ByRef offset, idx) { if NumGet(pIconGroup+0, 2, "UShort") != 1 && Text := "Ресурс " Idx " неправильного типа. Возможно, файл сжат или зашифрован`nПродолжить?" Return DllCall("MessageBox", Ptr, 0, Str, Text, Str, "Неправильный ресурс", UInt, 4) DataArray := [], RT_ICON := 3 CountIcons := NumGet(pIconGroup+0, 4, "UShort") offset := 6 + CountIcons*16 Loop % CountIcons { id := NumGet(pIconGroup + 6 + 14*A_Index - 2, "UShort") hRes := DllCall("FindResource", Ptr, hModule, UInt, id, UInt, RT_ICON, Ptr) pIcon := GetResData(hModule, hRes) DataArray[A_Index] := {ptr: pIcon , size: s := NumGet(pIconGroup + 6 + 14*A_Index - 6, "UInt") , offset: offset} offset += s } Return DataArray } CreateDataBuff(DataArray, pIconGroup, CountIcons, size) { static IconData VarSetCapacity(IconData, size) DllCall("RtlMoveMemory", Ptr, &IconData, Ptr, pIconGroup, Ptr, 6) offset := 6 Loop % CountIcons { DllCall("RtlMoveMemory", Ptr, &IconData + offset, Ptr, pIconGroup + offset - 2*(A_Index - 1), Ptr, 12) NumPut(DataArray[A_Index].offset, &IconData + offset + 12, "UInt"), offset += 16 DllCall("RtlMoveMemory", Ptr, &IconData + DataArray[A_Index].offset, Ptr, DataArray[A_Index].ptr, Ptr, DataArray[A_Index].size) } Return &IconData } Data2icoFile(pData, Dest, size, idx) { static i = 0 SplitPath, Dest,, Dir, Ext, OutNameNoExt if !FileExist(Dir) { FileCreateDir, % Dir if ErrorLevel && Text := "Невозможно создать папку " Dir "`nОшибка " A_LastError Return, 0, DllCall("MessageBox", Ptr, 0, Str, Text, Str, "", UInt, 0) } (!idx) ? Dest := (Ext ? SubStr(Dest, 1, -(StrLen(Ext) + 1)) : Dest) . "(" . ++i . ")" . (Ext ? "." . Ext : "") if !(File := FileOpen(Dest, "w")) && Text := "Невозможно открыть файл " Dest "на запись`nОшибка " A_LastError Return, 0, DllCall("MessageBox", Ptr, 0, Str, Text, Str, "", UInt, 0) File.Seek(0), File.RawWrite(pData+0, size), File.Close() Return 1 }
Главное эта:GetIconFromResource(dest, source, idx) Теперь разберёмся: dest -Эта путь куда будет сохранена инока(иконки),если в пути указана папка которой нету то она будет создана. source -Эта ваш dll или exe idx -порядковый номер иконки Если вам надо основная иконка берите 1 Чтобы извлечь из ресурса все иконки за раз, передайте idx равный 0. В этом случае к имени файла, указанного в dest, будет добавлен порядковый номер каждой из иконок. Пример от автора: Код
GetIconFromResource(A_Desktop "\Icons\test.ico", "Shell32.dll", 0) ; извлекаем все иконки из Shell32.dll GetIconFromResource(A_Desktop "\Icons2\test.ico", "Shell32.dll", 45) ; извлекаем иконку с порядковым индексом 45 (счёт от 1) Return
Ещё пример: Код
GetIconFromResource(A_Desktop "/test.ico", "exe.exe", 0) Return
Автор:teadrinker
МОЙ ВК - https://vk.com/gospodin_buero