Closed klaus101 closed 1 year ago
Yes, confimed with https://wiki.freepascal.org/RichMemo I will try to solve it inside our package
(Seeing the image above:) yes, control's main window (and borders) were also light, but i didn't mention that -sorry!-, because i had sorted it out early via Color := clWindow and BorderStyle := bsNone.
Some thoughts .. Unfortunately the TRichMemo, which at the end is derived from a TCustomMemo, is not covered by the custommemo callback, but nevertheless. The workaround does work fine, but a "SetWindowTheme(Window, 'DarkMode_Explorer'" would be somehow not very intuitive to use for a TMemo. Whereas the proccedure "EnableDarkStyle" already does just the same. It's simply not exposed to be callable from outside yet. But it’s esay to define it as a public procedure ("uses Windows" must be shifted a bit upwards for that).
Better, if a similar proceedeure covers "Color" and "BorderStyle" too --- just as "TWin32WSCustomMemoDark.CreateHandle" already does. So, in sum, why not do something like:
interface
uses
Windows, // for to make HWND known
LCLVersion, uDarkStyleParams, uDarkStyleSchemes;
.....
procedure TryEnforceDarkStyle(Window: HWND);
implementation
uses
//Classes, SysUtils, Win32Int, WSLCLClasses, Forms, Windows, Win32Proc, Menus,
Classes, SysUtils, Win32Int, WSLCLClasses, Forms, Win32Proc, Menus,
....
procedure EnableDarkStyle(Window: HWND);
begin
AllowDarkModeForWindow(Window, True);
SetWindowTheme(Window, 'DarkMode_Explorer', nil);
SendMessageW(Window, WM_THEMECHANGED, 0, 0);
end;
// and then, placed directly beyond procedure EnableDarkStyle(Window: HWND);
procedure TryEnforceDarkStyle(Window: HWND);
var ctrl: TWinControl;
begin
if (Window <> 0) then begin
EnableDarkStyle(Window);
ctrl := FindControl(Window);
if ctrl = nil then exit;
ctrl.Color := clWindow;
//if (ctrl Is TCustomMemo) then // This attempt won't work (= light scrollbars again)
// (ctrl As TCustomMemo).BorderStyle := bsNone;
end;
end;
// In the user program:
If IsDarkModeEnabled then begin
//RichMemo1.Color := clWindow; // No more needed
//SetWindowTheme(RichMemo1.Handle, 'DarkMode_Explorer', nil); // Appears roonter-intiutive
RichMemo1.BorderStyle := bsNone; // Still needed here
TryEnforceDarkStyle(RichMemo1.Handle);
end;
A kind of last resort that could be easily applied for similar cases ...
Yes, it seems that nothing can be done from the inside((
I'd ended up in the same opinion, so the idea at least to encapsulate it a bit ...
Btw, maybe better to pass directly a "TWinControl" as parameter, for to save the need to do a "FindControl". Requires to move "Controls" (instead of "Windows") into the first "uses" clause. "BorderStyle" would work now too:
procedure TryEnforceDarkStyle(ctrl:TWinControl);
begin
if (ctrl <> nil) then begin
if (ctrl Is TCustomMemo) then // Could be expanded for other component types later, if needed
(ctrl As TCustomMemo).BorderStyle := bsNone; // Must be coded here before "EnableDarkStyle"!
EnableDarkStyle(ctrl.Handle);
ctrl.Color := clWindow;
end;
end;
// User program:
If IsDarkModeEnabled then
TryEnforceDarkStyle(RichMemo1);
Would it be, conceptually, anyway of interest for you to offer such an exposed procedure for such cases we have here?
Unless any better solution (using an internal hook) could be found (which would be very appreciated), the best i could do for to support an easier usage is to propose an exposure procedure via merge request.
Thank you! Can be revoked if an intrinsic solution is seen.
So far closing.
Another program learned smoothly the dark mode now, but, the ScrollBars for a TRichMemo stayed light, not darkened .... See screenshot and testcase attached. The debug output in the message console shows up that within “InterceptOpenThemeData” VSCLASS_SCROLLBAR is correctly detected in the classlist. And, so, “AllowDarkStyle” for the scrollbar's hwnd will be done. But it stays light.
I found a workaround (see the testcase attached) but I don't know what to do with this, if it is something that had to be handled in the uwin32widgetsetdark.pas itself.
testcase_TRichMemo_Scrollbars__workaround.zip
The workaround is: to call a
SetWindowTheme(RichMemo1.Handle, 'DarkMode_Explorer', nil); // Needs uses UXTheme
within the user program.A special thing here is that RichMemo's property "ScrollBars := " has to be set before, early! If done later (after the SetWindowTheme), the workaround won't have any effect (scrollbars stay light).
What do you mean, zamtmn? Should metadarkstyle handle it generically?
(Note, RichMemo needs the richmemo_package from the OPM). At the end TRichMemo is derived from a StdCrls items.