25.10.2002 Автор: Нижегородцев Сергей Как извлекать иконки из файлов exe или dll. Не так часто появляется необходимость извлекать иконки из каких-либо других программ, чтобы потом использовать их в своих программах. Но вот когда вдруг понадобилась именно эта иконка, что делать? Ну конечно можно через проводник найти файл с иконкой и просто тупо скопировать весь экран в буфер обмена нажатием клавиши “Print Screen”. Затем вставить содержимое буфера обмена в любом графическом редакторе (например Paint.exe, входящий в поставку Windows) и отредактировать экран таким образом, чтобы осталась одна иконка. В таком методе есть недостатки. Это невозможность использовать иконки из dll-файлов (они не отображаются в проводнике) и невозможность извлечения более одной иконки из exe-файла. К тому же зачем упрощать данную задачу, ведь мы же русские, зачем нам искать простые пути? J Я предлагаю вам простенькую программку, которую можно лишь слегка модифицировать получать ресурсы из любого файла ресурсов. Эта программа будет получать все иконки из указанного вами файла, и сохранять рисунки в bmp-файлы. Причем, все сохраняемые файлы будут иметь порядковые имена. Итак, что нам нужно:
Ну все, теперь можно приступить к программированию как таковому. Нам потребуется две API функции: ExtracIconA и DrawIcon. API–функция (Application Programming Interface) – это функция, входящая в операционную систему Windows. Подобные функции можно использовать практически в любом языке программирования под Windows будь то C++, Visual Basic, Delphi и т.д. Для использования вышеуказанных функций в нашей программе нужно их описать (или импортировать, как хотите называйте), нужно написать следующие строчки в модуле формы Form1: Private Declare Function ExtractIcon Lib "shell32.dll" Alias _ "ExtractIconA" (ByVal hInst As Long, _ ByVal lpszExeFileName As String, _ ByVal nIconIndex As Long) As Long Это первая функция, которая импортируется из shell32.dll. Эта функция будет извлекать из файла lpszExeFileName иконку по номеру (индексу) nIconIndex. Параметр hInst – это экземпляр программы, которая вызывает функцию. Функция возвращает дескриптор на иконку. Самое интересное, что мы еще раз будем использовать эту дллэльку. Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long, _ ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long Эта функция рисует иконку на элементе hdc. x и y это координаты верхнего левого угла с которого будет рисоваться иконка. Параметр hIcon – дескриптор иконки, который мы будем получать функцией ExtractIcon. В нашей форме Form1 надо написать обработчик события нажатия на кнопку с именем Command1. Для этого щелкните дважды на кнопке формы, и вы попадете в окно редактирования кода. Вставьте код: Dim hIcon As Long, i As Long Dim FilePath As String
i = 0 hIcon = -1 FilePath = "C:\Windows\System32\Shell32.dll" Picture1.BorderStyle = 0 Picture1.BackColor = vbWhite Picture1.Height = Screen.TwipsPerPixelY * 32 Picture1.Width = Screen.TwipsPerPixelY * 32 While hIcon <> 0 hIcon = ExtractIcon(App.hInstance, FilePath, i) Set Picture1.Picture = LoadPicture("") ' Clear the picture box Picture1.AutoRedraw = True '?enoai eeiieo Call DrawIcon(Picture1.hdc, 0, 0, hIcon) Picture1.AutoRedraw = False Picture1.Refresh SavePicture Picture1.Image, App.Path & "\Temp\" & i & ".bmp" i = i + 1 Wend Разберем его по порядку. Переменная hIcon это дескриптор иконки, которую мы будем извлекать. Переменная i – счетчик. Мы будем в цикле стараться извлечь все иконки начиная от 0 и до тех пор пока не hIcon не будет равна 0. Это будет означать, что функция ExtractIcon не может извлечь иконку с индексом i. Переменная FilePath = "C:\Windows\System32\Shell32.dll". Этот файл содержит огромное количество иконок, которые использует Windows, например в проводнике. Именно из этого файла мы будем извлекать иконки. Дальше мы делаем Picture1.BorderStyle = 0, что значит, что ободок нашего элемента не будет виден и, следовательно, не будет занимать место на форме. Именно поэтому мы сможем приравнять размеры большой стандартной иконки и компонент Picture1: Picture1.Height = Screen.TwipsPerPixelY * 32 Picture1.Width = Screen.TwipsPerPixelY * 32 Как вы может быть знаете, что стандартная величина измерения форм и компонент на экране у VB – это Twip (не понимаю, зачем ее придумали). А стандартная величина в Windows – это Pixel. Поэтому мы и конвертируем размер иконки в пикселах в размер иконки в твипах. Можно еще поменять фон компонента для того, чтобы белый фон компонента, был белым фоном для bmp-рисунка Picture1.BackColor = vbWhite Затем мы в цикле проверяем hIcon на соответствие 0, на каждом шаге увеличивая индекс иконки на 1 (i = i + 1). Так как мы заранее не знаем сколько иконок в файле-ресурсе, то как только функция ExtractIcon вернет 0, будем предполагать, что больше нет иконок с другими индексами. Перед тем, как используем функцию DrawIcon для рисования на Picture1, надо сделать Picture1.AutoRedraw = True чтобы включить автоматическое прорисовывание компоненте, как только изменится содержимое его памяти. После того как иконка нарисовалась выключим автопрорисовывание и обновим компонент Picture1.AutoRedraw = False Picture1.Refresh И наконец, запишем в файл все содержимое компонента Picture1 во временный каталог нашего проекта. SavePicture Picture1.Image, App.Path & "\Temp\" & i & ".bmp" После того как программа отработает, проверьте этот каталог. Желаю удачи! |