mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-27 17:47:40 +01:00
LCL/ShellCtrls: On Windows automatically show shell icons in TShellTreeView when no imagelist is attached.
git-svn-id: trunk@64575 -
This commit is contained in:
parent
fcff9d8ea7
commit
e32b62e6b4
@ -3511,7 +3511,9 @@ type
|
|||||||
procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
|
procedure DoAutoAdjustLayout(const AMode: TLayoutAdjustmentPolicy;
|
||||||
const AXProportion, AYProportion: Double); override;
|
const AXProportion, AYProportion: Double); override;
|
||||||
function ExpandSignSizeIsStored: Boolean;
|
function ExpandSignSizeIsStored: Boolean;
|
||||||
|
function GetBuiltinIconSize: TSize; virtual;
|
||||||
function GetDragImages: TDragImageList; override;
|
function GetDragImages: TDragImageList; override;
|
||||||
|
function GetImageSize: TSize;
|
||||||
function GetMaxLvl: integer;
|
function GetMaxLvl: integer;
|
||||||
function GetMaxScrollLeft: integer;
|
function GetMaxScrollLeft: integer;
|
||||||
function GetMaxScrollTop: integer;
|
function GetMaxScrollTop: integer;
|
||||||
@ -3545,6 +3547,7 @@ type
|
|||||||
procedure DoStartDrag(var DragObject: TDragObject); override;
|
procedure DoStartDrag(var DragObject: TDragObject); override;
|
||||||
procedure DragOver(Source: TObject; X,Y: Integer; State: TDragState;
|
procedure DragOver(Source: TObject; X,Y: Integer; State: TDragState;
|
||||||
var Accept: Boolean); override;
|
var Accept: Boolean); override;
|
||||||
|
function DrawBuiltinIcon(ANode: TTreeNode; ARect: TRect): TSize; virtual;
|
||||||
procedure EndEditing(Cancel: boolean = false); virtual;
|
procedure EndEditing(Cancel: boolean = false); virtual;
|
||||||
procedure EnsureNodeIsVisible(ANode: TTreeNode);
|
procedure EnsureNodeIsVisible(ANode: TTreeNode);
|
||||||
procedure Expand(Node: TTreeNode); virtual;
|
procedure Expand(Node: TTreeNode); virtual;
|
||||||
|
|||||||
@ -1754,16 +1754,24 @@ function TTreeNode.DisplayTextLeft: integer;
|
|||||||
var
|
var
|
||||||
TV: TCustomTreeView;
|
TV: TCustomTreeView;
|
||||||
ImgIndex: TImageIndex;
|
ImgIndex: TImageIndex;
|
||||||
|
sz: TSize;
|
||||||
begin
|
begin
|
||||||
Result := DisplayIconLeft;
|
Result := DisplayIconLeft;
|
||||||
TV := TreeView;
|
TV := TreeView;
|
||||||
if (TV = nil) or (TV.Images = nil) then Exit;
|
if TV = nil then
|
||||||
|
exit;
|
||||||
|
sz := TV.GetImageSize;
|
||||||
|
if (TV.Images = nil) then
|
||||||
|
begin
|
||||||
|
inc(Result, sz.CX);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
if (TV.Selected = Self) then
|
if (TV.Selected = Self) then
|
||||||
ImgIndex:=SelectedIndex
|
ImgIndex:=SelectedIndex
|
||||||
else
|
else
|
||||||
ImgIndex:=ImageIndex;
|
ImgIndex:=ImageIndex;
|
||||||
if (ImgIndex<0) or (ImgIndex>=TV.Images.Count) then Exit;
|
if (ImgIndex<0) or (ImgIndex>=TV.Images.Count) then Exit;
|
||||||
Inc(Result, TV.Images.WidthForPPI[TV.StateImagesWidth, TV.Font.PixelsPerInch] + TV.FDefItemSpace);
|
Inc(Result, sz.CX + TV.FDefItemSpace);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TTreeNode.DisplayTextRight: integer;
|
function TTreeNode.DisplayTextRight: integer;
|
||||||
@ -3667,12 +3675,11 @@ begin
|
|||||||
if (tvoAutoItemHeight in FOptions)
|
if (tvoAutoItemHeight in FOptions)
|
||||||
and HandleAllocated and Canvas.HandleAllocated then begin
|
and HandleAllocated and Canvas.HandleAllocated then begin
|
||||||
NewDefItemHeight:=Canvas.TextHeight(TVAutoHeightString)+FDefItemSpace;
|
NewDefItemHeight:=Canvas.TextHeight(TVAutoHeightString)+FDefItemSpace;
|
||||||
if Assigned(FImages) then
|
ImageSize := GetImageSize;
|
||||||
ImageSize := Images.SizeForPPI[ImagesWidth, Font.PixelsPerInch];
|
|
||||||
if Assigned(FStateImages) then
|
if Assigned(FStateImages) then
|
||||||
StateImageSize := StateImages.SizeForPPI[StateImagesWidth, Font.PixelsPerInch];
|
StateImageSize := StateImages.SizeForPPI[StateImagesWidth, Font.PixelsPerInch];
|
||||||
if NewDefItemHeight<FDefItemSpace then NewDefItemHeight:=FDefItemSpace;
|
if NewDefItemHeight<FDefItemSpace then NewDefItemHeight:=FDefItemSpace;
|
||||||
if (Images<>nil) and (ImageSize.cy+FDefItemSpace>NewDefItemHeight) then
|
if (ImageSize.cy > 0) and (ImageSize.cy + FDefItemSpace > NewDefItemHeight) then
|
||||||
NewDefItemHeight:=ImageSize.cy+FDefItemSpace;
|
NewDefItemHeight:=ImageSize.cy+FDefItemSpace;
|
||||||
if (StateImages<>nil) and (StateImageSize.cy+FDefItemSpace>NewDefItemHeight) then
|
if (StateImages<>nil) and (StateImageSize.cy+FDefItemSpace>NewDefItemHeight) then
|
||||||
NewDefItemHeight:=StateImageSize.cy+FDefItemSpace;
|
NewDefItemHeight:=StateImageSize.cy+FDefItemSpace;
|
||||||
@ -4704,6 +4711,20 @@ begin
|
|||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomTreeView.GetBuiltinIconSize: TSize;
|
||||||
|
begin
|
||||||
|
Result := Types.Size(0, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomTreeView.GetImageSize: TSize;
|
||||||
|
begin
|
||||||
|
if FImages <> nil then
|
||||||
|
begin
|
||||||
|
Result := Images.SizeForPPI[ImagesWidth, Font.PixelsPerInch]
|
||||||
|
end else
|
||||||
|
Result := GetBuiltinIconSize;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomTreeView.UpdateInsertMark(X,Y: integer);
|
procedure TCustomTreeView.UpdateInsertMark(X,Y: integer);
|
||||||
begin
|
begin
|
||||||
if (tvoAutoInsertMark in Options) and (not (csDesigning in ComponentState))
|
if (tvoAutoInsertMark in Options) and (not (csDesigning in ComponentState))
|
||||||
@ -5339,7 +5360,7 @@ var
|
|||||||
|
|
||||||
var
|
var
|
||||||
x, ImgIndex: integer;
|
x, ImgIndex: integer;
|
||||||
CurTextRect: TRect;
|
CurTextRect, ImgRect: TRect;
|
||||||
DrawState: TCustomDrawState;
|
DrawState: TCustomDrawState;
|
||||||
PaintImages: boolean;
|
PaintImages: boolean;
|
||||||
OverlayIndex: Integer;
|
OverlayIndex: Integer;
|
||||||
@ -5404,7 +5425,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// draw icon
|
// draw icon
|
||||||
if (Images <> nil) then
|
if (Images = nil) then
|
||||||
|
begin
|
||||||
|
imgRect := NodeRect;
|
||||||
|
imgRect.Left := x+1;
|
||||||
|
inc(x, DrawBuiltinIcon(Node, imgRect).CX + FDefItemSpace);
|
||||||
|
end else
|
||||||
begin
|
begin
|
||||||
if FSelectedNode <> Node then
|
if FSelectedNode <> Node then
|
||||||
begin
|
begin
|
||||||
@ -5479,6 +5505,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomTreeView.DrawBuiltinIcon(ANode: TTreeNode; ARect: TRect): TSize;
|
||||||
|
begin
|
||||||
|
Result := Size(0, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomTreeView.GetImageIndex(Node: TTreeNode);
|
procedure TCustomTreeView.GetImageIndex(Node: TTreeNode);
|
||||||
begin
|
begin
|
||||||
if Assigned(FOnGetImageIndex) then
|
if Assigned(FOnGetImageIndex) then
|
||||||
|
|||||||
@ -24,7 +24,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, Laz_AVL_Tree,
|
Classes, SysUtils, Laz_AVL_Tree,
|
||||||
// LCL
|
// LCL
|
||||||
Forms, Graphics, ComCtrls, LCLProc, LCLStrConsts,
|
Forms, Graphics, ComCtrls, LCLProc, LCLType, LCLStrConsts, Types,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
FileUtil, LazFileUtils, LazUTF8, Masks;
|
FileUtil, LazFileUtils, LazUTF8, Masks;
|
||||||
|
|
||||||
@ -64,6 +64,7 @@ type
|
|||||||
FShellListView: TCustomShellListView;
|
FShellListView: TCustomShellListView;
|
||||||
FFileSortType: TFileSortType;
|
FFileSortType: TFileSortType;
|
||||||
FInitialRoot: String;
|
FInitialRoot: String;
|
||||||
|
FUseBuiltinIcons: Boolean;
|
||||||
FOnAddItem: TAddItemEvent;
|
FOnAddItem: TAddItemEvent;
|
||||||
{ Setters and getters }
|
{ Setters and getters }
|
||||||
function GetPath: string;
|
function GetPath: string;
|
||||||
@ -72,6 +73,7 @@ type
|
|||||||
procedure SetPath(AValue: string);
|
procedure SetPath(AValue: string);
|
||||||
procedure SetRoot(const AValue: string);
|
procedure SetRoot(const AValue: string);
|
||||||
procedure SetShellListView(const Value: TCustomShellListView);
|
procedure SetShellListView(const Value: TCustomShellListView);
|
||||||
|
procedure SetUseBuiltinIcons(const AValue: Boolean);
|
||||||
protected
|
protected
|
||||||
procedure DoCreateNodeClass(var NewNodeClass: TTreeNodeClass); override;
|
procedure DoCreateNodeClass(var NewNodeClass: TTreeNodeClass); override;
|
||||||
procedure Loaded; override;
|
procedure Loaded; override;
|
||||||
@ -82,6 +84,15 @@ type
|
|||||||
procedure DoSelectionChanged; override;
|
procedure DoSelectionChanged; override;
|
||||||
procedure DoAddItem(const ABasePath: String; const AFileInfo: TSearchRec; var CanAdd: Boolean);
|
procedure DoAddItem(const ABasePath: String; const AFileInfo: TSearchRec; var CanAdd: Boolean);
|
||||||
function CanExpand(Node: TTreeNode): Boolean; override;
|
function CanExpand(Node: TTreeNode): Boolean; override;
|
||||||
|
|
||||||
|
{$ifdef mswindows}
|
||||||
|
private
|
||||||
|
FBuiltinIconSize: TSize;
|
||||||
|
protected
|
||||||
|
function DrawBuiltInIcon(ANode: TTreeNode; ARect: TRect): TSize; override;
|
||||||
|
function GetBuiltinIconSize: TSize; override;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
public
|
public
|
||||||
{ Basic methods }
|
{ Basic methods }
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
@ -97,6 +108,7 @@ type
|
|||||||
function GetPathFromNode(ANode: TTreeNode): string;
|
function GetPathFromNode(ANode: TTreeNode): string;
|
||||||
procedure PopulateWithBaseFiles;
|
procedure PopulateWithBaseFiles;
|
||||||
procedure Refresh(ANode: TTreeNode); overload;
|
procedure Refresh(ANode: TTreeNode); overload;
|
||||||
|
property UseBuiltinIcons: Boolean read FUseBuiltinIcons write SetUseBuiltinIcons default true;
|
||||||
|
|
||||||
{ Properties }
|
{ Properties }
|
||||||
property ObjectTypes: TObjectTypes read FObjectTypes write SetObjectTypes;
|
property ObjectTypes: TObjectTypes read FObjectTypes write SetObjectTypes;
|
||||||
@ -365,7 +377,7 @@ procedure Register;
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
{$ifdef windows}
|
{$ifdef windows}
|
||||||
uses Windows;
|
uses Windows, ShellApi;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -411,7 +423,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ TShellTreeNode }
|
{ TShellTreeNode }
|
||||||
|
|
||||||
procedure TShellTreeNode.SetBasePath(ABasePath: String);
|
procedure TShellTreeNode.SetBasePath(ABasePath: String);
|
||||||
@ -470,6 +481,12 @@ begin
|
|||||||
Value.ShellTreeView := Self;
|
Value.ShellTreeView := Self;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomShellTreeView.SetUseBuiltinIcons(const AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FUseBuiltinIcons = AValue then exit;
|
||||||
|
FUseBuiltinIcons := AValue;
|
||||||
|
Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomShellTreeView.DoCreateNodeClass(
|
procedure TCustomShellTreeView.DoCreateNodeClass(
|
||||||
var NewNodeClass: TTreeNodeClass);
|
var NewNodeClass: TTreeNodeClass);
|
||||||
@ -608,6 +625,7 @@ constructor TCustomShellTreeView.Create(AOwner: TComponent);
|
|||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
FInitialRoot := '';
|
FInitialRoot := '';
|
||||||
|
FUseBuiltinIcons := true;
|
||||||
|
|
||||||
// Initial property values
|
// Initial property values
|
||||||
FObjectTypes:= [otFolders];
|
FObjectTypes:= [otFolders];
|
||||||
@ -984,6 +1002,65 @@ begin
|
|||||||
FOnAddItem(Self, ABasePath, AFileInfo, CanAdd);
|
FOnAddItem(Self, ABasePath, AFileInfo, CanAdd);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$ifdef mswindows}
|
||||||
|
{ Extracts the windows shell icon of the specified file. }
|
||||||
|
function GetShellIcon(const AFileName: WideString): TIcon;
|
||||||
|
var
|
||||||
|
FileInfo: TSHFileInfoW;
|
||||||
|
imgHandle: DWORD_PTR;
|
||||||
|
begin
|
||||||
|
imgHandle := SHGetFileInfoW(PWideChar(AFileName), 0, FileInfo, SizeOf(FileInfo),
|
||||||
|
SHGFI_ICON + SHGFI_SMALLICON + SHGFI_SYSICONINDEX);
|
||||||
|
if imgHandle <> 0 then
|
||||||
|
begin
|
||||||
|
Result := TIcon.Create;
|
||||||
|
Result.Handle := FileInfo.hIcon;
|
||||||
|
end else
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomShellTreeView.DrawBuiltinIcon(ANode: TTreeNode; ARect: TRect): TSize;
|
||||||
|
var
|
||||||
|
filename: widestring;
|
||||||
|
ico: TIcon;
|
||||||
|
begin
|
||||||
|
if FUseBuiltinIcons then
|
||||||
|
begin
|
||||||
|
fileName := widestring(GetPathFromNode(ANode));
|
||||||
|
ico := GetShellIcon(fileName);
|
||||||
|
try
|
||||||
|
Canvas.Draw(ARect.Left, (ARect.Top + ARect.Bottom - ico.Height) div 2, ico);
|
||||||
|
Result := Types.Size(ico.Width, ico.Height);
|
||||||
|
finally
|
||||||
|
ico.Free;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
Result := Types.Size(0, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomShellTreeView.GetBuiltinIconSize: TSize;
|
||||||
|
var
|
||||||
|
ico: TIcon;
|
||||||
|
begin
|
||||||
|
if FUseBuiltinIcons then
|
||||||
|
begin
|
||||||
|
if (FBuiltinIconSize.CX > 0) and (FBuiltinIconSize.CY > 0) then
|
||||||
|
Result := FBuiltinIconSize
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
ico := GetShellIcon(WideString('C:'));
|
||||||
|
try
|
||||||
|
Result := Types.Size(ico.Width, ico.Height);
|
||||||
|
FBuiltinIconSize := Result;
|
||||||
|
finally
|
||||||
|
ico.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
Result := Types.Size(0, 0);
|
||||||
|
end;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
function TCustomShellTreeView.GetPathFromNode(ANode: TTreeNode): string;
|
function TCustomShellTreeView.GetPathFromNode(ANode: TTreeNode): string;
|
||||||
begin
|
begin
|
||||||
if Assigned(ANode) then
|
if Assigned(ANode) then
|
||||||
@ -998,7 +1075,6 @@ begin
|
|||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TCustomShellTreeView.Refresh(ANode: TTreeNode);
|
procedure TCustomShellTreeView.Refresh(ANode: TTreeNode);
|
||||||
//nil will refresh root
|
//nil will refresh root
|
||||||
var
|
var
|
||||||
@ -1271,8 +1347,6 @@ begin
|
|||||||
for i := 0 to sl.Count - 1 do debugln(['sl[',i,']="',sl[i],'"']);
|
for i := 0 to sl.Count - 1 do debugln(['sl[',i,']="',sl[i],'"']);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
try
|
try
|
||||||
Node := Items.GetFirstVisibleNode;
|
Node := Items.GetFirstVisibleNode;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user