Delphi支持Aero Glass和DoubleBuffered属性 – 发生了什么,我们如何使用它们?

前端之家收集整理的这篇文章主要介绍了Delphi支持Aero Glass和DoubleBuffered属性 – 发生了什么,我们如何使用它们?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我很困惑的Delphi 2009/2010支持Aero主题玻璃功能在Windows中,由什么,正是DoubleBuffered的意思,它与Aero玻璃有关。我发现DoubleBuffered不仅是VCL中的一个属性,它也发现在 .net WinForms.最初我想知道它是否设置某种类型的窗口样式位使用的公共控制库,或什么。为什么使用它,什么时候使用它?

[更新:我应该声明,我知道什么是“双缓冲”,作为减少闪烁的一般技术,我想知道的是,为什么有任何关于渲染控制在Windows Vista / Windows 7,特别是为什么一个BUTTON的所有东西都需要双缓冲设置为真,在玻璃上工作。下面链接博客帖子似乎是最丰富的信息。]

特别是,我很困惑的DoubleBuffered属性,我想知道,为什么它存在,它的玻璃支持和双缓冲属性在窗体和控件之间的关系设置。当你读到C++ articles like this one,你会发现没有提到双缓冲。

[Update2:以下包含一些实际错误,并已修改:]

我发现一些C开发人员谈论他们如何可以调用SetLayeredWindowAttributes,以避免DWM / Aero合成导致当你在经典的Win32应用程序中打开“黑色变成玻璃”毛刺[但是下面的博客链接告诉我,这不再工作在Windows 7中,实际上只是简单地在Vista中,直到Microsoft阻止它]。 [开始错误的想法]我们不应该使用一些其他颜色,像明亮的洋红色,使之变成玻璃透明色? [结束错误想法]

当DoubleBuffered应该设置和未设置,以及为什么DoubleBuffered添加到VCL的规则是什么?什么时候设置会导致问题? (它看起来远程桌面是一种情况,但是是唯一的情况?),当它没有设置,我们得到闪烁的按钮文本的渲染,很可能是因为它似乎Delphi不改变默认“渲染黑色玻璃“在Aero DWM。

在我看来,Aero Glass渲染基本上是以奇怪或难以理解的方式完成的[由Windows本身,而不是由Delphi,它只是包装这个功能],并且在2009/2010的许多内部VCL源代码在StdCtrls中的类必须做很多复杂的逻辑来在Aero Glass上正确地渲染东西,但它仍然有很多问题,并且看起来像我做错了,这可能是在这之后related question,and qc issue. [Update3:很多在玻璃上渲染毛刺,在VCL中渲染做错了内部的常见控件,这似乎微软不在乎固定。总之,Delphi VCL代码修复不能修复的事实,古老的Windows公共控制库和现代[但古怪] Aero玻璃合成功能不喜欢对方,不是特别是一起工作。感谢Microsoft建立这样一个高质量的技术,并释放它在世界上。

如果它还不够有趣;为什么我们有ParentDoubleBuffered?

[7月30日更新:这个问题对我很有趣,因为我认为它表明,工作在Windows API解决这个问题,当你有一个大的现有VCL框架,是一个艰难的问题。

解决方法

关于DoubleBuffer

.NET可能有一个,它可能有与Delphi相同的名称和目的,但Delphi正在从头开始实现DoubleBuffer,我认为.NET也是一样。不使用窗口样式位来实现此。

双缓冲和玻璃航空

相当简单:不要为坐在Glass上的控件设置DoubleBuffer。对于DoubleBuffering工作,一个必须能够初始化“缓冲区” – 但是什么来初始化它与Glass? Windows标准控件(包括TButton)不需要DoubleBuffering。对于需要透明表面和类似doublebuffer行为的新控件,可以使用Layered windows api的。

获取控件在Glass上工作

步骤1:

TForm1 = class(TForm)
...
protected
  procedure CreateWindowHandle(const Params: TCreateParams); override;
...
end;

procedure TForm15.CreateWindowHandle(const Params: TCreateParams);
begin
  inherited;
  SetWindowLong(Handle,GWL_EXSTYLE,GetWindowLong(Handle,GWL_EXSTYLE) or WS_EX_LAYERED);
  SetLayeredWindowAttributes(Handle,RGB(60,60,60),LWA_COLORKEY);
end;

步骤2,这应该是你的窗体的OnPaint处理程序:

procedure TForm15.FormPaint(Sender: TObject);
var rClientRect:TRect;
begin
  if GlassFrame.Enabled then
  begin
    rClientRect := ClientRect;

    Canvas.Brush.Color := RGB(60,60);
    Canvas.Brush.Style := bsSolid;
    Canvas.FillRect(rClientRect);

    if not GlassFrame.SheetOfGlass then
    begin
      rClientRect.Top := rClientRect.Top + GlassFrame.Top;
      rClientRect.Left := rClientRect.Left + GlassFrame.Left;
      rClientRect.Right := rClientRect.Right - GlassFrame.Right;
      rClientRect.Bottom := rClientRect.Bottom - GlassFrame.Bottom;
      Canvas.Brush.Color := clBtnFace;
      Canvas.FillRect(rClientRect);
    end;
  end;
end;

步骤3:设置GlassFrame.Enabled = True;设置所有其他玻璃属性添加控件到窗体,无论你喜欢他们。可能在玻璃上或其他地方。确保控件没有“DoubleBuffered = True”。就是这样,享受。我已经测试与TButton,TCkBox和TEdit。

…编辑…

不幸的是,使用这种方法“玻璃”被视为100%透明表面,它不是 – 它看起来像玻璃,但它的行为不像玻璃。 100%透明度的问题是,如果你点击那个透明区域,你的点击进入窗口后面的窗口。可怕。

在写这篇文章的时候,我确定没有API可以更改原始玻璃的默认BLACK键颜色(google发现无数博客和论坛帖子,您需要使用自定义绘图来控制坐在玻璃上的控件,并且没有功能改变在the list of DWM functions on MSDN)。没有改变默认的BLACK颜色,大多数控件不能正确呈现,因为他们使用clWindowText编写文本,这是BLACK。在几个论坛上发现的一个建议的技巧是使用SetLayeredWindowAttributes API更改透明度颜色。它的工作原理!一旦完成黑色文本控件显示投掷,但不幸的是,玻璃不再是玻璃,玻璃看起来像玻璃,但表现得像100%的透明度。这几乎使这个解决方案无效,并在微软方面显示了双重标准:原来的BLACK不像100%透明度,如果我们改变它的行为像100%透明度的行为。

在我看来,在Glass上使用自定义控件的常见思考是错误的。这是唯一可能的工作,但它是错误的,因为我们应该使用在平台上一致的控件:建议自定义控件打开不一致,winamp的应用程序的门,每个用户重新创建车轮西装是艺术的想法。即使开发人员设法忠实地重新创建任何给定的窗口控件,并使其在玻璃上工作,“修复”只是临时的,需要为下一个版本的窗口重新创建。更不用说现有版本的Windows应该有多个变体。

另一个解决方案是使用带有UpdateLayeredWindow的分层窗口。但是这是一个痛苦的sooo很多原因。

这对我来说是一个死胡同。但我会给这个问题一个“最喜欢”的旗帜,如果更好的东西出现我想知道它。

猜你在找的Delphi相关文章