{"id":2043,"date":"2014-01-20T07:00:00","date_gmt":"2014-01-20T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/01\/20\/how-do-i-get-a-high-resolution-icon-for-a-file\/"},"modified":"2024-06-05T11:58:36","modified_gmt":"2024-06-05T18:58:36","slug":"20140120-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140120-00\/?p=2043","title":{"rendered":"How do I get a high resolution icon for a file?"},"content":{"rendered":"<p>Today&#8217;s Little Program obtains a high resolution icon for a file.<\/p>\n<p>Start with our <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20030723-00\/?p=43073\"> scratch program<\/a> and make these changes. Remember, Little Programs do little or no error checking. This week&#8217;s smart pointer class is (rolls dice) <code>_com_ptr_t<\/code>!<\/p>\n<pre>...\r\n#include &lt;shlwapi.h&gt;\r\n<span style=\"border: solid 1px currentcolor; border-bottom: none;\">#include &lt;commoncontrols.h&gt;                             <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">#include &lt;comip.h&gt;                                      <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">#include &lt;comdef.h&gt;                                     <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">\u00a0                                                       <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-top: none;\">_COM_SMARTPTR_TYPEDEF(IImageList, __uuidof(IImageList));<\/span>\r\n\r\nHICON g_hico;\r\n\r\nHINSTANCE g_hinst;                          \/* This application's HINSTANCE *\/\r\n...\r\n\r\n<span style=\"border: solid 1px currentcolor; border-bottom: none;\">int GetIconIndex(PCTSTR pszFile)                                   <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">{                                                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  SHFILEINFO sfi;                                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  SHGetFileInfo(pszFile, 0, &amp;sfi, sizeof(sfi), SHGFI_SYSICONINDEX);<\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  return sfi.iIcon;                                                <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">}                                                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">\u00a0                                                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">HICON GetJumboIcon(int iImage)                                     <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">{                                                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  IImageListPtr spiml;                                             <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  SHGetImageList(SHIL_JUMBO, IID_PPV_ARGS(&amp;spiml));                <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">\u00a0                                                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  HICON hico;                                                      <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  spiml-&gt;GetIcon(iImage, ILD_TRANSPARENT, &amp;hico);                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">  return hico;                                                     <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-top: none;\">}                                                                  <\/span>\r\n<\/pre>\n<p>The <code>Get\u00adIcon\u00adIndex<\/code> function does nothing new. It simply retrieves the system image list icon index for a file&#8217;s icon.<\/p>\n<p>The <code>Get\u00adJumbo\u00adIcon<\/code> retrieves an icon by its system image list index. First, it asks <code>SHGet\u00adImage\u00adList<\/code> for the jumbo image list, then it asks the jumbo image list for the icon.<\/p>\n<p>Now all we have to do is hook the functions up.<\/p>\n<pre>void\r\nPaintContent(HWND hwnd, PAINTSTRUCT *pps)\r\n{\r\n  <span style=\"border: solid 1px currentcolor; border-bottom: none;\">DrawIconEx(pps-&gt;hdc, 50, 50, g_hico,    <\/span>\r\n  <span style=\"border: solid 1px currentcolor; border-top: none;\">           0, 0, 0, nullptr, DI_NORMAL);<\/span>\r\n}\r\n\r\n    ...\r\n    if (SUCCEEDED(CoInitialize(NULL))) {\/* In case we use COM *\/\r\n\r\n        <span style=\"border: solid 1px currentcolor;\">g_hico = GetJumboIcon(GetIconIndex(lpCmdLine));<\/span>\r\n\r\n        ...\r\n        <span style=\"border: solid 1px currentcolor;\">DestroyIcon(g_hico);<\/span>\r\n        CoUninitialize();\r\n    }\r\n    ...\r\n<\/pre>\n<p>Run this program and pass the full path to a file on the command line. (No quotation marks, even if it contains spaces!) Result: A gigantic icon for the file appears.<\/p>\n<p>Instead of converting the system imagelist index into an icon, we could just ask the jumbo imagelist to render it directly.<\/p>\n<pre><span style=\"border: solid 1px currentcolor;\">int g_iImage;<\/span>\r\n\r\nvoid\r\nPaintContent(HWND hwnd, PAINTSTRUCT *pps)\r\n{\r\n  <span style=\"border: solid 1px currentcolor; border-bottom: none;\">IImageListPtr spiml;                             <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">SHGetImageList(SHIL_JUMBO, IID_PPV_ARGS(&amp;spiml));<\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">\u00a0                                                <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">IMAGELISTDRAWPARAMS ildp = { sizeof(ildp) };     <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.himl = IImageListToHIMAGELIST(spiml);       <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.i = g_iImage;                               <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.hdcDst = pps-&gt;hdc;                          <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.x = 50;                                     <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.y = 50;                                     <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.rgbBk = CLR_NONE;                           <\/span>\r\n  <span style=\"border: 1px currentcolor; border-style: none solid;\">ildp.fStyle = ILD_TRANSPARENT;                   <\/span>\r\n  <span style=\"border: solid 1px currentcolor; border-top: none;\">spiml-&gt;Draw(&amp;ildp);                              <\/span>\r\n}\r\n\r\n    ...\r\n    if (SUCCEEDED(CoInitialize(NULL))) {\/* In case we use COM *\/\r\n\r\n        <span style=\"border: solid 1px currentcolor;\">g_iImage = GetIconIndex(lpCmdLine);<\/span>\r\n\r\n        ...\r\n        <span style=\"border: solid 1px currentcolor;\">\/\/ no cleanup necessary<\/span>\r\n        CoUninitialize();\r\n    }\r\n    ...\r\n<\/pre>\n<p>This is how Explorer deals with icons most of the time. It doesn&#8217;t create actual icons; it merely remembers indices into the system imagelist, and when it needs to draw an icon, it calls the <code>Draw<\/code> method on the imagelist whose size corresponds to the image it wants.<\/p>\n<p><b>Bonus chatter<\/b>: The system imagelists come in four sizes (as of this writing). And yet <i>large<\/i> is one of the smallest available ones. Why is that?<\/p>\n<p>The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb762185%28v=vs.85%29.aspx\"> system imagelist sizes<\/a> are<\/p>\n<ul>\n<li>Small<\/li>\n<li>Large<\/li>\n<li>Extra-Large<\/li>\n<li>Jumbo<\/li>\n<\/ul>\n<p>The first two (<i>small<\/i> and <i>large<\/i>) were the only ones available in Windows\u00a095. Windows\u00a0XP added a size larger than large, which was named <i>extra-large<\/i>. And then Windows Vista added another size even larger than extra-large, which I named <i>jumbo<\/i>.<\/p>\n<p>It&#8217;s an artifact of history that one of the smallest icon sizes has the name <i>large<\/i>. It was the largest icon size at the time, but things got even larger since then.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jumbo size.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-2043","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Jumbo size.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/2043","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=2043"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/2043\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=2043"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=2043"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=2043"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}