Как получить значок, связанный с темой Windows? - PullRequest
3 голосов
/ 05 декабря 2011

Как получить значок какого-то элемента управления в 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 ]

6 голосов
/ 01 июня 2012

Согласно документам MSDN, функцию GetThemeBitmap() можно вызывать для свойства TMT_DIBDATA (фон без глифа) или TMT_GLYPHDIBDATA (глиф, т.е. здесь только треугольник) или TMT_HBITMAP (что не являетсяхотя в настоящее время поддерживается вообще).

К сожалению, я обнаружил, что при TMT_GLYPHDIBDATA функции всегда завершаются с E_INVALIDARG.Заголовок <vssym32.h> определяет TMT_GLYPHDIBDATA как 8.Однако я обнаружил, что функция получает растровое изображение глифа для константы 3.

Я предполагаю, что есть ошибка (опечатка) в заголовке <vssym32.h> (в Windows SDK 7.1) или реализацияGetThemeBitmap() в Windows 7.

Если Microsoft хотя бы документирует правильность 3 или 8, я использую этот обходной путь в своем коде:

HBITMAP bmp;
HRESULT hr = GetThemeBitmap(hTheme, iPartId, iStateId, 3, GBF_DIRECT, &bmp);
if(FAILED(hr))
   hr = GetThemeBitmap(hTheme, iPartId, iStateId, TMT_GLYPHDIBDATA, GBF_DIRECT, &bmp);
1 голос
/ 14 декабря 2011

В качестве обходного пути я мог бы предложить следующую функцию, чтобы получить растровое изображение стрелки сортировки.

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); внутри заголовка рисования владельца, которая была более элегантной, чем ее отрисовка на растровое изображение и отображение этого растрового изображения.

1 голос
/ 05 декабря 2011

Я не думаю, что API темы даст вам значок для этого.Это не так, как работает API темы.Скорее вы просто попросите его нарисовать значок сортировки и идентифицировать его по part и state идентификаторам.Он указан в разделе Детали и состояния MSDN: HP_HEADERSORTARROW, HSAS_SORTEDDOWN, HSAS_SORTEDUP.

Изменить : перечитав ваш вопрос, явидите, что вы уже знаете все о деталях и состояниях!

0 голосов
/ 22 апреля 2016

Я обнаружил, что GetThemeBitmap () может завершиться ошибкой как для TMT_GLYPHDIBDATA, так и для TMT_DIBDATA.Я расширил решение Мити следующим образом.

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);

Магические ценности страшны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...