How to get icon from a shortcut file ?
I have found that if you use a ListView component, to show a list of files in any
folder that contains shortcuts, then the shortcut icons do not appear correctly -
they do not show the true icon of the application to which they relate.
However, there is a a very useful feature of SHGetFileInfo, which is
SHGFI_LINKOVERLAY. This adds the shortcut "arrow", which is shown in the bottom
left corner of any shortcut icon. The demo code below shows the basic use of the
SHGFI_LINKOVERLAY feature. I have added code to this demo, to distingiush between
shortcut and non-shortcut files - without this code, it will overlay the shortcut
"arrow" irrespective of the file type.
To show the icon of a shortcut, the following code can be used as a demo:
1. Add the following components to a new project, and adjust their
properties according to the code below:
1
2 // Code for DFM file:
3
4 object Form1: TForm1
5 Left = 379
6 Top = 355
7 Width = 479
8 Height = 382
9 Caption = 'Get Icon from Shortcut File'
10 Color = clBtnFace
11 Font.Charset = DEFAULT_CHARSET
12 Font.Color = clWindowText
13 Font.Height = -11
14 Font.Name = 'MS Sans Serif'
15 Font.Style = []
16 OldCreateOrder = False
17 PixelsPerInch = 96
18 TextHeight = 13
19 object ListView: TListView
20 Left = 0
21 Top = 73
22 Width = 471
23 Height = 275
24 Align = alClient
25 Columns = <
26 item
27 Width = 100
28 end
29 item
30 Width = 100
31 end>
32 SmallImages = imgList
33 TabOrder = 0
34 ViewStyle = vsReport
35 end
36 object Panel: TPanel
37 Left = 0
38 Top = 0
39 Width = 471
40 Height = 73
41 Align = alTop
42 TabOrder = 1
43 object btnGetFile: TButton
44 Left = 16
45 Top = 8
46 Width = 75
47 Height = 25
48 Caption = 'Get file'
49 TabOrder = 0
50 OnClick = btnGetFileClick
51 end
52 object btnGetIcon: TButton
53 Left = 104
54 Top = 8
55 Width = 75
56 Height = 25
57 Caption = 'Get icon'
58 TabOrder = 1
59 OnClick = btnGetIconClick
60 end
61 object edFileName: TEdit
62 Left = 16
63 Top = 40
64 Width = 441
65 Height = 21
66 TabOrder = 2
67 end
68 end
69 object dlgOpen: TOpenDialog
70 Filter = 'Shortcut files|*.lnk|All files|*.*'
71 Options = [ofHideReadOnly, ofNoDereferenceLinks,
72 ofEnableSizing] // - this is important !
73 Left = 248
74 Top = 8
75 end
76 object imgList: TImageList
77 BlendColor = clWhite
78 BkColor = clWhite
79 Masked = False
80 ShareImages = True
81 Left = 216
82 Top = 8
83 end
84 end
85
86
87 // 2. Add the code to the PAS file below:
88
89 unit cdShortCutIcon;
90
91 interface
92
93 uses
94 SysUtils, Graphics, Forms, ShellAPI, Dialogs, ImgList,
95 Classes, ComCtrls, StdCtrls, ExtCtrls, Controls;
96
97 type
98 TForm1 = class(TForm)
99 dlgOpen: TOpenDialog;
100 ListView: TListView;
101 imgList: TImageList;
102 Panel: TPanel;
103 btnGetFile: TButton;
104 btnGetIcon: TButton;
105 edFileName: TEdit;
106 procedure btnGetFileClick(Sender: TObject);
107 procedure btnGetIconClick(Sender: TObject);
108 private
109 { Private declarations }
110 public
111 { Public declarations }
112 end;
113
114 var
115 Form1: TForm1;
116 Flags: Cardinal;
117
118 implementation
119
120 {$R *.dfm}
121
122 procedure TForm1.btnGetFileClick(Sender: TObject);
123 begin
124 { choose file to get icon from }
125 if dlgOpen.Execute then edFileName.Text := dlgOpen.FileName;
126 end;
127
128 procedure TForm1.btnGetIconClick(Sender: TObject);
129 var
130 Icon : TIcon;
131 ListItem : TListItem;
132 shInfo : TSHFileInfo;
133 sFileType : string;
134 begin
135 { initialise Flags for SHGetFileInfo }
136 Flags := SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SYSICONINDEX or SHGFI_TYPENAME;
137
138 { initialise ListView and Icon }
139 ListView.SmallImages := imgList;
140 Icon := TIcon.Create;
141
142 try
143 { Initialise ListView.Item.Add }
144 ListView.Items.BeginUpdate;
145 ListItem := listview.items.add;
146
147 { is this a shortcut file ? }
148 if ExtractFileExt(dlgOpen.FileName) = '.lnk' then
149 Flags := Flags or SHGFI_LINKOVERLAY else Flags := Flags;
150
151 { assign icon, adding shortcut overlay if appropriate; get details about file
152 type }
153 SHGetFileInfo(PChar(edFileName.Text), 0, shInfo, SizeOf(shInfo), Flags);
154 sFileType := shInfo.szTypeName;
155 Icon.Handle := shInfo.hIcon;
156
157 { List File name, Icon and FileType in ListView }
158 ListItem.Caption := ExtractFileName(edFileName.Text); { ...add filename... }
159 ListItem.SubItems.Add(sFileType); { ...and
160 filetype... }
161 ListItem.ImageIndex := imgList.AddIcon(Icon); { ...and icon. }
162 finally
163 {..free memory on icon and clean up.}
164 ListView.Items.EndUpdate;
165 sFileType := '';
166 Icon.Free;
167 end;
168 end;
169
170 end.
|