Как получить изображение, которое использует окна 7 для рисования родительских узлов в элементе управления TreeView?

Я работаю в настраиваемом элементе управления, который смешивает два элемента управления Windows (listview и treeview). В какой-то момент мне нужно нарисовать изображение, которое использует окна 7 (с включенными темами) для идентификации родительских узлов, я использую DrawThemeBackground с частью TVP_GLYPH и состоянием GLPS_CLOSED (я безуспешно пытался со всеми частями и состояниями, связанными с классом TREEVIEW), но образ результата всегда является старым (+) или (-).

На этом изображении отображается проблема

enter image description here

Я хочу нарисовать изображение стрелки (внутри черного круга) вместо знака (+) (внутри оранжевого круга).

Это пример кода, который я использую для рисования изображения.

uses
  UxTheme;

procedure TForm40.Button1Click(Sender: TObject);
var
  iPartId : integer;
  iStateId: integer;
  hTheme  : THandle;
begin
  hTheme  := OpenThemeData(Handle, VSCLASS_TREEVIEW);

  iPartId := TVP_GLYPH;
  iStateId:= GLPS_CLOSED;          
  //iPartId := TVP_TREEITEM;
  //iStateId:= TREIS_NORMAL;
  if hTheme <> 0 then
    try

      //if (IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId)) then
      //    DrawThemeParentBackground(Handle, PaintBox1.Canvas.Handle, nil);

      DrawThemeBackground(hTheme, PaintBox1.Canvas.Handle, iPartId, iStateId, Rect(0, 0, 31, 31), nil);
    finally
      CloseThemeData(hTheme);
    end;
end;

Я проверяю пару инструментов, таких как приложение, сделанное Andreas Rejbrand и this, но я не могу найти изображение, которое я хочу.

Мой вопрос: как я могу получить изображение стрелки?

UPDATE

Благодаря ответу на Стигма я нашел дополнительные ресурсы для значений частей и состояний класса Explorer::Treeview.

Ответы

Ответ 1

Прежде всего, в случае обычного ListView или TreeView можно просто вызвать SetWindowTheme на свой дескриптор чтобы применить надлежащий вид стилизации. Пример со страницы MSDN выглядит следующим образом:

SetWindowTheme(hwndList, L"Explorer", NULL);

Поскольку мы говорим о пользовательском элементе управления, я не уверен, что это применимо. Но поскольку SetWindowTheme вызывает сообщение WM_THEMECHANGED, чтобы быть отправлен в соответствующее окно, это означает, что вам просто нужно использовать правильный вызов OpenThemeData для конкретной подтемы.

Я думаю, что комментарий Люка верен. Вероятно, вам просто нужно передать "Explorer:: Treeview", а не простой стиль. Таким образом, за исключением лет, не затронутых Delphi/Pascal:

hTheme  := OpenThemeData(Handle, 'Explorer::Treeview');

Ответ 2

Вы должны установить SetWindowTheme(Handle, 'explorer', nil); перед рисованием, чтобы OpenThemeData использовал новую тему стиля проводника. Конечно, дескриптор окна должен быть одинаковым для обеих функций.