На протяжении всего проекта мы наблюдали иконки папок и чекбоксы, подгруженные в виде картинок с диска. Сейчас же я хочу загружать их из ресурсов. Если, например, делать свой компонент из цикла статей про DBTreeView, то без загрузки картинок из ресурсов не обойтись. Действительно, кинул компонент на форму, а в нём уже все есть. Но обо всём по порядку.
Итак, как же добиться такого результата? Как организовать загрузку картинок из ресурсов? Об этом мы и поговорим в данной статье. К счастью, сделать это не так сложно.
Начали!
Для начала, собственно, организуем сами картинки. 16*16 – форматы почти любые – загрузим их с помощью специального типа twicimage.
В нашем проекте добавим ресурсы через Project > Resources and Images
Здесь главное написать понятные идентификаторы ресурсов, так как будем возвращаться к ним.
Создадим отдельный датамодуль, в котором и будет происходить основная работа и добавим на него 2 imagelist
И напишем следующий код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
unit DMImageLists; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, Vcl.ExtCtrls, System.ImageList, Vcl.ImgList; type TDMImageList = class(TDataModule) ilFoldersAndFiles: TImageList; ilCheckBoxes: TImageList; procedure DataModuleCreate(Sender: TObject); private procedure AddToImageList(ImageList:TImageList; Res_id:PWideChar); procedure FillFilesAndFolders; procedure FillCheckBoxes; { Private declarations } public { Public declarations } end; var DMImageList: TDMImageList; implementation {%CLASSGROUP 'Vcl.Controls.TControl'} {$R *.dfm} { TDataModule1 } //--------------------------Вспомогательная процедура------------------------ procedure TDMImageList.AddToImageList(ImageList:TImageList; Res_id:PWideChar); var image:timage; rs:TResourceStream; twic:twicimage; bmp:tbitmap; begin // Создание bmp:=TBitmap.Create; twic:=twicimage.Create; if FindResource(0,Res_id,PChar(RT_RCDATA))<>0 then begin rs:=TResourceStream.Create(0,Res_id,PChar(RT_RCDATA)); twic.LoadFromStream(rs); bmp.Assign(twic); bmp.Height:=16; bmp.Width:=16; ImageList.Add(bmp,nil); end; //Уничтожение bmp.Free; twic.Free; rs.Free; end; //-----------------Создание DataModule procedure TDMImageList.DataModuleCreate(Sender: TObject); begin FillCheckBoxes; FillFilesAndFolders; end; //--------------Заполнение Image листов procedure TDMImageList.FillCheckBoxes; begin //Защита от повторного добавления if ilCheckBoxes.Count<>0 then exit; AddToImageList(ilCheckBoxes,'Unchecked_id'); AddToImageList(ilCheckBoxes,'Unchecked_id'); AddToImageList(ilCheckBoxes,'Checked_id'); end; procedure TDMImageList.FillFilesAndFolders; begin //Защита от повторного добавления if ilCheckBoxes.Count<>0 then exit; AddToImageList(ilCheckBoxes,'file_id'); AddToImageList(ilCheckBoxes,'FolderClosed_id'); AddToImageList(ilCheckBoxes,'FolderOpened_id'); end; end. |
Здесь всё относительно просто. Вспомогательная процедура добавляет в imagelist изображения 16*16. Она вызывается для заполнения соответствующих imagelist. В нашем случае их два – один для галочек, другой для папок и файлов.
В главном модуле – добавляем в Uses наш датамодуль работы с imageList,
1 2 |
uses DMImageLists |
Убираем его из Auto-Create в Project>Options>Forms
Объявляем глобальную переменную типа нашего датамодуля
1 |
DMImageList:TDMImageList; |
В FormCreate подключаем к TreeView
1 2 3 4 5 6 7 8 9 10 11 12 13 |
procedure TMainForm.FormCreate(Sender: TObject); begin DMImageList:=TDMImageList.Create(nil); TreeView1.StateImages:=DMImageList.ilCheckBoxes; TreeView1.Images:=DMImageList.ilFoldersAndFiles; end; |
В FormClose удаляем из памяти нашу переменную, так как она была глобальной
1 2 3 4 5 6 7 |
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin DMImageList.Free; end; |
В результате, что мы получили? При загрузке программы заполняются имэдж листы из ресурсов. Я не уверен до конца где они хранятся, но провел небольшой эксперимент. Добавил файл в 2 мб. в ресурсы и загружал его таким же образом в программу. В итоге EXE файл увеличился как раз на эти +2Мб.
В принципе, в Delphi работа с ресурсами построена очень грамотно! Если не считать небольшой возни с подбором картинок, то само программирование заняло не более 10 минут. Всё благодаря продуманной IDE RAD Studio.