mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
747 lines
21 KiB
ObjectPascal
747 lines
21 KiB
ObjectPascal
unit ListViewColProperties;
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, ComCtrls, Contnrs;
|
|
|
|
type
|
|
TCustomListViewColProperty = class(TObject)
|
|
Alignment: TAlignment;
|
|
Caption: string;
|
|
Width: Integer;
|
|
MaxWidth: Integer;
|
|
MinWidth: Integer;
|
|
Visible: Boolean;
|
|
Order: Integer;
|
|
|
|
constructor Create(AOrder: Integer);
|
|
end;
|
|
|
|
type
|
|
TCustomListViewColProperties = class(TPersistent)
|
|
private
|
|
FChanged: Boolean;
|
|
FOnChange: TNotifyEvent;
|
|
FUpdating: Integer;
|
|
FProperties: TObjectList;
|
|
FCreated: Boolean;
|
|
function GetColumns: TListColumns;
|
|
function GetCount: Integer;
|
|
function GetOrderStr: string;
|
|
procedure CheckBounds(Index: Integer);
|
|
procedure SetWidthsStr(Value: string; PixelsPerInch: Integer);
|
|
function GetWidthsStr: string;
|
|
procedure SetOrderStr(Value: string);
|
|
protected
|
|
FListView: TCustomListView;
|
|
FListViewManaged: Boolean;
|
|
FConstraintsInitialized: Boolean;
|
|
function GetAlignments(Index: Integer): TAlignment;
|
|
function GetParamsStr: string; virtual;
|
|
function GetVisible(Index: Integer): Boolean;
|
|
function GetWidths(Index: Integer): Integer;
|
|
procedure SetAlignments(Index: Integer; Value: TAlignment);
|
|
procedure SetVisibleInternal(Index: Integer; Value: Boolean; SaveWidth: Boolean);
|
|
procedure SetVisible(Index: Integer; Value: Boolean);
|
|
procedure SetWidths(Index: Integer; Value: Integer);
|
|
function GetCaptions(Index: Integer): string;
|
|
procedure Changed; virtual;
|
|
procedure SetCaptions(Index: Integer; Value: string); virtual;
|
|
procedure SetParamsStr(Value: string); virtual;
|
|
procedure UpdateListView;
|
|
procedure UpdateFromListView;
|
|
procedure UpdateOrderFromListView;
|
|
procedure UpdateListViewOrder;
|
|
function GetProperties(Index: Integer): TCustomListViewColProperty;
|
|
function GetIndexByOrder(Order: Integer): Integer;
|
|
function ColumnsExists: Boolean;
|
|
procedure SetRuntimeVisible(Index: Integer; Value: Boolean; SaveWidth: Boolean);
|
|
function GetColumn(Index: Integer): TListColumn;
|
|
procedure CreateProperties(ACount: Integer);
|
|
function DefaultConstraint(Value: Integer; Visible: Boolean; Def: Integer): Integer;
|
|
|
|
property Columns: TListColumns read GetColumns stored False;
|
|
public
|
|
constructor Create(ListView: TCustomListView; ColCount: Integer);
|
|
destructor Destroy; override;
|
|
procedure EndUpdate;
|
|
procedure BeginUpdate;
|
|
procedure ListViewWndCreated;
|
|
procedure ListViewWndDestroying;
|
|
procedure ListViewWndDestroyed;
|
|
procedure ChangeScale(M, D: Integer);
|
|
property Count: Integer read GetCount stored False;
|
|
property Alignments[Index: Integer]: TAlignment read GetAlignments write SetAlignments;
|
|
property Captions[Index: Integer]: string read GetCaptions write SetCaptions;
|
|
property Widths[Index: Integer]: Integer read GetWidths write SetWidths;
|
|
property Visible[Index: Integer]: Boolean read GetVisible write SetVisible;
|
|
procedure RecreateColumns;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
property ParamsStr: string read GetParamsStr write SetParamsStr stored False;
|
|
end; { TCustomListViewColProperties }
|
|
|
|
type
|
|
TListViewColProperties = class(TCustomListViewColProperties)
|
|
published
|
|
end; { TListViewColProperties }
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, CommCtrl, Windows, PasTools, Controls, Forms;
|
|
|
|
const
|
|
DefaultListViewMaxWidth = 1000;
|
|
DefaultListViewMinWidth = 20;
|
|
|
|
{ TODO : V ListView zamezit zmenu velikosti neviditelnych sloupecku }
|
|
|
|
constructor TCustomListViewColProperty.Create(AOrder: Integer);
|
|
begin
|
|
Alignment := taLeftJustify;
|
|
Caption := '';
|
|
Width := 50;
|
|
Visible := True;
|
|
Order := AOrder;
|
|
end;
|
|
|
|
{ TCustomListViewColProperties }
|
|
|
|
constructor TCustomListViewColProperties.Create(
|
|
ListView: TCustomListView; ColCount: Integer);
|
|
var
|
|
ACount: Integer;
|
|
begin
|
|
// This contructor (and constructors of descendants)
|
|
// is only even called from implementations of
|
|
// TCustomNortonLikeListView.NewColProperties
|
|
inherited Create;
|
|
|
|
FConstraintsInitialized := False;
|
|
FCreated := False;
|
|
FUpdating := 0;
|
|
FChanged := False;
|
|
// ColCount is not 0 for file panels (TDirView and TCustomUnixDirView).
|
|
// It is 0 otherwise.
|
|
FListViewManaged := (ColCount = 0);
|
|
FListView := ListView;
|
|
|
|
FProperties := TObjectList.Create;
|
|
if FListViewManaged then ACount := GetColumns.Count
|
|
else ACount := ColCount;
|
|
|
|
CreateProperties(ACount);
|
|
|
|
if not Assigned(FListView) then
|
|
raise Exception.Create('NIL ListView pointer.');
|
|
end;
|
|
|
|
destructor TCustomListViewColProperties.Destroy;
|
|
begin
|
|
inherited;
|
|
FProperties.Free;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetWidthsStr(Value: string; PixelsPerInch: Integer);
|
|
var
|
|
ColStr: string;
|
|
Index: Integer;
|
|
NeedInvalidate, NewVisible: Boolean;
|
|
NewWidth: Integer;
|
|
begin
|
|
Index := 0;
|
|
NeedInvalidate := False;
|
|
BeginUpdate;
|
|
try
|
|
while (Value <> '') and (Index < Count) do
|
|
begin
|
|
ColStr := CutToChar(Value, ';', True);
|
|
NewWidth := LoadDimension(StrToInt(CutToChar(ColStr, ',', True)), PixelsPerInch, FListView);
|
|
Widths[Index] := NewWidth;
|
|
NewVisible := Boolean(StrToInt(CutToChar(ColStr, ',', True)));
|
|
if Visible[Index] <> NewVisible then
|
|
begin
|
|
// As we are within BeginUpdate guard, the width set just above is not propadated to WinAPI.
|
|
// As reading width retrieves it from WinAPI (if the control is already allocated), we actually save wrong width.
|
|
SetVisibleInternal(Index, NewVisible, False);
|
|
NeedInvalidate := True;
|
|
end;
|
|
Inc(Index);
|
|
end;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
|
|
// When visibility changes (particularly while reseting layout) redraw is needed
|
|
// (Invalidate is called in SetVisible too, but maybe it has no effect there, because it is within BeginUpdate/EndUpdate)
|
|
if NeedInvalidate and FListView.HandleAllocated then
|
|
FListView.Invalidate;
|
|
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetWidthsStr: string;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Result := '';
|
|
for Index := 0 to Count-1 do
|
|
begin
|
|
Result := Format('%s;%d,%d', [Result, SaveDimension(Widths[Index]), Integer(Visible[Index])]);
|
|
end;
|
|
Delete(Result, 1, 1);
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.BeginUpdate;
|
|
begin
|
|
Columns.BeginUpdate;
|
|
Inc(FUpdating);
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.EndUpdate;
|
|
begin
|
|
Columns.EndUpdate;
|
|
Dec(FUpdating);
|
|
if FUpdating = 0 then
|
|
begin
|
|
// call Changed() even when FChange is false
|
|
Changed;
|
|
|
|
FChanged := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.Changed;
|
|
begin
|
|
if FUpdating > 0 then FChanged := True
|
|
else
|
|
if Assigned(FOnChange) then FOnChange(Self);
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.CheckBounds(Index: Integer);
|
|
begin
|
|
if (Index < 0) or (Index >= Count) then
|
|
raise Exception.Create('Index out of bounds.');
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetProperties(Index: Integer): TCustomListViewColProperty;
|
|
begin
|
|
Result := TCustomListViewColProperty(FProperties.Items[Index]);
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetIndexByOrder(Order: Integer): Integer;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
if GetProperties(I).Order = Order then
|
|
begin
|
|
Result := I;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
raise Exception.Create('Column order out of bounds');
|
|
end;
|
|
|
|
function TCustomListViewColProperties.ColumnsExists: Boolean;
|
|
begin
|
|
Result := FListView.HandleAllocated;
|
|
if Result and (not FCreated) and (not FListViewManaged) then
|
|
UpdateListView;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetAlignments(Index: Integer; Value: TAlignment);
|
|
begin
|
|
CheckBounds(Index);
|
|
if Alignments[Index] <> Value then
|
|
begin
|
|
GetProperties(Index).Alignment := Value;
|
|
if ColumnsExists then GetColumn(Index).Alignment := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetCaptions(Index: Integer; Value: string);
|
|
begin
|
|
CheckBounds(Index);
|
|
if Captions[Index] <> Value then
|
|
begin
|
|
if ColumnsExists then GetColumn(Index).Caption := Value
|
|
else GetProperties(Index).Caption := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetAlignments(Index: Integer): TAlignment;
|
|
begin
|
|
CheckBounds(Index);
|
|
if ColumnsExists then Result := GetColumn(Index).Alignment
|
|
else Result := GetProperties(Index).Alignment;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetCaptions(Index: Integer): string;
|
|
begin
|
|
CheckBounds(Index);
|
|
if ColumnsExists then Result := GetColumn(Index).Caption
|
|
else Result := GetProperties(Index).Caption;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetOrderStr(Value: string);
|
|
var
|
|
Order, Index: Integer;
|
|
Properties: TCustomListViewColProperty;
|
|
STemp: string;
|
|
Phase: Boolean;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
for Index := 0 to Count - 1 do
|
|
GetProperties(Index).Order := -1;
|
|
|
|
// First order invisible columns (not True), then visible (not not True)
|
|
Phase := True;
|
|
Order := 0;
|
|
|
|
repeat
|
|
Phase := not Phase;
|
|
STemp := Value;
|
|
while (STemp <> '') and (Order < Count) do
|
|
begin
|
|
Index := StrToInt(CutToChar(STemp, ';', True));
|
|
Properties := GetProperties(Index);
|
|
if (Properties.Visible = Phase) and
|
|
(Properties.Order < 0) { robustness } then
|
|
begin
|
|
Properties.Order := Order;
|
|
Inc(Order);
|
|
end;
|
|
end;
|
|
|
|
// add missing columns from the same visibility class
|
|
for Index := 0 to Count - 1 do
|
|
begin
|
|
Properties := GetProperties(Index);
|
|
if (Properties.Visible = Phase) and
|
|
(Properties.Order < 0) then
|
|
begin
|
|
Properties.Order := Order;
|
|
Inc(Order);
|
|
end;
|
|
end;
|
|
until Phase;
|
|
|
|
if ColumnsExists then
|
|
UpdateListViewOrder;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetParamsStr(Value: string);
|
|
var
|
|
S: string;
|
|
WidthsStr: string;
|
|
OrderStr: string;
|
|
PixelsPerInch: Integer;
|
|
begin
|
|
// TFileFindDialog uses / as separator of its settings
|
|
S := CutToChar(Value, '|', True);
|
|
WidthsStr := CutToChar(S, '@', True);
|
|
PixelsPerInch := LoadPixelsPerInch(S, FListView);
|
|
SetWidthsStr(WidthsStr, PixelsPerInch);
|
|
// Have to set order after visibility, otherwise we lost ordering of columns that are invisible by default,
|
|
// but visible by configuration (as they would get ordered to the front)
|
|
OrderStr := CutToChar(Value, '|', True);
|
|
SetOrderStr(OrderStr);
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetVisibleInternal(Index: Integer; Value: Boolean; SaveWidth: Boolean);
|
|
var
|
|
I: Integer;
|
|
Properties: TCustomListViewColProperty;
|
|
begin
|
|
CheckBounds(Index);
|
|
if Visible[Index] <> Value then
|
|
begin
|
|
Properties := GetProperties(Index);
|
|
|
|
if ColumnsExists then
|
|
UpdateOrderFromListView;
|
|
|
|
if Value then
|
|
begin
|
|
// shown column is moved to the back
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
if GetProperties(I).Order > Properties.Order then
|
|
Dec(GetProperties(I).Order);
|
|
end;
|
|
Properties.Order := Count - 1;
|
|
|
|
if ColumnsExists then
|
|
UpdateListViewOrder;
|
|
|
|
// show only after reordering column
|
|
Properties.Visible := True;
|
|
|
|
if ColumnsExists then
|
|
SetRuntimeVisible(Index, True, SaveWidth);
|
|
end
|
|
else
|
|
begin
|
|
// hide before reordering column
|
|
Properties.Visible := False;
|
|
|
|
if ColumnsExists then
|
|
SetRuntimeVisible(Index, False, SaveWidth);
|
|
|
|
// hidden column is moved to the front,
|
|
// unless column to the left is not hidden already
|
|
// (or unless it is first already, in which case the
|
|
// condition in the loop is never satisfied)
|
|
if (Properties.Order > 0) and
|
|
GetProperties(GetIndexByOrder(Properties.Order - 1)).Visible then
|
|
begin
|
|
for I := 0 to Count - 1 do
|
|
begin
|
|
if GetProperties(I).Order < Properties.Order then
|
|
Inc(GetProperties(I).Order);
|
|
end;
|
|
Properties.Order := 0;
|
|
end;
|
|
|
|
if ColumnsExists then
|
|
UpdateListViewOrder;
|
|
end;
|
|
|
|
Changed;
|
|
|
|
// It does not refresh itself at last one on Win7 when DoubleBuffered
|
|
if FListView.HandleAllocated then
|
|
FListView.Invalidate;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetVisible(Index: Integer; Value: Boolean);
|
|
begin
|
|
SetVisibleInternal(Index, Value, True);
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetRuntimeVisible(
|
|
Index: Integer; Value: Boolean; SaveWidth: Boolean);
|
|
var
|
|
Properties: TCustomListViewColProperty;
|
|
begin
|
|
// This is probably only ever called from file panels (DirViews)
|
|
// as other uses ("sychronization checklist" and "file find")
|
|
// have FListViewManaged = False and never change Visible property
|
|
// (though user can hide some columns manually in configuration storage)
|
|
with GetColumn(Index) do
|
|
begin
|
|
Properties := GetProperties(Index);
|
|
if Value then
|
|
begin
|
|
MaxWidth := Properties.MaxWidth;
|
|
MinWidth := Properties.MinWidth;
|
|
Width := Properties.Width;
|
|
end
|
|
else
|
|
begin
|
|
if SaveWidth then
|
|
Properties.Width := Width;
|
|
MaxWidth := 1;
|
|
MinWidth := 0;
|
|
Width := 0
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.SetWidths(Index: Integer; Value: Integer);
|
|
var
|
|
Properties: TCustomListViewColProperty;
|
|
begin
|
|
CheckBounds(Index);
|
|
|
|
Properties := GetProperties(Index);
|
|
|
|
if (Properties.MinWidth > 0) and (Value < Properties.MinWidth) then
|
|
begin
|
|
Value := Properties.MinWidth;
|
|
end
|
|
else
|
|
if (Properties.MaxWidth > 0) and (Value > Properties.MaxWidth) then
|
|
begin
|
|
Value := Properties.MaxWidth;
|
|
end;
|
|
|
|
if Widths[Index] <> Value then
|
|
begin
|
|
Properties.Width := Value;
|
|
if ColumnsExists and Visible[Index] then GetColumn(Index).Width := Value;
|
|
Changed;
|
|
end;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetColumns: TListColumns;
|
|
begin
|
|
Result := TListView(FListView).Columns;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetColumn(Index: Integer): TListColumn;
|
|
begin
|
|
Result := Columns[Index];
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetCount: Integer;
|
|
begin
|
|
Result := FProperties.Count;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetOrderStr: string;
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Result := '';
|
|
if ColumnsExists then
|
|
UpdateOrderFromListView;
|
|
for Index := 0 to Count - 1 do
|
|
Result := Format('%s;%d', [Result, GetIndexByOrder(Index)]);
|
|
Delete(Result, 1, 1);
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetParamsStr: string;
|
|
begin
|
|
// WORKAROUND
|
|
// Adding an additional semicolon after the list,
|
|
// to ensure that old versions that did not expect the pixels-per-inch part,
|
|
// stop at the semicolon, otherwise they try to parse the
|
|
// "last-column-width|pixels-per-inch" as integer and throw.
|
|
// For the other instance of this hack, see GetListViewStr.
|
|
// The new pixels-per-inch part is inserted after the widths part
|
|
// as parsing of this was always robust to stop at "count" elements,
|
|
// what order part was not (due to its logic of skipping hidden columns)
|
|
Result := Format('%s;@%s|%s', [GetWidthsStr, SavePixelsPerInch(FListView), GetOrderStr]);
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetVisible(Index: Integer): Boolean;
|
|
begin
|
|
CheckBounds(Index);
|
|
Result := GetProperties(Index).Visible;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.GetWidths(Index: Integer): Integer;
|
|
begin
|
|
CheckBounds(Index);
|
|
if ColumnsExists and Visible[Index] then
|
|
begin
|
|
Result := GetColumn(Index).Width;
|
|
end
|
|
else
|
|
begin
|
|
Result := GetProperties(Index).Width;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.RecreateColumns;
|
|
var
|
|
Copy: TListColumns;
|
|
begin
|
|
Copy := TListColumns.Create(nil);
|
|
try
|
|
Copy.Assign(Columns);
|
|
Columns.Assign(Copy);
|
|
finally
|
|
Copy.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.CreateProperties(ACount: Integer);
|
|
var
|
|
Index: Integer;
|
|
Properties: TCustomListViewColProperty;
|
|
begin
|
|
for Index := 0 to ACount - 1 do
|
|
begin
|
|
Properties := TCustomListViewColProperty.Create(Index);
|
|
FProperties.Add(Properties);
|
|
end;
|
|
end;
|
|
|
|
function TCustomListViewColProperties.DefaultConstraint(Value: Integer; Visible: Boolean; Def: Integer): Integer;
|
|
begin
|
|
if (Value > 0) and Visible then Result := Value
|
|
else Result := Def;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.ListViewWndCreated;
|
|
var
|
|
Index: Integer;
|
|
Properties: TCustomListViewColProperty;
|
|
Column: TListColumn;
|
|
begin
|
|
if FListViewManaged then
|
|
begin
|
|
if (FProperties.Count = 0) and (Columns.Count > 0) then
|
|
CreateProperties(Columns.Count);
|
|
|
|
UpdateFromListView;
|
|
end
|
|
else
|
|
begin
|
|
UpdateListView;
|
|
end;
|
|
|
|
Assert(ColumnsExists);
|
|
for Index := 0 to Count - 1 do
|
|
begin
|
|
Column := GetColumn(Index);
|
|
Properties := GetProperties(Index);
|
|
|
|
if not FConstraintsInitialized then
|
|
begin
|
|
Properties.MaxWidth := DefaultConstraint(Column.MaxWidth, Properties.Visible, DefaultListViewMaxWidth);
|
|
Properties.MinWidth := DefaultConstraint(Column.MinWidth, Properties.Visible, DefaultListViewMinWidth);
|
|
end;
|
|
|
|
// To apply the default constraints to columns that do not have their own
|
|
if Properties.Visible then
|
|
begin
|
|
Column.MaxWidth := Properties.MaxWidth;
|
|
if Column.Width > Column.MaxWidth then Column.Width := Column.MaxWidth;
|
|
Column.MinWidth := Properties.MinWidth;
|
|
if Column.Width < Column.MinWidth then Column.Width := Column.MinWidth;
|
|
end;
|
|
end;
|
|
|
|
FConstraintsInitialized := True;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.ListViewWndDestroying;
|
|
begin
|
|
UpdateFromListView;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.ListViewWndDestroyed;
|
|
begin
|
|
if not FListViewManaged then
|
|
FCreated := False;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.ChangeScale(M, D: Integer);
|
|
var
|
|
Index: Integer;
|
|
Properties: TCustomListViewColProperty;
|
|
Column: TListColumn;
|
|
begin
|
|
for Index := 0 to Count - 1 do
|
|
begin
|
|
Properties := GetProperties(Index);
|
|
// This is not perfect, as the constraints apply on re-scaled width before they are re-scaled themselves
|
|
if Properties.Visible and ColumnsExists then
|
|
begin
|
|
Column := GetColumn(Index);
|
|
Column.MaxWidth := MulDiv(Column.MaxWidth, M, D);
|
|
Column.MinWidth := MulDiv(Column.MinWidth, M, D);
|
|
end
|
|
else
|
|
begin
|
|
Properties.MaxWidth := MulDiv(Properties.MaxWidth, M, D);
|
|
Properties.MinWidth := MulDiv(Properties.MinWidth, M, D);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.UpdateListViewOrder;
|
|
var
|
|
Index: Integer;
|
|
Properties: TCustomListViewColProperty;
|
|
Temp: array of Integer;
|
|
begin
|
|
SetLength(Temp, Count);
|
|
// Seemingly useless,
|
|
// but probably only because we swallow HDN_ENDDRAG in TCustomIEListView.WMNotify,
|
|
// what prevents VLC from actually reordering columns collection
|
|
ListView_GetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
|
|
for Index := 0 to Count - 1 do
|
|
begin
|
|
Properties := GetProperties(Index);
|
|
Temp[Properties.Order] := Index;
|
|
end;
|
|
ListView_SetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.UpdateListView;
|
|
var
|
|
Index: Integer;
|
|
Column: TListColumn;
|
|
Properties: TCustomListViewColProperty;
|
|
begin
|
|
// Only called when FListViewManaged = False
|
|
BeginUpdate;
|
|
try
|
|
for Index := 0 to Count-1 do
|
|
begin
|
|
if Index < Columns.Count then
|
|
Column := GetColumn(Index)
|
|
else
|
|
Column := Columns.Add;
|
|
|
|
Properties := GetProperties(Index);
|
|
|
|
Column.Alignment := Properties.Alignment;
|
|
Column.Caption := Properties.Caption;
|
|
SetRuntimeVisible(Index, Properties.Visible, False);
|
|
end;
|
|
|
|
UpdateListViewOrder;
|
|
|
|
finally
|
|
FCreated := True;
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.UpdateOrderFromListView;
|
|
var
|
|
Index: Integer;
|
|
Temp: array of Integer;
|
|
begin
|
|
SetLength(Temp, Count);
|
|
ListView_GetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
|
|
for Index := 0 to Count - 1 do
|
|
begin
|
|
GetProperties(Temp[Index]).Order := Index;
|
|
end;
|
|
end;
|
|
|
|
procedure TCustomListViewColProperties.UpdateFromListView;
|
|
var
|
|
Index: Integer;
|
|
Column: TListColumn;
|
|
Properties: TCustomListViewColProperty;
|
|
begin
|
|
Assert(FProperties.Count = Columns.Count);
|
|
for Index := 0 to Count-1 do
|
|
begin
|
|
Column := GetColumn(Index);
|
|
Properties := GetProperties(Index);
|
|
|
|
Properties.Alignment := Column.Alignment;
|
|
Properties.Caption := Column.Caption;
|
|
if Properties.Visible then
|
|
begin
|
|
Properties.Width := Column.Width;
|
|
if Column.MaxWidth > 0 then
|
|
Properties.MaxWidth := Column.MaxWidth;
|
|
if Column.MinWidth > 0 then
|
|
Properties.MinWidth := Column.MinWidth;
|
|
end;
|
|
end;
|
|
|
|
UpdateOrderFromListView;
|
|
end;
|
|
|
|
end.
|