3
votes

I am having trouble with incorrectly painted corners when drawing VCL-styled window elements. On styles that have rounded corners, I get a white background in the space between the control's bounding rect and the style's rounded window corner.

enter image description here

The above image was run using Aqua Light Slate, but any style with rounded corners will show this same problem. What am I missing?

type
  TSample = class(TCustomControl)
  protected
    procedure Paint; override;
  end;

{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
  R: TRect;
  S: TSample;
begin
  R := ClientRect;
  InflateRect(R, -20, -20);
  S := TSample.Create(Application);
  S.Parent := Self;
  S.BoundsRect := R;
end;

{ TSample }
procedure TSample.Paint;
var
  Details: TThemedElementDetails;
begin
  Details := StyleServices.GetElementDetails(twCaptionActive);
  StyleServices.DrawParentBackground(Self.Handle, Canvas.Handle, Details, False);
  StyleServices.DrawElement(Canvas.Handle, Details, ClientRect);
end;
1
btw, I also tried ParentBackground := True, no change. Have also tried making sure csOpaque is removed.DaveS_Lifeway
Are you tried debugging the StyleServices.DrawElement method to see how it draw the bitmap in the canvas?RRUZ
Frankly I was hoping to avoid diving into the internals of the theme engine, but if no one has any better ideas, that's what I'll have to do.DaveS_Lifeway
Unfortunately, this didn't help. DrawElement is drawing white corners whether the DC is the offscreen bitmap, or the control's canvas. I proved this by filling the offscreen bitmap with a solid color first, then calling DrawElement into the bitmap, but using a rectangle not as wide as the bitmap and centered. The result was my solid color on both sides, and the caption bar in the middle, still with white corners. DrawElement is just not drawing the corners transparent, for some reason.DaveS_Lifeway

1 Answers

5
votes

Ok, I spend some minutes in you question and I found the answer. The key to draw the rounded corners, is call the StyleServices.GetElementRegion function to get the region and then use the SetWindowRgn function to apply the region to the control.

check this sample

procedure TSample.Paint;
var
  Details : TThemedElementDetails;
  Region  : HRgn;
  LRect   : TRect;
begin
  Details := StyleServices.GetElementDetails(twCaptionActive);
  LRect := Rect(0, 0, Width, Height);
  StyleServices.GetElementRegion(Details, LRect, Region);
  SetWindowRgn(Handle, Region, True);
  StyleServices.DrawParentBackground(Self.Handle, Canvas.Handle, Details, False);
  StyleServices.DrawElement(Canvas.Handle, Details, ClientRect);
end;

And this is the result

enter image description here