Pārlūkot izejas kodu

Windows shell local file copy status window is centered on the main window

Source commit: 91a0daf05a54079315906c22dca82a0cc4d5a77a
Martin Prikryl 3 nedēļas atpakaļ
vecāks
revīzija
b38cf104cc

+ 62 - 0
source/forms/CustomScpExplorer.cpp

@@ -280,6 +280,11 @@ __fastcall TCustomScpExplorerForm::TCustomScpExplorerForm(TComponent* Owner):
   // (necessary for "explorer" only, as "commander" loads it for its drive menu)
   DriveInfo->NeedData();
   UsesCustomColorMode(this);
+
+  FOperationStatusWindow = nullptr;
+  FOperationStatusWindowTimer = nullptr;
+  DebugAssert(OnActiveFormChange == nullptr);
+  OnActiveFormChange = ActiveFormChange;
 }
 //---------------------------------------------------------------------------
 __fastcall TCustomScpExplorerForm::~TCustomScpExplorerForm()
@@ -12382,3 +12387,60 @@ void TCustomScpExplorerForm::ChangeDirViewStyle(TOperationSide Side, TDirViewSty
     UpdateControls();
   }
 }
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::ActiveFormChange(TObject *)
+{
+  HWND WindowHandle = GetForegroundWindow();
+  if ((WindowHandle != nullptr) && (WindowHandle != FOperationStatusWindow))
+  {
+    DWORD ProcessId;
+    if ((GetWindowThreadProcessId(WindowHandle, &ProcessId) != 0) &&
+        (ProcessId == GetCurrentProcessId()))
+    {
+      UnicodeString ClassName;
+      ClassName.SetLength(256);
+      GetClassName(WindowHandle, ClassName.c_str(), ClassName.Length());
+      PackStr(ClassName);
+      if ((ClassName == L"OperationStatusWindow") &&
+          !IsIconic(WindowHandle))
+      {
+        FOperationStatusWindow = WindowHandle;
+        PlaceOperationStatusWindow();
+        FOperationStatusWindowIterations = 0;
+        if (FOperationStatusWindowTimer == nullptr)
+        {
+          FOperationStatusWindowTimer = new TTimer(this);
+        }
+        FOperationStatusWindowTimer->OnTimer = OperationStatusWindowTimer;
+        FOperationStatusWindowTimer->Interval = 50;
+        FOperationStatusWindowTimer->Enabled = true;
+      }
+    }
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall TCustomScpExplorerForm::OperationStatusWindowTimer(TObject *)
+{
+  FOperationStatusWindowIterations++;
+  PlaceOperationStatusWindow();
+  if (FOperationStatusWindowIterations == 5)
+  {
+    SAFE_DESTROY(FOperationStatusWindowTimer);
+  }
+}
+//---------------------------------------------------------------------------
+void TCustomScpExplorerForm::PlaceOperationStatusWindow()
+{
+  TRect CurRect;
+  if ((Screen->ActiveForm != nullptr) &&
+      GetWindowRect(FOperationStatusWindow, &CurRect))
+  {
+    TRect Rect = CurRect;
+    CenterFormOn(Rect, Screen->ActiveForm, nullptr);
+    if (Rect != CurRect)
+    {
+      // What TWinControl.SetBounds does
+      SetWindowPos(FOperationStatusWindow, 0, Rect.Left, Rect.Top, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
+    }
+  }
+}

+ 6 - 0
source/forms/CustomScpExplorer.h

@@ -321,6 +321,9 @@ private:
   bool FUpdatingSessionTabs;
   TCalculateSizeOperation * FCalculateSizeOperation;
   TTBXTheme * FHiContrastTheme;
+  HWND FOperationStatusWindow;
+  TTimer * FOperationStatusWindowTimer;
+  int FOperationStatusWindowIterations;
 
   bool __fastcall GetEnableFocusedOperation(TOperationSide Side, int FilesOnly);
   bool __fastcall GetEnableSelectedOperation(TOperationSide Side, int FilesOnly);
@@ -381,6 +384,9 @@ private:
   void __fastcall StoreTransitionCloseClick(TObject * Sender);
   void __fastcall StoreTransitionLinkClick(TObject * Sender);
   void InitializeRemoteThumbnailMask();
+  void __fastcall OperationStatusWindowTimer(TObject *);
+  void __fastcall ActiveFormChange(TObject *);
+  void PlaceOperationStatusWindow();
 
 protected:
   TOperationSide FCurrentSide;

+ 31 - 24
source/windows/VCLCommon.cpp

@@ -17,6 +17,7 @@
 //---------------------------------------------------------------------------
 const UnicodeString ContextSeparator(TraceInitStr(L"\x00BB"));
 const UnicodeString LinkAppLabelMark(TraceInitStr(UnicodeString(L" ") + ContextSeparator));
+TNotifyEvent OnActiveFormChange = nullptr;
 //---------------------------------------------------------------------------
 class TFormCustomizationComponent : public TComponent
 {
@@ -959,6 +960,14 @@ static void __fastcall FormWindowProc(void * Data, TMessage & Message)
     CountClicksForWindowPrint(AForm);
     WndProc(Message);
   }
+  else if (Message.Msg == WM_ACTIVATE)
+  {
+    if (OnActiveFormChange != nullptr)
+    {
+      OnActiveFormChange(nullptr);
+    }
+    WndProc(Message);
+  }
   else
   {
     WndProc(Message);
@@ -1752,6 +1761,26 @@ void __fastcall CutFormToDesktop(TForm * Form)
   }
 }
 //---------------------------------------------------------------------------
+void CenterFormOn(TRect & Bounds, TCustomForm * CenterForm, Forms::TMonitor * CenterMonitor)
+{
+  int X, Y;
+  if (CenterForm != NULL)
+  {
+    TForm * PublicCenterForm = reinterpret_cast<TForm *>(CenterForm);
+    X = ((PublicCenterForm->Width - Bounds.Width()) / 2) + PublicCenterForm->Left;
+    Y = ((PublicCenterForm->Height - Bounds.Height()) / 2) + PublicCenterForm->Top;
+  }
+  else
+  {
+    X = (CenterMonitor->Width - Bounds.Width()) / 2;
+    Y = (CenterMonitor->Height - Bounds.Height()) / 2;
+  }
+
+  X = std::max(X, 0);
+  Y = std::max(Y, 0);
+  Bounds.SetLocation(X, Y);
+}
+//---------------------------------------------------------------------------
 void __fastcall UpdateFormPosition(TCustomForm * Form, TPosition Position)
 {
   if ((Position == poScreenCenter) ||
@@ -1771,30 +1800,8 @@ void __fastcall UpdateFormPosition(TCustomForm * Form, TPosition Position)
     }
 
     TRect Bounds = Form->BoundsRect;
-    int X, Y;
-    if (CenterForm != NULL)
-    {
-      X = ((((TForm *)CenterForm)->Width - Bounds.Width()) / 2) +
-        ((TForm *)CenterForm)->Left;
-      Y = ((((TForm *)CenterForm)->Height - Bounds.Height()) / 2) +
-        ((TForm *)CenterForm)->Top;
-    }
-    else
-    {
-      X = (Form->Monitor->Width - Bounds.Width()) / 2;
-      Y = (Form->Monitor->Height - Bounds.Height()) / 2;
-    }
-
-    if (X < 0)
-    {
-      X = 0;
-    }
-    if (Y < 0)
-    {
-      Y = 0;
-    }
-
-    Form->SetBounds(X, Y, Bounds.Width(), Bounds.Height());
+    CenterFormOn(Bounds, CenterForm, Form->Monitor);
+    Form->SetBounds(Bounds.Left, Bounds.Top, Bounds.Width(), Bounds.Height());
   }
 }
 //---------------------------------------------------------------------------

+ 2 - 0
source/windows/VCLCommon.h

@@ -9,6 +9,7 @@
 #include <HistoryComboBox.hpp>
 //---------------------------------------------------------------------------
 extern const UnicodeString ContextSeparator;
+extern TNotifyEvent OnActiveFormChange;
 //---------------------------------------------------------------------------
 void __fastcall FixListColumnWidth(TListView * TListView, int Index);
 void __fastcall AutoSizeListColumnsWidth(TListView * ListView, int ColumnToShrinkIndex = -1);
@@ -59,6 +60,7 @@ void __fastcall SetVerticalControlsOrder(TControl ** ControlsOrder, int Count);
 void __fastcall SetHorizontalControlsOrder(TControl ** ControlsOrder, int Count);
 void __fastcall MakeNextInTabOrder(TWinControl * Control, TWinControl * After);
 void __fastcall CutFormToDesktop(TForm * Form);
+void CenterFormOn(TRect & Bounds, TCustomForm * CenterForm, Forms::TMonitor * CenterMonitor);
 void __fastcall UpdateFormPosition(TCustomForm * Form, TPosition Position);
 void __fastcall ResizeForm(TCustomForm * Form, int Width, int Height);
 TComponent * __fastcall GetFormOwner();