Prechádzať zdrojové kódy

Issue 2361 – Layout problems of by-default hidden columns on high-DPI displays

https://winscp.net/tracker/2361

Source commit: 79a9e1d15ab353e30939b9a3f7ce561febcc94bc
Martin Prikryl 6 mesiacov pred
rodič
commit
28ffba2df0

+ 48 - 48
source/packages/my/ListViewColProperties.pas

@@ -53,13 +53,13 @@ type
     procedure UpdateFromListView;
     procedure UpdateOrderFromListView;
     procedure UpdateListViewOrder;
-    procedure UpdateListViewMaxMinWidth;
     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
@@ -70,6 +70,7 @@ type
     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;
@@ -568,12 +569,17 @@ begin
   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;
-  W: Integer;
 begin
   if FListViewManaged then
   begin
@@ -587,36 +593,29 @@ begin
     UpdateListView;
   end;
 
-  if not FConstraintsInitialized then
+  Assert(ColumnsExists);
+  for Index := 0 to Count - 1 do
   begin
-    FConstraintsInitialized := True;
+    Column := GetColumn(Index);
+    Properties := GetProperties(Index);
 
-    for Index := 0 to Count - 1 do
+    if not FConstraintsInitialized then
     begin
-      Column := GetColumn(Index);
-      Properties := GetProperties(Index);
+      Properties.MaxWidth := DefaultConstraint(Column.MaxWidth, Properties.Visible, DefaultListViewMaxWidth);
+      Properties.MinWidth := DefaultConstraint(Column.MinWidth, Properties.Visible, DefaultListViewMinWidth);
+    end;
 
-      // Is this branching needed?
-      if Properties.Visible then
-      begin
-        W := Column.MaxWidth;
-        if W = 0 then W := DefaultListViewMaxWidth;
-        Properties.MaxWidth := ScaleByTextHeight(FListView, W);
-
-        W := Column.MinWidth;
-        if W = 0 then W := DefaultListViewMinWidth;
-        Properties.MinWidth := ScaleByTextHeight(FListView, W);
-      end
-        else
-      begin
-        Column.MaxWidth := ScaleByTextHeight(FListView, Column.MaxWidth);
-        Column.MinWidth := ScaleByTextHeight(FListView, Column.MinWidth);
-      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;
 
-  // To apply the default constraints to columns that do not have their own
-  UpdateListViewMaxMinWidth;
+  FConstraintsInitialized := True;
 end;
 
 procedure TCustomListViewColProperties.ListViewWndDestroying;
@@ -630,46 +629,47 @@ begin
     FCreated := False;
 end;
 
-procedure TCustomListViewColProperties.UpdateListViewOrder;
+procedure TCustomListViewColProperties.ChangeScale(M, D: Integer);
 var
   Index: Integer;
   Properties: TCustomListViewColProperty;
-  Temp: array of Integer;
+  Column: TListColumn;
 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;
+    // 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;
-  ListView_SetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
 end;
 
-procedure TCustomListViewColProperties.UpdateListViewMaxMinWidth;
+procedure TCustomListViewColProperties.UpdateListViewOrder;
 var
   Index: Integer;
-  Column: TListColumn;
   Properties: TCustomListViewColProperty;
+  Temp: array of Integer;
 begin
-  Assert(ColumnsExists);
-
-  for Index := 0 to Count-1 do
+  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
-    Column := GetColumn(Index);
     Properties := GetProperties(Index);
-
-    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;
+    Temp[Properties.Order] := Index;
   end;
+  ListView_SetColumnOrderArray(FListView.Handle, Count, PInteger(Temp));
 end;
 
 procedure TCustomListViewColProperties.UpdateListView;

+ 1 - 0
source/packages/my/NortonLikeListView.pas

@@ -1131,6 +1131,7 @@ begin
     HandleNeeded;
   end;
   inherited;
+  ColProperties.ChangeScale(M, D);
 end;
 
 end.

+ 5 - 5
source/windows/VCLCommon.cpp

@@ -987,9 +987,9 @@ void __fastcall ApplySystemSettingsOnControl(TControl * Control)
   #endif
 
   TCustomListView * ListView = dynamic_cast<TCustomListView *>(Control);
-  TCustomIEListView * IEListView = dynamic_cast<TCustomIEListView *>(Control);
-  // For IEListView, this is (somewhat) handled in the TCustomListViewColProperties
-  if ((ListView != NULL) && (IEListView == NULL))
+  TCustomNortonLikeListView * NortonLikeListView = dynamic_cast<TCustomNortonLikeListView *>(Control);
+  // For NortonLikeListView, this is (somewhat) handled in the TCustomListViewColProperties
+  if ((ListView != NULL) && (NortonLikeListView == NULL))
   {
     TListView * PublicListView = reinterpret_cast<TListView *>(ListView);
 
@@ -1003,14 +1003,14 @@ void __fastcall ApplySystemSettingsOnControl(TControl * Control)
 
   // WORKAROUND for lack of public API for mimicking Explorer-style mouse selection
   // See https://stackoverflow.com/q/15750842/850848
-  if (IEListView != NULL)
+  if (NortonLikeListView != NULL)
   {
     // It should not be a problem to call the LVM_QUERYINTERFACE
     // on earlier versions of Windows. It should be noop.
     if (IsWin7())
     {
       IListView_Win7 * ListViewIntf = NULL;
-      SendMessage(IEListView->Handle, LVM_QUERYINTERFACE, reinterpret_cast<WPARAM>(&IID_IListView_Win7), reinterpret_cast<LPARAM>(&ListViewIntf));
+      SendMessage(NortonLikeListView->Handle, LVM_QUERYINTERFACE, reinterpret_cast<WPARAM>(&IID_IListView_Win7), reinterpret_cast<LPARAM>(&ListViewIntf));
       if (ListViewIntf != NULL)
       {
         ListViewIntf->SetSelectionFlags(1, 1);