10
votes

In a Delphi 2010 application with themes enabled I have two TPageControls (one inside the other) in a Form with a clMoneyGreen Background:

enter image description here

The outer page control correctly draw its background with the color of the parent component, the inner page control however draw its background with clBtnFace (red ellipsis in the image) instead of its parent control (TTabSheet)'s white. Is there a way to fix this without returning the page control to its windows classic appearance (lose windows theme)?

All fixes that I've found in Google and here on Stack Overflow involves OwnerDraw which make the page control lose its theming.

I have tried creating new page control component inherited from TPageControl with a method to handle the WM_ERASEBKGND windows message:

procedure TMyPageControl.WMEraseBkGnd(var Msg: TWMEraseBkGnd);
begin
  if Parent is TCustomPageControl then
  begin
    Brush.Color := clWhite;
    Windows.FillRect(Msg.dc, ClientRect, Brush.Handle);
    Msg.Result := 1;
  end
  else
    inherited;
end;

It paints the background white but some other method called after WM_ERASEBKGND (I'm guessing TWinControl's WM_PAINT method) repaints gray over the white background.

Note: I'm researching this because I'm implementing theming on a large application ported from Delphi 7, that's why I'm trying to solve this problem through a derived component: I can easily search and replace all the 207 TPageControl occurrences with my new class, but placing panels behind some of them would require way more time.

1

1 Answers

13
votes

That's a known bug in Delphi 2010. You can work around it by adding a panel that is a child of the outermost tabsheet, and is the parent of the inner page control.

I've no idea why this fixes the problem. I only discovered the workaround myself because I noticed that in my app, the only nested tab/page controls that rendered properly were those with a panel suitably interposed.

If I recall correctly, the defect is not present in the latest Delphi versions.