如何获得与Windows主题相关联的图标?

时间:2011-12-05 13:06:33

标签: winapi visual-c++

如何在Windows中获取某些控件的图标? 更具体地说,我想从ListView标题中获取排序箭头图标。 我尝试使用以下方法获取它:

HRESULT GetSortArrowBmp(HWND hwnd, HEADERSORTARROWSTATES arrowState, HBITMAP** arrow)
{
    HTHEME theme = OpenThemeData(hwnd,L"HEADER"); // hwnd is header itself
    HRESULT res = E_FAIL;
    if (theme){
        res = GetThemeBitmap(theme, HP_HEADERSORTARROW, arrowState, TMT_DIBDATA, GBF_COPY, *arrow);   
        CloseThemeData(theme);
    }
    return res;
} 

但它并没有回归我期待的那个小三角形。有什么建议吗?

4 个答案:

答案 0 :(得分:5)

根据MSDN文档,函数GetThemeBitmap()可以为属性TMT_DIBDATA(没有字形的背景)或TMT_GLYPHDIBDATA(字形,即此处只是三角形)或{ {1}}(目前根本不支持)。

不幸的是,我发现TMT_HBITMAP使用TMT_GLYPHDIBDATA功能始终失败。标头E_INVALIDARG<vssym32.h>定义为TMT_GLYPHDIBDATA。但是我发现函数获取常量8的字形位图。

我猜标题3(从Windows SDK 7.1开始)或在Windows 7上实现<vssym32.h>时会出现错误(拼写错误)。

除非Microsoft至少提供3或8的文档是正确的,否则我在代码中使用此解决方法:

GetThemeBitmap()

答案 1 :(得分:1)

我认为主题API不会为您提供此图标。这不是主题API的工作方式。而是简单地要求它绘制排序图标并通过 part state 标识符来识别它。它列在Parts and States MSDN主题中:HP_HEADERSORTARROWHSAS_SORTEDDOWNHSAS_SORTEDUP

编辑:重新阅读您的问题后,我发现您已经了解了所有部分和状态!

答案 2 :(得分:1)

作为一种解决方法,我可以建议使用以下函数来获取排序箭头的位图图像。

HBITMAP GetSortArrowBmp(HWND hwnd, HEADERSORTARROWSTATES arrowState, int width, int height){
    RECT rect; // dimensions of a bitmap
    rect.left = 0;
    rect.right = width;
    rect.top = 0;
    rect.bottom = height;

    HDC hdc;
    HDC hdcMem;
    HBITMAP hBitmap;

    hdc = GetDC(hwnd);
    hdcMem = CreateCompatibleDC(hdc);
    hBitmap = CreateCompatibleBitmap(hdc, width, height);

    HTHEME theme = OpenThemeData(hwnd, L"HEADER");

    if(theme){
        DrawThemeBackground(theme, hdcMem, HP_HEADERITEM, HIS_ICONNORMAL, &rect, NULL);
        // drawing sort arrow
        DrawThemeBackground(theme, hdcMem, HP_HEADERSORTARROW, arrowState, &rect, NULL); 
    }
    CloseThemeData(theme);

    DeleteObject(hdcMem);
    ReleaseDC(hwnd, hdc);

    return hBitmap;
}

虽然我没有在我的代码中使用它。我在所有者绘制标题中应用了相同的DrawThemeBackground(theme, hdcMem, HP_HEADERSORTARROW, arrowState, &rect, NULL);函数,这比将其绘制到位图并显示该位图更优雅。

答案 3 :(得分:0)

我发现对于TMT_GLYPHDIBDATA和TMT_DIBDATA,GetThemeBitmap()都可能失败。我将mity的解决方案扩展到以下内容。

HRESULT ret = ::GetThemeBitmap(hTheme, iPartId, iStateId, glyph ? TMT_GLYPHDIBDATA : TMT_DIBDATA, GBF_DIRECT, hBmp);
if (ret == E_INVALIDARG)
    ret = ::GetThemeBitmap(pThemeRecord->hTheme, iPartId, iStateId, 3, GBF_DIRECT, hBmp);

魔术值很可怕。