瀏覽代碼

Properly drawing background of selectable value displays on tab controls on Windows 11

(would also help on Windows XP, but we do not support that anymore)

Source commit: 23db1a3f17f5cd240650c5005fa33702ff7d7a2a
Martin Prikryl 7 月之前
父節點
當前提交
3a887624f6
共有 1 個文件被更改,包括 56 次插入12 次删除
  1. 56 12
      source/windows/VCLCommon.cpp

+ 56 - 12
source/windows/VCLCommon.cpp

@@ -307,6 +307,45 @@ static void __fastcall ReadOnlyEditContextPopup(void * /*Data*/, TObject * Sende
   }
 }
 //---------------------------------------------------------------------------
+class TPublicWinControl : public TWinControl
+{
+friend TWndMethod __fastcall ControlWndProc(TWinControl * Control);
+friend void __fastcall InstallPathWordBreakProc(TWinControl * Control);
+};
+//---------------------------------------------------------------------------
+TWndMethod __fastcall ControlWndProc(TWinControl * Control)
+{
+  TPublicWinControl * PublicWinControl = static_cast<TPublicWinControl *>(Control);
+  return &PublicWinControl->WndProc;
+}
+//---------------------------------------------------------------------------
+static void __fastcall ReadOnlyEditWindowProc(void * Data, TMessage & Message)
+{
+  TCustomEdit * Edit = static_cast<TCustomEdit *>(Data);
+  TCustomStyleServices * AStyleServices;
+  if ((Message.Msg == CN_CTLCOLORSTATIC) && Edit->ReadOnly && (AStyleServices = StyleServices(Edit))->Enabled)
+  {
+    // VCL_COPY Based on TCustomStaticText.CNCtlColorStatic
+
+    // Pure Win32 alternative can be seen at:
+    // https://stackoverflow.com/a/75764544/850848
+    // (see my comment to the answer)
+
+    HDC ControlDC = reinterpret_cast<HDC>(Message.WParam);
+    HWND ControlHandle = reinterpret_cast<HWND>(Message.LParam);
+    DebugAssert(ControlHandle == Edit->Handle);
+
+    SetBkMode(ControlDC, TRANSPARENT);
+    AStyleServices->DrawParentBackground(ControlHandle, ControlDC, NULL, false);
+
+    Message.Result = reinterpret_cast<LRESULT>(GetStockObject(NULL_BRUSH));
+  }
+  else
+  {
+    ControlWndProc(Edit)(Message);
+  }
+}
+//---------------------------------------------------------------------------
 void __fastcall DoReadOnlyControl(TControl * Control, bool ReadOnly, bool Color)
 {
   if (dynamic_cast<TCustomEdit *>(Control) != NULL)
@@ -314,6 +353,23 @@ void __fastcall DoReadOnlyControl(TControl * Control, bool ReadOnly, bool Color)
     TEdit * Edit = static_cast<TEdit *>(Control);
     Edit->ReadOnly = ReadOnly;
     TMemo * Memo = dynamic_cast<TMemo *>(Control);
+
+    TWinControl * Parent = Edit->Parent;
+    while (Parent != NULL)
+    {
+      // Not necessary, just to limit impact and conflicts
+      if (dynamic_cast<TTabSheet *>(Parent) != NULL)
+      {
+        TWndMethod WindowProc = MakeMethod<TWndMethod>(Edit, ReadOnlyEditWindowProc);
+        if ((Edit->WindowProc != WindowProc) && DebugAlwaysTrue(Edit->WindowProc == ControlWndProc(Edit)))
+        {
+          Edit->WindowProc = WindowProc;
+        }
+        break;
+      }
+      Parent = Parent->Parent;
+    }
+
     if (ReadOnly)
     {
       if (Color)
@@ -466,18 +522,6 @@ UnicodeString __fastcall FormatFormCaption(
   }
   return Result;
 }
-//---------------------------------------------------------------------------
-class TPublicWinControl : public TWinControl
-{
-friend TWndMethod __fastcall ControlWndProc(TWinControl * Control);
-friend void __fastcall InstallPathWordBreakProc(TWinControl * Control);
-};
-//---------------------------------------------------------------------------
-TWndMethod __fastcall ControlWndProc(TWinControl * Control)
-{
-  TPublicWinControl * PublicWinControl = static_cast<TPublicWinControl *>(Control);
-  return &PublicWinControl->WndProc;
-}
 //---------------------------------------------------------------------
 class TPublicControl : public TControl
 {