【问题标题】:How to figure out the shell's drag/drop icon size for use with SHDoDragDrop?如何确定用于 SHDoDragDrop 的外壳的拖放图标大小?
【发布时间】:2021-08-01 17:59:29
【问题描述】:

如何确定要使用的正确图标大小,以使图标与 Explorer 的默认拖放图标匹配?

(如果这很重要,我正在尝试将它与 SHDoDragDrop 一起使用。)

【问题讨论】:

    标签: c winapi drag-and-drop icons imagelist


    【解决方案1】:

    大小取决于数据对象格式中的内容。在 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 缩放的,它变成了每个监视器等......知道这里的正确方法是什么吗?
    • 我的意思是“数据对象” :-) 即使使用其他 DPI 设置,图像大小也始终相同
    • 嗯,我不认为它总是 96x96。在我的机器上,它似乎是 115x115(在 120% 时为 96)。您实际上可以在我的屏幕截图中看到这一点;我图标中的纸张长度已经大于 96 像素。我注意到我可以使用GetDeviceCaps(hDC, LOGPIXELSX) 来获得这个值,所以我想这就是我现在要做的,但它最终可能会搞砸多显示器支持。让我好奇是否有正确的方法来做到这一点。似乎很难找到好的代码示例。
    • 哇,太迷人了!非常感谢,看起来这甚至似乎不再需要 DPI 调整了。请问你到底是怎么想出来的?!必须使用 UxTheme 似乎很随意!
    • 哇。谢谢! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多