【发布时间】:2021-08-01 17:59:29
【问题描述】:
【问题讨论】:
标签: c winapi drag-and-drop icons imagelist
【问题讨论】:
标签: c winapi drag-and-drop icons imagelist
大小取决于数据对象格式中的内容。在 Shell 中,它是 96x96。
您可以检查,如果您将文件拖放到任何有效的放置目标中,数据对象将包含“DragImageBits”格式并且其数据是SHDRAGIMAGE structure:
typedef struct SHDRAGIMAGE {
SIZE sizeDragImage; // will contain 96x96 when dragged from the Shell
POINT ptOffset;
HBITMAP hbmpDragImage;
COLORREF crColorKey;
} SHDRAGIMAGE, *LPSHDRAGIMAGE;
如果您正在寻找更静态的方式,这里有一个似乎可以工作的代码,它使用 UxThemes API。请注意,虽然它使用文档化的 API 和定义,但我不认为它是这样记录的。
...
#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);
至于DPI设置,我知道你想模仿Explorer,在这种情况下你必须根据你的需要和屏幕上下文自己做一些计算,因为Shell提取的图像大小本身是固定的。
【讨论】:
SHDoDragDrop 时不处理剪贴板,所以我能问一下它在哪里起作用吗?弄清楚拖放应该如何工作有点令人困惑。我也不知道如何在运行时解决这个问题。而且我不能只对 96x96 进行硬编码,因为它似乎是由 DPI 缩放的,它变成了每个监视器等......知道这里的正确方法是什么吗?
GetDeviceCaps(hDC, LOGPIXELSX) 来获得这个值,所以我想这就是我现在要做的,但它最终可能会搞砸多显示器支持。让我好奇是否有正确的方法来做到这一点。似乎很难找到好的代码示例。