2012-04-10 89 views
3

我在绘制VCL风格的窗口元素时遇到绘画不正确的问题。在具有圆角的样式上,我在控件边界矩形和样式的圆角窗口角之间的空白处获得了白色背景。Delphi XE2风格绘画

enter image description here

上面的影像是用水族光板岩运行,但带有圆角的任何风格会显示此相同的问题。我错过了什么?

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; 
+0

顺便说一句,我也试过ParentBackground:=真,没有任何变化。也尝试确保csOpaque被删除。 – 2012-04-10 18:36:01

+0

您是否尝试调试'StyleServices.DrawElement'方法以查看它如何在画布中绘制位图? – RRUZ 2012-04-10 21:47:34

+0

坦率地说,我希望避免潜入主题引擎的内部,但如果没有人有更好的想法,那就是我必须做的。 – 2012-04-11 17:32:27

回答

4

好吧,我花了几分钟在你的问题,我找到了答案。绘制圆角的关键是调用StyleServices.GetElementRegion函数获取区域,然后使用SetWindowRgn函数将区域应用于控件。

检查该样本

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; 

这是结果

enter image description here

+0

这绝对有用,非常感谢您的帮助!这也适用于使用屏幕位图作为标题区域。对于其他人做类似的事情,值得指出的是,整个客户端矩形需要传递给GetElementRegion。 – 2012-04-12 17:12:53