Delphi XE与Aero效果导致绘制问题

9
我从2009升级到了Delphi XE,遇到了一个奇怪的问题。
我创建了一个新项目,在其中放置了一个TRibbon控件,编译并运行。保持窗体在默认大小下最小化和还原,没有问题。然后我将窗体最大化,最小化和还原,窗体的颜色就会变成黑色。
我没有随机代码来改变窗体颜色,并且使用所有默认的Delphi XE,每一次都会出现这个问题。
我已经把编译好的exe文件移动到了朋友的电脑上,问题仍然存在,所以我知道这不是我的电脑问题。如果关闭Aero效果,问题就消失了,但是重新启用Aero后问题又回来了。
有什么想法吗?我很难在互联网上找到与此问题相关的线程。
谢谢, Seb
编辑(根据要求,以下是显示此行为的表单的DFM。注意:任何我开始的项目都会出现这种情况):
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 555
  ClientWidth = 989
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  PrintScale = poNone
  Scaled = False
  PixelsPerInch = 96
  TextHeight = 13
  object Ribbon1: TRibbon
    Left = 0
    Top = 0
    Width = 989
    Height = 143
    Caption = 'Ribbon1'
    ExplicitLeft = 104
    ExplicitTop = 296
    ExplicitWidth = 0
    StyleName = 'Ribbon - Luna'
  end
end

没有任何花哨的东西,它只是一个带有单个表单的新项目。


你有 GlassFrame.SheetOfGlass = True 吗?问这个是因为黑色是玻璃的默认键颜色,也许你的应用程序中某种方式禁用了"玻璃",导致你看到了黑色键颜色。 - Cosmin Prund
我使用了以下代码来检查SheetOfGlass和Colour是否发生变化->procedure TfmMainForm.WMSysCommand; begin if (Msg.CmdType = SC_RESTORE) or (Msg.CmdType = SC_MAXIMIZE) or (Msg.CmdType = SC_MINIMIZE) then begin ShowMessage('SheetOfGlass = ' + BoolToStr(GlassFrame.SheetOfGlass, True)); ShowMessage('Colour = ' + ColorToString(Color)); end; DefaultHandler(Msg) ; end; <- 但是什么也没有改变。 - Sebastien
@Sebastien,切换GlassFrame.SheetOfGlass可以解决问题,这表明你看到的黑色确实与“玻璃”有关。不幸的是,我现在无法测试。我会采取几种方法:跟踪代码,当我切换SheetOfGlass时查看涉及哪些API调用,然后找出是否因其他原因在程序中调用了其中一些API。然后我会尝试弄清楚黑色是由VCL还是Windows自身绘制的:我会尝试覆盖窗体的WM_ERASEBKGND处理程序并将背景绘制为红色。 - Cosmin Prund
检查您表单的GlassFrame子属性,检查GlassFrame.Top/Bottom/Left/Right,也许其中某些地方出了问题,导致了一些错误。尝试将它们全部设置为0,看看会发生什么。如果您能提供一个最小化的表单DFM文件以展示此问题,那将非常有趣,我想自己尝试一下。 - Cosmin Prund
GlassFrame.SheetOfGlass := False; GlassFrame.Enabled := False; GlassFrame.Top/Bottom/Left/Right := 0); 这是默认设置(在启动新项目时由Delphi设置)。除了放置TRibbon之外,我没有做任何其他更改。我的一个朋友尝试了一下,使用Delphi XE无法复制该问题(我尝试卸载/重新安装,但没有任何区别,修复也不行)。 - Sebastien
显示剩余6条评论
2个回答

4
我能够重现这个bug,以下是我发现的一些问题。也许它们会帮助别人解决这个问题。
- 如果我在表单上放置一个按钮并从按钮的OnClick事件中调用Invalidate,表单就会恢复其颜色。 - 如果我在表单上放一个计时器,在WndProc的WM_SIZE中以wParam = SIZE_MAXIMIZED启用计时器,然后从计时器中调用Invalidate,表单会恢复其颜色。这本质上与第一种方法(从按钮调用Invalidate)相同,但计时器使其自动化,并确保仅在没有更多消息要处理时才调用Invalidate。我尝试了简单的PostMessage,但没起作用(即:我可能太早调用了Invalidate,这可能是另一个线索) - 有趣的是:如果我在项目的源代码中设置Application.MainFormOnTaskbar := False,则不再看到黑色表单。
解决方法
功能区占据了表单的顶部。在其余部分上放置一个TPanel,将其Align设置为alClient并将所有内容放在Panel上。面板后面的黑色不再可见!

尝试在WM_NCPAINT上添加一个invalidate,看看是否有更好的解决方法。 - Warren P

1

在使用Ribbon时,应启用玻璃框架,因为Ribbon控件是专门设计用于与Aero玻璃框架配合使用的。其次,您应该做更多的工作来配置您的Ribbon,添加应用程序菜单和一些窗格,以使其按设计工作。我不相信“仅有Ribbon本身”没有任何选项卡组或系统菜单,在运行时会正确呈现。

如果您希望Ribbon在启用Aero玻璃的系统上正常工作,则应启用玻璃框架属性(Form.GlassFrame.Enabled),并打开Form.DoubleBuffered属性,添加一些选项卡页、选项卡组和系统菜单。需要进行许多步骤。

请尝试附加的ribbon starter project。(ribbonStarter.zip 88k)

更新 如果即使我的ribbon starter在您的系统上也产生了相同的结果,则可能应将此记录在Quality Central中。这可能是您的视频驱动程序中的错误,可以在ribbon和form代码中进行一些代码解决方案。


嗨@Warren-p,DoubleBuffered没有效果:( - 我已经编辑了我的问题,包括DFM,但是恐怕没有什么可以看到的。这个DRM来自于文件->新建->VLC Forms Application for Delphi并保存它。没有任何更改,也没有修改(除了当然放下TRibbon)。 - Sebastien
视频卡的类型、驱动程序的日期和版本是什么?(例如ATI或nVidia,型号#,驱动程序日期和版本)。 - Warren P
这是一款 ATI Radeon Mobility HD 5650 1gb 显卡,驱动程序日期为2010/01/13,驱动版本为8.672.1.2000(没有找到更新的版本)。这个问题在我的同事的电脑上也出现了,他的 GTS 250 1gb 已经安装了最新的 Nvidia 驱动程序。这个问题发生在 Windows 7 64位和32位系统中,只有我使用 Delphi XE 时才会发生,但在 Delphi 2009 中不会发生这个问题。真令人困惑 :/ - Sebastien
@Warren,请看我对问题本身的最后一条评论。我可以在VmWare“硬件”上重现这个错误。 - Cosmin Prund
Cosmin - 你使用的是哪个版本的VMWare和哪个版本(工作站等)? - Warren P
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接