How to figure out the shell's drag/drop icon size for use with SHDoDragDrop?

190 Views Asked by At

How do I figure out the right icon size to use so that the icon matches Explorer's default drag-and-drop icon?

(I'm trying to use it with SHDoDragDrop if that matters.)

enter image description here

1

There are 1 best solutions below

6
Simon Mourier On BEST ANSWER

The size depends on what's in the data object format. From the Shell, it's 96x96.

You can check that if you drag & drop a file into any valid drop target, the data object will contain the "DragImageBits" format and its data is a SHDRAGIMAGE structure:

typedef struct SHDRAGIMAGE {
  SIZE     sizeDragImage; // will contain 96x96 when dragged from the Shell
  POINT    ptOffset;
  HBITMAP  hbmpDragImage;
  COLORREF crColorKey;
} SHDRAGIMAGE, *LPSHDRAGIMAGE;

If you're looking for a more static way, here is a code that seems to work, using the UxThemes API. Note that although it uses documented APIs and defines, I don't think it's documented as such.

...
#include <uxtheme.h>
#include <vsstyle.h>
#include <vssym32.h>
...

// note: error checking ommited
auto theme = OpenThemeData(NULL, VSCLASS_DRAGDROP);

SIZE size = {};
GetThemePartSize(theme, NULL, DD_IMAGEBG, 0, NULL, THEMESIZE::TS_DRAW, &size);

MARGINS margins = {};
GetThemeMargins(theme, NULL, DD_IMAGEBG, 0, TMT_CONTENTMARGINS, NULL, &margins);

// final size
size.cx -= margins.cxLeftWidth + margins.cxRightWidth;
size.cy -= margins.cyTopHeight + margins.cyBottomHeight;

CloseThemeData(theme);

As for DPI settings, I understand you want to mimic Explorer, in this case you'll have to do some computation by yourself depending on your needs and screen context, as the image size extracted by the Shell is itself fixed.