RRUZ
RRUZ

Reputation: 136451

How can obtain the image which uses windows 7 to draw the parent nodes in a treeview control?

I'm working in a custom control which mix two windows controls (listview and treeview). In some point, I need to draw the image which uses windows 7 (with themes enabled) to identify the parent nodes, I'm using the DrawThemeBackground function with the TVP_GLYPH part and the GLPS_CLOSED state (I tried with all the parts and states related to the TREEVIEW class without luck), but the result image always is the old (+) or (-).

This image show the issue

enter image description here

I want to draw the Arrow image (inside of black circle) instead of the (+) sign (inside of orange circle).

This is the sample code which I use to draw the image.

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;

I check a couple of tools like the application made by Andreas Rejbrand and this too, but I can't find the image which I want.

My question is : how I can obtain the arrow image?

UPDATE

Thanks to the answer posted for Stigma I found additional resources to the values of the parts and states of the Explorer::Treeview class.

Upvotes: 15

Views: 3346

Answers (2)

Stigma
Stigma

Reputation: 1736

First of all, in the case of an ordinary ListView or TreeView, one can simply call SetWindowTheme on its handle to apply the proper sort of styling. The example from its MSDN page is as follows:

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

Since we are talking about a custom control, I am not so sure that applies here however. But since SetWindowTheme causes the WM_THEMECHANGED message to be sent to the proper window, it implies that you will just need to use the proper OpenThemeData call for the specific sub theme.

I think Luke's comment is correct. You probably just need to pass 'Explorer::Treeview' rather than the plain style. So, barring years of not having touched Delphi/Pascal:

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

Upvotes: 11

Linas
Linas

Reputation: 5545

You must set SetWindowTheme(Handle, 'explorer', nil); before painting to ensure that OpenThemeData will use new explorer style theme. Of course, window handle must be the same for both functions.

Upvotes: 2

Related Questions