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.