Search code examples
delphivcldelphi-xe3

Use Styled SysColor for selected text in TEdit


I am using Delphi XE3 to build a VCL application. This VCL application is styled using the buildin stying from unit Vcl.Styles.

In the style I am using the SysColor clHighlight has been altered but when a piece of text is selected in a TEdit (or TComboBox or TMemo) the default system highlight color is used (defaults to blue) for coloring the background of the selected text.

NB: Other controls use the SysColor clHighlight for selected items from the style.

Question: how can you specify this color in the style?


Solution

  • This is a limitation of the WinApi, the highlight color used by these controls can't be modified directly. The only workaround is hook and replace the GetSysColor method by the StyleServices.GetSystemColor function. like so

    implementation
    
    uses
      DDetours,
      WinApi.Windows,
      Vcl.Styles,
      Vcl.Themes;
    
    var
      TrampolineGetSysColor:  function (nIndex: Integer): DWORD; stdcall;
      GetSysColorOrgPointer : Pointer = nil;
    
    function InterceptGetSysColor(nIndex: Integer): DWORD; stdcall;
    begin
      if StyleServices.IsSystemStyle then
       Result:= TrampolineGetSysColor(nIndex)
      else
       Result:= StyleServices.GetSystemColor(nIndex or Integer($FF000000));
    end;
    
    initialization
     if StyleServices.Available then
     begin
        GetSysColorOrgPointer := GetProcAddress(GetModuleHandle('user32.dll'), 'GetSysColor');
        @TrampolineGetSysColor := InterceptCreate(GetSysColorOrgPointer, @InterceptGetSysColor);
     end;
    finalization
      if GetSysColorOrgPointer<>nil then
        InterceptRemove(@TrampolineGetSysColor);
    
    end. 
    

    Before

    enter image description here

    After

    enter image description here

    Btw the VCL Styles Utils project includes a unit with this hook.