Конференция "WinAPI" » Отрисовка элементов стандартного TreeView
 
  • Dmitriy (18.01.19 23:29) [0]
    Коллеги, помогите. Всю голову поломал за этот вечер. Задача простая отрисовать элементы на произвольном контроле по стилю эквивалентно стандартному TreeView. Элементы из TThemedTreeview прорисовываются как окно с рамкой, то есть не отрисвываются. Почему????? Вот взял отрисовал на форме все что относится к TreeView. Из всех элементов отрисовался только ttGlyphClosed, ttGlyphOpened.
    Вот обработчик кнопки на форме:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    e: TThemedElementDetails;
    RC: TRect;
    i: TThemedTreeview;
    begin
    if ThemeServices.ThemesEnabled then
    begin
     RC := Rect(10, 10, 50, 20);
     for i := low(TThemedTreeview) to high(TThemedTreeview) do
     begin
      e := ThemeServices.GetElementDetails(i);
      ThemeServices.DrawElement(Canvas.Handle, e, RC);
      Inc(RC.Top, 15); Inc(RC.Bottom, 15);
     end;
    end;
    end;
  • Сапёр (19.01.19 00:41) [1]
    Во-первых очень рекомендую всегда вызывать Lock() и Unlock() у целевой Canvas, особенно при рисовании на окне, особенно при рисовании не в событиях для рисования.
    А во-вторых - кто будет заполнять Part и State?)) :3
  • Сапёр (19.01.19 00:55) [2]
    гм... Хотя пишут вроде что GetElementDetails() должен был заполнить... Может в текущей теме оформления просто нет картинок для данных Part и State?
  • Сапёр (19.01.19 01:16) [3]
    procedure TForm1.Button1Click(Sender: TObject);
    var Details: TThemedElementDetails; RC: TRect; Themed: TThemedButton; // TThemedTreeview;
    begin
    // if ThemeServices.ThemesEnabled then // у меня на Delphi7 почему-то всегда False, хотя по факту там точно True...
       begin
       RC:=Rect(10, 10, 80, 40);
       Canvas.Lock();
       for Themed:=Low(Themed) to High(Themed) do
           begin
           Details:=ThemeServices.GetElementDetails(Themed);
           if IsThemePartDefined(ThemeServices.Theme[Details.Element], Details.Part, 0 { unused, should be 0 } ) then
               ThemeServices.DrawElement(Canvas.Handle, Details, RC)
           else
               Canvas.TextRect(RC, RC.Left, RC.Top, '<not exists>');
           OffsetRect(RC, 0, 40);
           end;
       Canvas.Unlock();
       end;
    end;
  • Сапёр (19.01.19 15:58) [4]
    З.Ы. Уже много лет периодически ищу ответы на вопросы, и что-то так и не нахожу:
    * Как стандартным UxTheme рисовать не текущей темой оформления? (это 100% возможно)
    * Как рисовать рамку и кнопки Aero хотя бы из текущей темы оформления?
    Раз уж вы в этом направлении изучаете, вдруг что попадётся...
  • Dmitriy (21.01.19 11:54) [5]
    Нашел)
    procedure TForm2.Button1Click(Sender: TObject);
    var
    ThemeData: HTHEME;
    RC: TRect;
    begin
    RC := rect(0, 0, 100, 30);
    ThemeData := OpenThemeData(TreeView1.Handle, VSCLASS_TREEVIEW);
    DrawThemeBackground(ThemeData, TreeView1.Canvas.Handle, TVP_TREEITEM, TREIS_SELECTED, RC, nil);
    CloseThemeData(ThemeData);
    end;
  • Сапёр (21.01.19 13:01) [6]
    гм... ThemeServices (по крайней мере в версии Делфи7) не поддерживают Theme Subclasses даже через свойства HWND, не говоря уже об явном указании...
    У вас тот же код что и в кишках ThemeServices, но с учётом текущего subclass у TTreeView...
    Надо проверить улучшили ли что в более новых версиях Делфи...
 
Конференция "WinAPI" » Отрисовка элементов стандартного TreeView
Есть новые Нет новых   [118425   +55][b:0][p:0]