├── .editorconfig
├── .gitignore
├── IconExtractor.sln
├── IconExtractor
├── IconExtractor.cs
├── IconExtractor.csproj
├── IconUtil.cs
├── NativeMethods.cs
└── Properties
│ └── AssemblyInfo.cs
├── LICENSE.txt
├── README.md
└── SampleApp
├── Form1.Designer.cs
├── Form1.cs
├── Form1.resx
├── IconListView.cs
├── IconPickerDialog.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
└── Resources.resx
├── Resources
└── Checker.png
└── SampleApp.csproj
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Windows-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = crlf
9 | insert_final_newline = true
10 |
11 | # 4 space indentation
12 | [*.cs]
13 | indent_style = space
14 | indent_size = 4
15 |
16 | # Trim trailing whitespaces
17 | [*.cs]
18 | trim_trailing_whitespace = true
19 |
20 | # UTF-8 with BOM
21 | [*.cs]
22 | charset=utf-8-bom
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #OS junk files
2 | [Tt]humbs.db
3 | *.DS_Store
4 |
5 | #Visual Studio files
6 | *.[Oo]bj
7 | *.user
8 | *.aps
9 | *.pch
10 | *.vspscc
11 | *.vssscc
12 | *_i.c
13 | *_p.c
14 | *.ncb
15 | *.suo
16 | *.tlb
17 | *.tlh
18 | *.bak
19 | *.[Cc]ache
20 | *.ilk
21 | *.log
22 | *.sbr
23 | *.sdf
24 | *.opensdf
25 | *.unsuccessfulbuild
26 | ipch/
27 | obj/
28 | [Ll]ib
29 | [Bb]in
30 | [Dd]ebug*/
31 | [Rr]elease*/
32 | Ankh.NoLoad
33 |
--------------------------------------------------------------------------------
/IconExtractor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30723.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApp", "SampleApp\SampleApp.csproj", "{FE83EBBD-A7AD-4E7D-B0DF-2A13EF23D2B4}"
7 | ProjectSection(ProjectDependencies) = postProject
8 | {FDFD4EEB-C202-4D93-A6E9-D8984A12D014} = {FDFD4EEB-C202-4D93-A6E9-D8984A12D014}
9 | EndProjectSection
10 | EndProject
11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IconExtractor", "IconExtractor\IconExtractor.csproj", "{FDFD4EEB-C202-4D93-A6E9-D8984A12D014}"
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Release|Any CPU = Release|Any CPU
17 | EndGlobalSection
18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
19 | {FDFD4EEB-C202-4D93-A6E9-D8984A12D014}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {FDFD4EEB-C202-4D93-A6E9-D8984A12D014}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {FDFD4EEB-C202-4D93-A6E9-D8984A12D014}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {FDFD4EEB-C202-4D93-A6E9-D8984A12D014}.Release|Any CPU.Build.0 = Release|Any CPU
23 | {FE83EBBD-A7AD-4E7D-B0DF-2A13EF23D2B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {FE83EBBD-A7AD-4E7D-B0DF-2A13EF23D2B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {FE83EBBD-A7AD-4E7D-B0DF-2A13EF23D2B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {FE83EBBD-A7AD-4E7D-B0DF-2A13EF23D2B4}.Release|Any CPU.Build.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * IconExtractor/IconUtil for .NET
3 | * Copyright (C) 2014 Tsuda Kageyu. All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | *
9 | * 1. Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * 2. Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
19 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | using System;
29 | using System.Collections.Generic;
30 | using System.ComponentModel;
31 | using System.Drawing;
32 | using System.IO;
33 | using System.Runtime.InteropServices;
34 | using System.Text;
35 |
36 | namespace TsudaKageyu
37 | {
38 | public class IconExtractor
39 | {
40 | ////////////////////////////////////////////////////////////////////////
41 | // Constants
42 |
43 | // Flags for LoadLibraryEx().
44 |
45 | private const uint LOAD_LIBRARY_AS_DATAFILE = 0x00000002;
46 |
47 | // Resource types for EnumResourceNames().
48 |
49 | private readonly static IntPtr RT_ICON = (IntPtr)3;
50 | private readonly static IntPtr RT_GROUP_ICON = (IntPtr)14;
51 |
52 | private const int MAX_PATH = 260;
53 |
54 | ////////////////////////////////////////////////////////////////////////
55 | // Fields
56 |
57 | private byte[][] iconData = null; // Binary data of each icon.
58 |
59 | ////////////////////////////////////////////////////////////////////////
60 | // Public properties
61 |
62 | ///
63 | /// Gets the full path of the associated file.
64 | ///
65 | public string FileName
66 | {
67 | get;
68 | private set;
69 | }
70 |
71 | ///
72 | /// Gets the count of the icons in the associated file.
73 | ///
74 | public int Count
75 | {
76 | get { return iconData.Length; }
77 | }
78 |
79 | ///
80 | /// Initializes a new instance of the IconExtractor class from the specified file name.
81 | ///
82 | /// The file to extract icons from.
83 | public IconExtractor(string fileName)
84 | {
85 | Initialize(fileName);
86 | }
87 |
88 | ///
89 | /// Extracts an icon from the file.
90 | ///
91 | /// Zero based index of the icon to be extracted.
92 | /// A System.Drawing.Icon object.
93 | /// Always returns new copy of the Icon. It should be disposed by the user.
94 | public Icon GetIcon(int index)
95 | {
96 | if (index < 0 || Count <= index)
97 | throw new ArgumentOutOfRangeException("index");
98 |
99 | // Create an Icon from the .ico file in memory.
100 |
101 | using (var ms = new MemoryStream(iconData[index]))
102 | {
103 | return new Icon(ms);
104 | }
105 | }
106 |
107 | ///
108 | /// Extracts all the icons from the file.
109 | ///
110 | /// An array of System.Drawing.Icon objects.
111 | /// Always returns new copies of the Icons. They should be disposed by the user.
112 | public Icon[] GetAllIcons()
113 | {
114 | var icons = new List();
115 | for (int i = 0; i < Count; ++i)
116 | icons.Add(GetIcon(i));
117 |
118 | return icons.ToArray();
119 | }
120 |
121 | ///
122 | /// Save an icon to the specified output Stream.
123 | ///
124 | /// Zero based index of the icon to be saved.
125 | /// The Stream to save to.
126 | public void Save(int index, Stream outputStream)
127 | {
128 | if (index < 0 || Count <= index)
129 | throw new ArgumentOutOfRangeException("index");
130 |
131 | if (outputStream == null)
132 | throw new ArgumentNullException("outputStream");
133 |
134 | var data = iconData[index];
135 | outputStream.Write(data, 0, data.Length);
136 | }
137 |
138 | private void Initialize(string fileName)
139 | {
140 | if (fileName == null)
141 | throw new ArgumentNullException("fileName");
142 |
143 | IntPtr hModule = IntPtr.Zero;
144 | try
145 | {
146 | hModule = NativeMethods.LoadLibraryEx(fileName, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE);
147 | if (hModule == IntPtr.Zero)
148 | throw new Win32Exception();
149 |
150 | FileName = GetFileName(hModule);
151 |
152 | // Enumerate the icon resource and build .ico files in memory.
153 |
154 | var tmpData = new List();
155 |
156 | ENUMRESNAMEPROC callback = (h, t, name, l) =>
157 | {
158 | // Refer to the following URL for the data structures used here:
159 | // http://msdn.microsoft.com/en-us/library/ms997538.aspx
160 |
161 | // RT_GROUP_ICON resource consists of a GRPICONDIR and GRPICONDIRENTRY's.
162 |
163 | var dir = GetDataFromResource(hModule, RT_GROUP_ICON, name);
164 |
165 | // Calculate the size of an entire .icon file.
166 |
167 | int count = BitConverter.ToUInt16(dir, 4); // GRPICONDIR.idCount
168 | int len = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
169 | for (int i = 0; i < count; ++i)
170 | len += BitConverter.ToInt32(dir, 6 + 14 * i + 8); // GRPICONDIRENTRY.dwBytesInRes
171 |
172 | using (var dst = new BinaryWriter(new MemoryStream(len)))
173 | {
174 | // Copy GRPICONDIR to ICONDIR.
175 |
176 | dst.Write(dir, 0, 6);
177 |
178 | int picOffset = 6 + 16 * count; // sizeof(ICONDIR) + sizeof(ICONDIRENTRY) * count
179 |
180 | for (int i = 0; i < count; ++i)
181 | {
182 | // Load the picture.
183 |
184 | ushort id = BitConverter.ToUInt16(dir, 6 + 14 * i + 12); // GRPICONDIRENTRY.nID
185 | var pic = GetDataFromResource(hModule, RT_ICON, (IntPtr)id);
186 |
187 | // Copy GRPICONDIRENTRY to ICONDIRENTRY.
188 |
189 | dst.Seek(6 + 16 * i, SeekOrigin.Begin);
190 |
191 | dst.Write(dir, 6 + 14 * i, 8); // First 8bytes are identical.
192 | dst.Write(pic.Length); // ICONDIRENTRY.dwBytesInRes
193 | dst.Write(picOffset); // ICONDIRENTRY.dwImageOffset
194 |
195 | // Copy a picture.
196 |
197 | dst.Seek(picOffset, SeekOrigin.Begin);
198 | dst.Write(pic, 0, pic.Length);
199 |
200 | picOffset += pic.Length;
201 | }
202 |
203 | tmpData.Add(((MemoryStream)dst.BaseStream).ToArray());
204 | }
205 |
206 | return true;
207 | };
208 | NativeMethods.EnumResourceNames(hModule, RT_GROUP_ICON, callback, IntPtr.Zero);
209 |
210 | iconData = tmpData.ToArray();
211 | }
212 | finally
213 | {
214 | if (hModule != IntPtr.Zero)
215 | NativeMethods.FreeLibrary(hModule);
216 | }
217 | }
218 |
219 | private byte[] GetDataFromResource(IntPtr hModule, IntPtr type, IntPtr name)
220 | {
221 | // Load the binary data from the specified resource.
222 |
223 | IntPtr hResInfo = NativeMethods.FindResource(hModule, name, type);
224 | if (hResInfo == IntPtr.Zero)
225 | throw new Win32Exception();
226 |
227 | IntPtr hResData = NativeMethods.LoadResource(hModule, hResInfo);
228 | if (hResData == IntPtr.Zero)
229 | throw new Win32Exception();
230 |
231 | IntPtr pResData = NativeMethods.LockResource(hResData);
232 | if (pResData == IntPtr.Zero)
233 | throw new Win32Exception();
234 |
235 | uint size = NativeMethods.SizeofResource(hModule, hResInfo);
236 | if (size == 0)
237 | throw new Win32Exception();
238 |
239 | byte[] buf = new byte[size];
240 | Marshal.Copy(pResData, buf, 0, buf.Length);
241 |
242 | return buf;
243 | }
244 |
245 | private string GetFileName(IntPtr hModule)
246 | {
247 | // Alternative to GetModuleFileName() for the module loaded with
248 | // LOAD_LIBRARY_AS_DATAFILE option.
249 |
250 | // Get the file name in the format like:
251 | // "\\Device\\HarddiskVolume2\\Windows\\System32\\shell32.dll"
252 |
253 | string fileName;
254 | {
255 | var buf = new StringBuilder(MAX_PATH);
256 | int len = NativeMethods.GetMappedFileName(
257 | NativeMethods.GetCurrentProcess(), hModule, buf, buf.Capacity);
258 | if (len == 0)
259 | throw new Win32Exception();
260 |
261 | fileName = buf.ToString();
262 | }
263 |
264 | // Convert the device name to drive name like:
265 | // "C:\\Windows\\System32\\shell32.dll"
266 |
267 | for (char c = 'A'; c <= 'Z'; ++c)
268 | {
269 | var drive = c + ":";
270 | var buf = new StringBuilder(MAX_PATH);
271 | int len = NativeMethods.QueryDosDevice(drive, buf, buf.Capacity);
272 | if (len == 0)
273 | continue;
274 |
275 | var devPath = buf.ToString();
276 | if (fileName.StartsWith(devPath))
277 | return (drive + fileName.Substring(devPath.Length));
278 | }
279 |
280 | return fileName;
281 | }
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/IconExtractor/IconExtractor.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FDFD4EEB-C202-4D93-A6E9-D8984A12D014}
8 | Library
9 | Properties
10 | IconExtractor
11 | IconExtractor
12 | v2.0
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
51 |
--------------------------------------------------------------------------------
/IconExtractor/IconUtil.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * IconExtractor/IconUtil for .NET
3 | * Copyright (C) 2014 Tsuda Kageyu. All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | *
9 | * 1. Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * 2. Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
19 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | using System;
29 | using System.Collections.Generic;
30 | using System.Drawing;
31 | using System.IO;
32 | using System.Reflection;
33 | using System.Reflection.Emit;
34 |
35 | namespace TsudaKageyu
36 | {
37 | public static class IconUtil
38 | {
39 | private delegate byte[] GetIconDataDelegate(Icon icon);
40 |
41 | static GetIconDataDelegate getIconData;
42 |
43 | static IconUtil()
44 | {
45 | // Create a dynamic method to access Icon.iconData private field.
46 |
47 | var dm = new DynamicMethod(
48 | "GetIconData", typeof(byte[]), new Type[] { typeof(Icon) }, typeof(Icon));
49 | var fi = typeof(Icon).GetField(
50 | "iconData", BindingFlags.Instance | BindingFlags.NonPublic);
51 | var gen = dm.GetILGenerator();
52 | gen.Emit(OpCodes.Ldarg_0);
53 | gen.Emit(OpCodes.Ldfld, fi);
54 | gen.Emit(OpCodes.Ret);
55 |
56 | getIconData = (GetIconDataDelegate)dm.CreateDelegate(typeof(GetIconDataDelegate));
57 | }
58 |
59 | ///
60 | /// Split an Icon consists of multiple icons into an array of Icon each
61 | /// consists of single icons.
62 | ///
63 | /// A System.Drawing.Icon to be split.
64 | /// An array of System.Drawing.Icon.
65 | public static Icon[] Split(Icon icon)
66 | {
67 | if (icon == null)
68 | throw new ArgumentNullException("icon");
69 |
70 | // Get an .ico file in memory, then split it into separate icons.
71 |
72 | var src = GetIconData(icon);
73 |
74 | var splitIcons = new List();
75 | {
76 | int count = BitConverter.ToUInt16(src, 4);
77 |
78 | for (int i = 0; i < count; i++)
79 | {
80 | int length = BitConverter.ToInt32(src, 6 + 16 * i + 8); // ICONDIRENTRY.dwBytesInRes
81 | int offset = BitConverter.ToInt32(src, 6 + 16 * i + 12); // ICONDIRENTRY.dwImageOffset
82 |
83 | using (var dst = new BinaryWriter(new MemoryStream(6 + 16 + length)))
84 | {
85 | // Copy ICONDIR and set idCount to 1.
86 |
87 | dst.Write(src, 0, 4);
88 | dst.Write((short)1);
89 |
90 | // Copy ICONDIRENTRY and set dwImageOffset to 22.
91 |
92 | dst.Write(src, 6 + 16 * i, 12); // ICONDIRENTRY except dwImageOffset
93 | dst.Write(22); // ICONDIRENTRY.dwImageOffset
94 |
95 | // Copy a picture.
96 |
97 | dst.Write(src, offset, length);
98 |
99 | // Create an icon from the in-memory file.
100 |
101 | dst.BaseStream.Seek(0, SeekOrigin.Begin);
102 | splitIcons.Add(new Icon(dst.BaseStream));
103 | }
104 | }
105 | }
106 |
107 | return splitIcons.ToArray();
108 | }
109 |
110 | ///
111 | /// Converts an Icon to a GDI+ Bitmap preserving the transparent area.
112 | ///
113 | /// An System.Drawing.Icon to be converted.
114 | /// A System.Drawing.Bitmap Object.
115 | public static Bitmap ToBitmap(Icon icon)
116 | {
117 | if (icon == null)
118 | throw new ArgumentNullException("icon");
119 |
120 | // Quick workaround: Create an .ico file in memory, then load it as a Bitmap.
121 |
122 | using (var ms = new MemoryStream())
123 | {
124 | icon.Save(ms);
125 | using (var bmp = (Bitmap)Image.FromStream(ms))
126 | {
127 | return new Bitmap(bmp);
128 | }
129 | }
130 | }
131 |
132 | ///
133 | /// Gets the bit depth of an Icon.
134 | ///
135 | /// An System.Drawing.Icon object.
136 | /// Bit depth of the icon.
137 | ///
138 | /// This method takes into account the PNG header.
139 | /// If the icon has multiple variations, this method returns the bit
140 | /// depth of the first variation.
141 | ///
142 | public static int GetBitCount(Icon icon)
143 | {
144 | if (icon == null)
145 | throw new ArgumentNullException("icon");
146 |
147 | // Get an .ico file in memory, then read the header.
148 |
149 | var data = GetIconData(icon);
150 | if (data.Length >= 51
151 | && data[22] == 0x89 && data[23] == 0x50 && data[24] == 0x4e && data[25] == 0x47
152 | && data[26] == 0x0d && data[27] == 0x0a && data[28] == 0x1a && data[29] == 0x0a
153 | && data[30] == 0x00 && data[31] == 0x00 && data[32] == 0x00 && data[33] == 0x0d
154 | && data[34] == 0x49 && data[35] == 0x48 && data[36] == 0x44 && data[37] == 0x52)
155 | {
156 | // The picture is PNG. Read IHDR chunk.
157 |
158 | switch (data[47])
159 | {
160 | case 0:
161 | return data[46];
162 | case 2:
163 | return data[46] * 3;
164 | case 3:
165 | return data[46];
166 | case 4:
167 | return data[46] * 2;
168 | case 6:
169 | return data[46] * 4;
170 | default:
171 | // NOP
172 | break;
173 | }
174 | }
175 | else if (data.Length >= 22)
176 | {
177 | // The picture is not PNG. Read ICONDIRENTRY structure.
178 |
179 | return BitConverter.ToUInt16(data, 12);
180 | }
181 |
182 | throw new ArgumentException("The icon is corrupt. Couldn't read the header.", "icon");
183 | }
184 |
185 | private static byte[] GetIconData(Icon icon)
186 | {
187 | var data = getIconData(icon);
188 | if (data != null)
189 | {
190 | return data;
191 | }
192 | else
193 | {
194 | using (var ms = new MemoryStream())
195 | {
196 | icon.Save(ms);
197 | return ms.ToArray();
198 | }
199 | }
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/IconExtractor/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * IconExtractor/IconUtil for .NET
3 | * Copyright (C) 2014 Tsuda Kageyu. All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions
7 | * are met:
8 | *
9 | * 1. Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * 2. Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
19 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | using System;
29 | using System.Runtime.InteropServices;
30 | using System.Security;
31 | using System.Text;
32 |
33 | namespace TsudaKageyu
34 | {
35 | internal static class NativeMethods
36 | {
37 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
38 | [SuppressUnmanagedCodeSecurity]
39 | public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
40 |
41 | [DllImport("kernel32.dll", SetLastError = true)]
42 | [SuppressUnmanagedCodeSecurity]
43 | public static extern bool FreeLibrary(IntPtr hModule);
44 |
45 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
46 | [SuppressUnmanagedCodeSecurity]
47 | public static extern bool EnumResourceNames(IntPtr hModule, IntPtr lpszType, ENUMRESNAMEPROC lpEnumFunc, IntPtr lParam);
48 |
49 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
50 | [SuppressUnmanagedCodeSecurity]
51 | public static extern IntPtr FindResource(IntPtr hModule, IntPtr lpName, IntPtr lpType);
52 |
53 | [DllImport("kernel32.dll", SetLastError = true)]
54 | [SuppressUnmanagedCodeSecurity]
55 | public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
56 |
57 | [DllImport("kernel32.dll", SetLastError = true)]
58 | [SuppressUnmanagedCodeSecurity]
59 | public static extern IntPtr LockResource(IntPtr hResData);
60 |
61 | [DllImport("kernel32.dll", SetLastError = true)]
62 | [SuppressUnmanagedCodeSecurity]
63 | public static extern uint SizeofResource(IntPtr hModule, IntPtr hResInfo);
64 |
65 | [DllImport("kernel32.dll", SetLastError = true)]
66 | [SuppressUnmanagedCodeSecurity]
67 | public static extern IntPtr GetCurrentProcess();
68 |
69 | [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
70 | [SuppressUnmanagedCodeSecurity]
71 | public static extern int QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
72 |
73 | [DllImport("psapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
74 | [SuppressUnmanagedCodeSecurity]
75 | public static extern int GetMappedFileName(IntPtr hProcess, IntPtr lpv, StringBuilder lpFilename, int nSize);
76 | }
77 |
78 | [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true, CharSet = CharSet.Unicode)]
79 | [SuppressUnmanagedCodeSecurity]
80 | internal delegate bool ENUMRESNAMEPROC(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam);
81 | }
82 |
--------------------------------------------------------------------------------
/IconExtractor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("IconExtractor.dll")]
9 | [assembly: AssemblyDescription("IconExtractor.dll")]
10 | [assembly: AssemblyCompany("Tsuda Kageyu")]
11 | [assembly: AssemblyProduct("IconExtractor/IconUtil Library for .NET")]
12 | [assembly: AssemblyCopyright("Copyright © 2014 Tsuda Kageyu. All rights reserved")]
13 |
14 | // Setting ComVisible to false makes the types in this assembly not visible
15 | // to COM components. If you need to access a type in this assembly from
16 | // COM, set the ComVisible attribute to true on that type.
17 | [assembly: ComVisible(false)]
18 |
19 | // The following GUID is for the ID of the typelib if this project is exposed to COM
20 | [assembly: Guid("57d89f12-2dc2-4a21-87c2-990c0a928a05")]
21 |
22 | // Version information for an assembly consists of the following four values:
23 | //
24 | // Major Version
25 | // Minor Version
26 | // Build Number
27 | // Revision
28 | //
29 | // You can specify all the values or you can default the Build and Revision Numbers
30 | // by using the '*' as shown below:
31 | // [assembly: AssemblyVersion("1.0.*")]
32 | [assembly: AssemblyVersion("1.0.0.0")]
33 | [assembly: AssemblyFileVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | IconExtractor/IconUtil for .NET
2 | Copyright (C) 2014 Tsuda Kageyu. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
18 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IconExtractor
2 |
3 | Icon Extractor Library for .NET
4 |
5 | http://www.codeproject.com/Articles/26824/Extract-icons-from-EXE-or-DLL-files
6 |
7 |
8 | Extract all the variations of an icon from .DLL/.EXE, including the ones ```ExtractIconEx()``` can't extract.
9 |
10 | ### Usage
11 |
12 | First, add a reference to ```IconExtractor.dll``` to your .NET project. Then...
13 |
14 | ```
15 | using System;
16 | using System.Drawing;
17 | using TsudaKageyu;
18 |
19 | // -----------------------------------------------------------------------------
20 | // Usage of IconExtractor class:
21 |
22 | // Construct an IconExtractor object with a file.
23 |
24 | IconExtractor ie = new IconExtractor(@"D:\sample.exe");
25 |
26 | // Get the full name of the associated file.
27 |
28 | string fileName = ie.FileName;
29 |
30 | // Get the count of icons in the associated file.
31 |
32 | int iconCount = ie.Count;
33 |
34 | // Extract icons individually.
35 |
36 | Icon icon0 = ie.GetIcon(0);
37 | Icon icon1 = ie.GetIcon(1);
38 |
39 | // Save icons individually.
40 |
41 | using (var fs = File.OpenWrite(@"D:\sample0.ico"))
42 | {
43 | ie.Save(0, fs);
44 | }
45 |
46 | // Extract all the icons in one go.
47 |
48 | Icon[] allIcons = ie.GetAllIcons();
49 |
50 | // -----------------------------------------------------------------------------
51 | // Usage of IconUtil class:
52 |
53 | // Split the variations of icon0 into separate icon objects.
54 |
55 | Icon[] splitIcons = IconUtil.SplitIcon(icon0);
56 |
57 | // Convert an icon into bitmap. Unlike Icon.ToBitmap() it preserves the transparency.
58 |
59 | Bitmap bitmap = IconUtil.ToBitmap(splitIcon[1]);
60 |
61 | // Get the bit count of an icon.
62 |
63 | int bitCount = IconUtil.GetBitCount(splitIcon[2]);
64 | ```
65 |
--------------------------------------------------------------------------------
/SampleApp/Form1.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace SampleApp
2 | {
3 | partial class Form1
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.txtFileName = new System.Windows.Forms.TextBox();
32 | this.btnSelectIcon = new System.Windows.Forms.Button();
33 | this.lvwIcons = new SampleApp.IconListView();
34 | this.btnSaveAsIco = new System.Windows.Forms.Button();
35 | this.saveIcoDialog = new System.Windows.Forms.SaveFileDialog();
36 | this.btnSaveAsPng = new System.Windows.Forms.Button();
37 | this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
38 | this.cbShowChecker = new System.Windows.Forms.CheckBox();
39 | this.iconPickerDialog = new SampleApp.IconPickerDialog();
40 | this.SuspendLayout();
41 | //
42 | // txtFileName
43 | //
44 | this.txtFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
45 | | System.Windows.Forms.AnchorStyles.Right)));
46 | this.txtFileName.Location = new System.Drawing.Point(110, 12);
47 | this.txtFileName.Name = "txtFileName";
48 | this.txtFileName.ReadOnly = true;
49 | this.txtFileName.Size = new System.Drawing.Size(370, 19);
50 | this.txtFileName.TabIndex = 1;
51 | //
52 | // btnSelectIcon
53 | //
54 | this.btnSelectIcon.Location = new System.Drawing.Point(12, 12);
55 | this.btnSelectIcon.Name = "btnSelectIcon";
56 | this.btnSelectIcon.Size = new System.Drawing.Size(92, 19);
57 | this.btnSelectIcon.TabIndex = 0;
58 | this.btnSelectIcon.Text = "Select Icon...";
59 | this.btnSelectIcon.UseVisualStyleBackColor = true;
60 | this.btnSelectIcon.Click += new System.EventHandler(this.btnPickFile_Click);
61 | //
62 | // lvwIcons
63 | //
64 | this.lvwIcons.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
65 | | System.Windows.Forms.AnchorStyles.Left)
66 | | System.Windows.Forms.AnchorStyles.Right)));
67 | this.lvwIcons.BackgroundImageTiled = true;
68 | this.lvwIcons.Location = new System.Drawing.Point(12, 37);
69 | this.lvwIcons.MultiSelect = false;
70 | this.lvwIcons.Name = "lvwIcons";
71 | this.lvwIcons.Size = new System.Drawing.Size(468, 291);
72 | this.lvwIcons.TabIndex = 2;
73 | this.lvwIcons.TileSize = new System.Drawing.Size(132, 130);
74 | this.lvwIcons.UseCompatibleStateImageBehavior = false;
75 | this.lvwIcons.View = System.Windows.Forms.View.Tile;
76 | //
77 | // btnSaveAsIco
78 | //
79 | this.btnSaveAsIco.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
80 | this.btnSaveAsIco.Location = new System.Drawing.Point(164, 334);
81 | this.btnSaveAsIco.Name = "btnSaveAsIco";
82 | this.btnSaveAsIco.Size = new System.Drawing.Size(155, 23);
83 | this.btnSaveAsIco.TabIndex = 4;
84 | this.btnSaveAsIco.Text = "Save as Single .ico...";
85 | this.btnSaveAsIco.UseVisualStyleBackColor = true;
86 | this.btnSaveAsIco.Click += new System.EventHandler(this.btnSaveAsIco_Click);
87 | //
88 | // saveIcoDialog
89 | //
90 | this.saveIcoDialog.Filter = "Icon files|*.ico";
91 | //
92 | // btnSaveAsPng
93 | //
94 | this.btnSaveAsPng.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
95 | this.btnSaveAsPng.Location = new System.Drawing.Point(325, 334);
96 | this.btnSaveAsPng.Name = "btnSaveAsPng";
97 | this.btnSaveAsPng.Size = new System.Drawing.Size(155, 23);
98 | this.btnSaveAsPng.TabIndex = 5;
99 | this.btnSaveAsPng.Text = "Save as Multiple .png...";
100 | this.btnSaveAsPng.UseVisualStyleBackColor = true;
101 | this.btnSaveAsPng.Click += new System.EventHandler(this.btnSaveAsPng_Click);
102 | //
103 | // cbShowChecker
104 | //
105 | this.cbShowChecker.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
106 | this.cbShowChecker.AutoSize = true;
107 | this.cbShowChecker.Location = new System.Drawing.Point(12, 338);
108 | this.cbShowChecker.Name = "cbShowChecker";
109 | this.cbShowChecker.Size = new System.Drawing.Size(97, 16);
110 | this.cbShowChecker.TabIndex = 3;
111 | this.cbShowChecker.Text = "Show Checker";
112 | this.cbShowChecker.UseVisualStyleBackColor = true;
113 | this.cbShowChecker.CheckedChanged += new System.EventHandler(this.cbShowChecker_CheckedChanged);
114 | //
115 | // Form1
116 | //
117 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
118 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
119 | this.ClientSize = new System.Drawing.Size(492, 369);
120 | this.Controls.Add(this.cbShowChecker);
121 | this.Controls.Add(this.btnSaveAsPng);
122 | this.Controls.Add(this.btnSaveAsIco);
123 | this.Controls.Add(this.lvwIcons);
124 | this.Controls.Add(this.btnSelectIcon);
125 | this.Controls.Add(this.txtFileName);
126 | this.MinimumSize = new System.Drawing.Size(500, 400);
127 | this.Name = "Form1";
128 | this.Text = "IconExtractor Sample App";
129 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
130 | this.ResumeLayout(false);
131 | this.PerformLayout();
132 |
133 | }
134 |
135 | #endregion
136 |
137 | private IconPickerDialog iconPickerDialog;
138 | private System.Windows.Forms.TextBox txtFileName;
139 | private System.Windows.Forms.Button btnSelectIcon;
140 | private SampleApp.IconListView lvwIcons;
141 | private System.Windows.Forms.Button btnSaveAsIco;
142 | private System.Windows.Forms.SaveFileDialog saveIcoDialog;
143 | private System.Windows.Forms.Button btnSaveAsPng;
144 | private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog;
145 | private System.Windows.Forms.CheckBox cbShowChecker;
146 | }
147 | }
148 |
149 |
--------------------------------------------------------------------------------
/SampleApp/Form1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Drawing2D;
4 | using System.IO;
5 | using System.Windows.Forms;
6 | using TsudaKageyu;
7 |
8 | namespace SampleApp
9 | {
10 | public partial class Form1 : Form
11 | {
12 | IconExtractor m_iconExtractor = null;
13 | int m_iconIndex = 0;
14 |
15 | public Form1()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void ClearAllIcons()
21 | {
22 | foreach (var item in lvwIcons.Items)
23 | ((IconListViewItem)item).Bitmap.Dispose();
24 |
25 | lvwIcons.Items.Clear();
26 | }
27 |
28 | private void Form1_FormClosing(object sender, FormClosingEventArgs e)
29 | {
30 | ClearAllIcons();
31 | }
32 |
33 | private void btnPickFile_Click(object sender, EventArgs e)
34 | {
35 | var result = iconPickerDialog.ShowDialog(this);
36 | if (result == DialogResult.OK)
37 | {
38 | var fileName = iconPickerDialog.FileName;
39 | m_iconIndex = iconPickerDialog.IconIndex;
40 |
41 | Icon icon = null;
42 | Icon[] splitIcons = null;
43 | try
44 | {
45 | if (Path.GetExtension(iconPickerDialog.FileName).ToLower() == ".ico")
46 | {
47 | m_iconExtractor = null;
48 | icon = new Icon(iconPickerDialog.FileName);
49 | }
50 | else
51 | {
52 | m_iconExtractor = new IconExtractor(fileName);
53 | icon = m_iconExtractor.GetIcon(m_iconIndex);
54 | }
55 |
56 | splitIcons = IconUtil.Split(icon);
57 | }
58 | catch (Exception ex)
59 | {
60 | MessageBox.Show(ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
61 | return;
62 | }
63 |
64 | txtFileName.Text = String.Format(
65 | "{0}, #{1}, {2} variations", fileName, m_iconIndex, splitIcons.Length);
66 |
67 | // Update icons.
68 |
69 | Icon = icon;
70 | icon.Dispose();
71 |
72 | lvwIcons.BeginUpdate();
73 | ClearAllIcons();
74 |
75 | foreach (var i in splitIcons)
76 | {
77 | var item = new IconListViewItem();
78 | var size = i.Size;
79 | item.BitCount = IconUtil.GetBitCount(i);
80 | item.Bitmap = IconUtil.ToBitmap(i);
81 | item.ToolTipText = String.Format("{0}x{1}, {2} bits", size.Width, size.Height, item.BitCount);
82 | i.Dispose();
83 |
84 | lvwIcons.Items.Add(item);
85 | }
86 |
87 | lvwIcons.EndUpdate();
88 |
89 | btnSaveAsIco.Enabled = (m_iconExtractor != null);
90 | }
91 | }
92 |
93 | private void cbShowChecker_CheckedChanged(object sender, EventArgs e)
94 | {
95 | if (cbShowChecker.Checked)
96 | lvwIcons.BackgroundImage = Properties.Resources.Checker;
97 | else
98 | lvwIcons.BackgroundImage = null;
99 | }
100 |
101 | private void btnSaveAsIco_Click(object sender, EventArgs e)
102 | {
103 | var result = saveIcoDialog.ShowDialog(this);
104 | if (result == DialogResult.OK)
105 | {
106 | using (var fs = File.OpenWrite(saveIcoDialog.FileName))
107 | {
108 | m_iconExtractor.Save(m_iconIndex, fs);
109 | }
110 | }
111 | }
112 |
113 | private void btnSaveAsPng_Click(object sender, EventArgs e)
114 | {
115 | var result = folderBrowserDialog.ShowDialog(this);
116 | if (result == DialogResult.OK)
117 | {
118 | int count = lvwIcons.Items.Count;
119 | for (int i = 0; i < count; ++i)
120 | {
121 | var item = (IconListViewItem)lvwIcons.Items[i];
122 | var fileName = String.Format(
123 | "{0}x{1}, {2} bits.png", item.Bitmap.Width, item.Bitmap.Height, item.BitCount);
124 |
125 | fileName = Path.Combine(folderBrowserDialog.SelectedPath, fileName);
126 |
127 | item.Bitmap.Save(fileName);
128 | }
129 | }
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/SampleApp/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 151, 19
122 |
123 |
124 | 272, 21
125 |
126 |
127 | 13, 16
128 |
129 |
--------------------------------------------------------------------------------
/SampleApp/IconListView.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Drawing.Drawing2D;
4 | using System.IO;
5 | using System.Windows.Forms;
6 | using TsudaKageyu;
7 |
8 | namespace SampleApp
9 | {
10 | internal class IconListView : ListView
11 | {
12 | public IconListView() : base()
13 | {
14 | SetStyle(ControlStyles.AllPaintingInWmPaint
15 | | ControlStyles.OptimizedDoubleBuffer
16 | | ControlStyles.ResizeRedraw, true);
17 |
18 | OwnerDraw = true;
19 | }
20 |
21 | protected override void OnDrawItem(DrawListViewItemEventArgs e)
22 | {
23 | base.OnDrawItem(e);
24 |
25 | var item = e.Item as IconListViewItem;
26 |
27 | // Draw item
28 |
29 | e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
30 | e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
31 | e.Graphics.Clip = new Region(e.Bounds);
32 |
33 | if (e.Item.Selected)
34 | e.Graphics.FillRectangle(SystemBrushes.MenuHighlight, e.Bounds);
35 |
36 | int w = Math.Min(128, item.Bitmap.Width);
37 | int h = Math.Min(128, item.Bitmap.Height);
38 |
39 | int x = e.Bounds.X + (e.Bounds.Width - w) / 2;
40 | int y = e.Bounds.Y + (e.Bounds.Height - h) / 2;
41 | var dstRect = new Rectangle(x, y, w, h);
42 | var srcRect = new Rectangle(Point.Empty, item.Bitmap.Size);
43 |
44 | e.Graphics.DrawImage(item.Bitmap, dstRect, srcRect, GraphicsUnit.Pixel);
45 |
46 | var textRect = new Rectangle(
47 | e.Bounds.Left, e.Bounds.Bottom - Font.Height - 4,
48 | e.Bounds.Width, Font.Height + 2);
49 | TextRenderer.DrawText(e.Graphics, item.ToolTipText, Font, textRect, ForeColor);
50 |
51 | e.Graphics.Clip = new Region();
52 | e.Graphics.DrawRectangle(SystemPens.ControlLight, e.Bounds);
53 | }
54 | }
55 |
56 | internal class IconListViewItem : ListViewItem
57 | {
58 | public Bitmap Bitmap { get; set; }
59 | public int BitCount { get; set; }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/SampleApp/IconPickerDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Runtime.InteropServices;
4 | using System.Security;
5 | using System.Text;
6 | using System.Windows.Forms;
7 |
8 | namespace SampleApp
9 | {
10 | public class IconPickerDialog : CommonDialog
11 | {
12 | private static class NativeMethods
13 | {
14 | [DllImport("shell32.dll", EntryPoint = "#62", CharSet = CharSet.Unicode, SetLastError = true)]
15 | [SuppressUnmanagedCodeSecurity]
16 | public static extern bool SHPickIconDialog(
17 | IntPtr hWnd, StringBuilder pszFilename, int cchFilenameMax, out int pnIconIndex);
18 | }
19 |
20 | private const int MAX_PATH = 260;
21 |
22 | [DefaultValue(default(string))]
23 | public string FileName
24 | {
25 | get;
26 | set;
27 | }
28 |
29 | [DefaultValue(0)]
30 | public int IconIndex
31 | {
32 | get;
33 | set;
34 | }
35 |
36 | protected override bool RunDialog(IntPtr hwndOwner)
37 | {
38 | var buf = new StringBuilder(FileName, MAX_PATH);
39 | int index;
40 |
41 | bool ok = NativeMethods.SHPickIconDialog(hwndOwner, buf, MAX_PATH, out index);
42 | if (ok)
43 | {
44 | FileName = Environment.ExpandEnvironmentVariables(buf.ToString());
45 | IconIndex = index;
46 | }
47 |
48 | return ok;
49 | }
50 |
51 | public override void Reset()
52 | {
53 | FileName = null;
54 | IconIndex = 0;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/SampleApp/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | namespace SampleApp
5 | {
6 | static class Program
7 | {
8 | ///
9 | /// The main entry point for the application.
10 | ///
11 | [STAThread]
12 | static void Main()
13 | {
14 | Application.EnableVisualStyles();
15 | Application.SetCompatibleTextRenderingDefault(false);
16 | Application.Run(new Form1());
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/SampleApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SampleApp")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SampleApp")]
13 | [assembly: AssemblyCopyright("Copyright © 2014 Tsuda Kageyu. All rights reserved.")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("9270f752-dca2-49a5-a352-dd20a8068815")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SampleApp/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SampleApp.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SampleApp.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap Checker {
67 | get {
68 | object obj = ResourceManager.GetObject("Checker", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SampleApp/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\Checker.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
--------------------------------------------------------------------------------
/SampleApp/Resources/Checker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TsudaKageyu/IconExtractor/7d66ce0cc0a4b59cdbf5366e917663f9ce7eeda4/SampleApp/Resources/Checker.png
--------------------------------------------------------------------------------
/SampleApp/SampleApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {FE83EBBD-A7AD-4E7D-B0DF-2A13EF23D2B4}
8 | WinExe
9 | Properties
10 | SampleApp
11 | SampleApp
12 | v2.0
13 | 512
14 | publish\
15 | true
16 | Disk
17 | false
18 | Foreground
19 | 7
20 | Days
21 | false
22 | false
23 | true
24 | 0
25 | 1.0.0.%2a
26 | false
27 | false
28 | true
29 |
30 |
31 |
32 | AnyCPU
33 | true
34 | full
35 | false
36 | bin\Debug\
37 | DEBUG;TRACE
38 | prompt
39 | 4
40 |
41 |
42 | AnyCPU
43 | pdbonly
44 | true
45 | bin\Release\
46 | TRACE
47 | prompt
48 | 4
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Form
58 |
59 |
60 | Form1.cs
61 |
62 |
63 | Component
64 |
65 |
66 | Component
67 |
68 |
69 |
70 |
71 | True
72 | True
73 | Resources.resx
74 |
75 |
76 |
77 |
78 | False
79 | Microsoft .NET Framework 4.5 %28x86 and x64%29
80 | true
81 |
82 |
83 | False
84 | .NET Framework 3.5 SP1 Client Profile
85 | false
86 |
87 |
88 | False
89 | .NET Framework 3.5 SP1
90 | false
91 |
92 |
93 |
94 |
95 | Form1.cs
96 |
97 |
98 | ResXFileCodeGenerator
99 | Resources.Designer.cs
100 |
101 |
102 |
103 |
104 | {fdfd4eeb-c202-4d93-a6e9-d8984a12d014}
105 | IconExtractor
106 |
107 |
108 |
109 |
110 |
111 |
112 |
119 |
--------------------------------------------------------------------------------