May 1st, 2014

How do I extract an icon at a nonstandard size if IExtractIcon::Extract tells me to go jump in a lake?

Commenter Ivo notes that if you ask IExtract­Icon::Extract to extract an icon at a particular size, the function can return S_FALSE which means “Go jump in a lake do it yourself.” But how can you do it yourself? The Extract­Icon and Extract­Icon­Ex functions don’t let you specify a custom size, and Load­Image doesn’t work with icon indices (only resource IDs).

The SH­Def­Extract­Icon function comes to the rescue. This takes all the parameters of IExtract­Icon::Extract (plus a bonus flags parameter), and it will actually do an extraction.

Let’s extract an icon from Explorer at 48×48, just for illustration. As usual, start with our scratch program, then make these changes:

#include <shlobj.h>
void
PaintContent(HWND hwnd, PAINTSTRUCT *pps)
{
  HICON hico;
  if (SHDefExtractIcon(TEXT("C:\\Windows\\Explorer.exe"),
                       1, 0, &hico, NULL, 48) == S_OK) {
    DrawIconEx(pps->hdc, 0, 0, hico, 0, 0, 0, NULL, DI_NORMAL);
    DestroyIcon(hico);
  }
}

Run the program, and observe that it draws the second icon from Explorer (whatever it is) at a size of 48×48.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.