Преглед на файлове

Bug 1576: Failure when starting with window position configuration, saved on lower DPI, that does not fit anymore on lower resolution caused by higher DPI

https://winscp.net/tracker/1576

Source commit: 53b884cc82e0d2c515188523a3ebcabe7862719e
Martin Prikryl преди 8 години
родител
ревизия
b0b9c55d6b
променени са 3 файла, в които са добавени 50 реда и са изтрити 20 реда
  1. 18 6
      source/windows/Tools.cpp
  2. 31 14
      source/windows/VCLCommon.cpp
  3. 1 0
      source/windows/WinApi.h

+ 18 - 6
source/windows/Tools.cpp

@@ -220,20 +220,32 @@ void __fastcall RestoreForm(UnicodeString Data, TForm * Form, bool PositionOnly)
            (Bounds.Top < Monitor->Top) ||
            (Bounds.Top > Monitor->Top + Monitor->WorkareaRect.Height() - 20)))
       {
-        if (Monitor->Primary)
+        bool ExplicitPlacing = !Monitor->Primary;
+        if (!ExplicitPlacing)
         {
+          TPosition Position;
           if ((Application->MainForm == NULL) || (Application->MainForm == Form))
           {
-            Form->Position = poDefaultPosOnly;
+            Position = poDefaultPosOnly;
           }
           else
           {
-            Form->Position = poOwnerFormCenter;
+            Position = poOwnerFormCenter;
+          }
+
+          // If handle is allocated already, changing Position reallocates it, what brings lot of nasty side effects.
+          if (Form->HandleAllocated() && (Form->Position != Position))
+          {
+            ExplicitPlacing = true;
+          }
+          else
+          {
+            Form->Width = Bounds.Width();
+            Form->Height = Bounds.Height();
           }
-          Form->Width = Bounds.Width();
-          Form->Height = Bounds.Height();
         }
-        else
+
+        if (ExplicitPlacing)
         {
           // when positioning on non-primary monitor, we need
           // to handle that ourselves, so place window to center

+ 31 - 14
source/windows/VCLCommon.cpp

@@ -543,6 +543,26 @@ void __fastcall RecordFormImplicitRescale(TForm * Form)
   }
 }
 //---------------------------------------------------------------------------
+static void GetFormRescaleRatio(TForm * Form, int PixelsPerInch, int & M, int & D)
+{
+  TFormRescaleComponent * FormRescaleComponent = GetFormRescaleComponent(Form);
+  TRatio ReverseRescaleKeyRatio(Form->PixelsPerInch, PixelsPerInch);
+  if (FormRescaleComponent->RatioMap.count(ReverseRescaleKeyRatio) > 0)
+  {
+    M = FormRescaleComponent->RatioMap[ReverseRescaleKeyRatio].second;
+    D = FormRescaleComponent->RatioMap[ReverseRescaleKeyRatio].first;
+  }
+  else
+  {
+    M = GetTextHeightAtPixelsPerInch(Form, PixelsPerInch);
+    D = GetTextHeightAtPixelsPerInch(Form, Form->PixelsPerInch);
+  }
+
+
+  TRatio RescaleKeyRatio(PixelsPerInch, Form->PixelsPerInch);
+  FormRescaleComponent->RatioMap[RescaleKeyRatio] = TRatio(M, D);
+}
+//---------------------------------------------------------------------------
 static void __fastcall ChangeFormPixelsPerInch(TForm * Form, int PixelsPerInch)
 {
   RecordFormImplicitRescale(Form);
@@ -555,20 +575,7 @@ static void __fastcall ChangeFormPixelsPerInch(TForm * Form, int PixelsPerInch)
     TAutoFlag RescalingFlag(FormRescaleComponent->Rescaling);
 
     int M, D;
-    TRatio ReverseRescaleKeyRatio(Form->PixelsPerInch, PixelsPerInch);
-    if (FormRescaleComponent->RatioMap.count(ReverseRescaleKeyRatio) > 0)
-    {
-      M = FormRescaleComponent->RatioMap[ReverseRescaleKeyRatio].second;
-      D = FormRescaleComponent->RatioMap[ReverseRescaleKeyRatio].first;
-    }
-    else
-    {
-      M = GetTextHeightAtPixelsPerInch(Form, PixelsPerInch);
-      D = GetTextHeightAtPixelsPerInch(Form, Form->PixelsPerInch);
-    }
-
-    TRatio RescaleKeyRatio(PixelsPerInch, Form->PixelsPerInch);
-    FormRescaleComponent->RatioMap[RescaleKeyRatio] = TRatio(M, D);
+    GetFormRescaleRatio(Form, PixelsPerInch, M, D);
 
     Form->PixelsPerInch = PixelsPerInch;
     TPublicForm * PublicCustomForm = static_cast<TPublicForm *>(Form);
@@ -788,6 +795,16 @@ inline void __fastcall DoFormWindowProc(TCustomForm * Form, TWndMethod WndProc,
       WndProc(Message);
     }
   }
+  else if (Message.Msg == WM_GETDPISCALEDSIZE)
+  {
+    WndProc(Message);
+    int M, D;
+    GetFormRescaleRatio(AForm, LOWORD(Message.WParam), M, D);
+    SIZE & Size = *(reinterpret_cast<SIZE *>(Message.LParam));
+    Size.cx = MulDiv(Size.cx, M, D);
+    Size.cy = MulDiv(Size.cy, M, D);
+    Message.Result = TRUE;
+  }
   else if (Message.Msg == WM_DPICHANGED)
   {
     ChangeFormPixelsPerInch(AForm, LOWORD(Message.WParam));

+ 1 - 0
source/windows/WinApi.h

@@ -12,6 +12,7 @@ typedef BOOL WINAPI (* AddClipboardFormatListenerProc)(HWND hwnd);
 typedef BOOL WINAPI (* RemoveClipboardFormatListenerProc)(HWND hwnd);
 //---------------------------------------------------------------------------
 #define WM_DPICHANGED 0x02E0
+#define WM_GETDPISCALEDSIZE 0x02E4
 //---------------------------------------------------------------------------
 typedef enum _Monitor_DPI_Type {
   MDT_Effective_DPI  = 0,