1
0
mirror of https://github.com/winscp/winscp.git synced 2026-10-24 02:28:55 +03:00

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
This commit is contained in:
Martin Prikryl
2025-03-04 14:02:57 +00:00
parent 0d64cc1278
commit 3a887624f6

View File

@@ -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
{