Delphi XE with Aero effects causes paint issue
Asked Answered
V

2

9

I have upgraded to Delphi XE from 2009 and am experiencing a strange issue.

I create a new project, put down a TRibbon control, compile and run. Keeping the form in its default size I then minimize and restore without issues. I then maximise the form, minimize and restore and the form colour is changed to black.

I have no random code to change it and am using all defaults Delphi XE comes with and it does it each and every time without fail.

I have moved the compiled exe to a friends computer and the problem remains so I know it's not my computer. If I turn off Aero effects the problem goes away, but put Aero back on and the problem returns.

Any ideas at all? I'm having trouble finding any relevant threads regarding this issue across the interwebs.

Thanks, Seb

Edit (as requested, the DFM for the Form that displays this behaviour. Note: This happens on any project I start):

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

Nothing fanciful at all, it's just a new project with a single form.

Voracity answered 27/6, 2011 at 9:29 Comment(11)
Do you have GlassFrame.SheetOfGlass = True? Asking because Black is the default keying color for glass, maybe "glass" somehow gets disabled for your app and you end up with the black key color visible.Royalroyalist
@cosmin-prund - SheetOfGlass is false and the background colour is set to $00FEDABE to match the Luna colour theme. I've tried to intercept when the form is restored from its minimized state and enabling SheetOfGlass then disabling it and even resetting the colour but it didn't fix the problem. Side note: I put in GlassFrame.SheetOfGlass := NOT GlassFrame.SheetOfGlass; into a button, if I click the button twice (Glass := true then Glass := false), it sets the background to the correct colour.Voracity
I used the following code to check if SheetOfGlass and Colour change at all -> 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; <- and nothing changes.Voracity
@Sebastien, the fact that toggling GlassFrame.SheetOfGlass fixes it is a hint, the black you're seeing is truly related to "glass". Unfortunately I can't test right now. I'd follow several approaches: trace the code when I toggle SheetOfGlass and see what API calls are involved, then figure out if some of those API's are called in the program for other reasons. Then I'll try to figure out if the Black is painted by the VCL or by Windows itself: I'd try overriding the form's WM_ERASEBKGND handler and paint the background red.Royalroyalist
@cosmin-prund I'll see what I can find on how to override WM_ERASEBKGND (not that knowledgeable with API calls and such :), but what I have found is that inside the Ribbon unit, TCustomRibbon.Paint contains a suspicious piece of code: if GlassFrameSupported then begin canvas.Brush.color := clBlack; canvas.FillRect(LRect); end but changing it doesn't seem to do anything, even if I change clBlack to something else, perhaps I'm doing it wrong? (I change the code and save, not sure if that is correct). Thanks for your assist so far :) - It's suspicious to me, lolVoracity
@Sebastien, if you change VCL code (for testing purposes, you shouldn't really need to do that) you need to make sure it gets compiled and linked into your program. Try adding the file to your project. To make sure your build is actually compiling the modified VCL, add some nonsense to the unit and look for the compile error.Royalroyalist
@cosmin-prund, after linking the unit "Ribbon" to my program I discovered that the following FParentForm.GlassFrame.Enabled := True; (line: 4687) when set to False stops the form from turning black, however it also removes the system buttons (min, max and close), lol. One step forward, one step back. :) Thanks again will keep you posted on what I find.Voracity
Check the sub-properties of GlassFrame for your form, check GlassFrame.Top/Bottom/Left/Right, maybe somethings wrong with those, surfacing some bug. Try making them all 0 and see what happens. Posting the DFM for a minimal form that exhibits this would also be interesting, I'd like to try it myself.Royalroyalist
GlassFrame.SheetOfGlass := False; GlassFrame.Enabled := False; GlassFrame.Top/Bottom/Left/Right := 0); This is the default setting (as set by Delphi when you start a new project). Apart from throwing down a TRibbon, I've made no other changes. A friend who has Delphi XE tried it and is unable to duplicate the issue (I've tried to uninstall/reinstall but it made no difference, neither did a Repair).Voracity
I can confirm the issue. Start a new VCL application, drop a single Ribbon control (don't do anything else), hit "RUN", maximize the app, minimize the app, restore the app and enjoy the blackness!Royalroyalist
The bug is there on Delphi 2010 as well.Royalroyalist
R
4

I am able to reproduce the bug, here are some of the issues I discovered. Maybe they'll help someone figure this thing out.

  • If I place a button on the form and call Invalidate from the button's OnClick event, the form gets it's colors back.
  • If I place a place a timer on the form, enable the timer from WndProc on WM_SIZE with wParam = SIZE_MAXIMIZED, then call Invalidate from the timer the form gets it's colors back. This is essentially the same as the first method (calling Invalidate from a button), but the timer makes this automatic and ensures Invalidate is called only when there are no more messages to be processed. I tried the same with a simple PostMessage but didn't work (ie: I was probably Invalidate-ing too soon, and that's probably an other clue)
  • Interesting: If I make Application.MainFormOnTaskbar := False in the project's source, I no longer see the black form.

Workaround

The ribbon takes up the top part of the form. Place a TPanel on the rest of the form, make it Align = alClient and put everything on the Panel. The Black behind the panel is no longer visible!

Royalroyalist answered 27/6, 2011 at 16:42 Comment(1)
Try adding an invalidate on WM_NCPAINT, see if that is a better workaround.Ambidexterity
A
1

You should enable glass frame when using Ribbon, because the Ribbon control is especially designed to work with aero glass frames on. Secondly you should do a little more work to configure your ribbon, adding an application menu, and some panes, to have it work as designed. I don't believe that "ribbon by itself" without any tab groups, or a system menu, is going to render properly at runtime.

If you want the ribbon to work on systems with Aero glass enabled, you should enable the glass frame property (Form.GlassFrame.Enabled) , and turn on Form.DoubleBuffered property, add some tab pages, add some tab groups, and add a system menu. Lots of steps.

Please try the attached ribbon starter project. (ribbonStarter.zip 88k)

Update If even my ribbonStarter produces the same result on your system, perhaps this should be logged in Quality Central. It is possibly a bug in your video driver, for which some code workaround in the ribbon and form code could be made.

Ambidexterity answered 27/6, 2011 at 13:4 Comment(8)
Hi @Warren-p, DoubleBuffered has no effect :( - I've edited my question to include the DFM, but there is nothing to see I'm afraid. This DRM is from File -> New -> VLC Forms Application for Delphi and saving it. No changes, no modifications (except for throwing down the TRibbon of course).Voracity
What type of video card, and what date is the driver? (ie ATI or nVidia, model #, and driver date and version).Ambidexterity
I think it's a combination of that you need double buffered, and the glass frame to be enabled, or else you will have problems on Aero Systems.Ambidexterity
It's a ATI Radeon Mobility HD 5650 1gb, the driver date is 2010/01/13, driver version: 8.672.1.2000 (haven't found any newer ones). This problem occurs on a coworkers pc as well which has the latest nvidia drivers for his GTS 250 1gb), it occurs on windows 7 64 and 32 bit and only if I use Delphi XE, with Delphi 2009 this problem doesn't occur. So confusing, really :/Voracity
@Warren, see my last comment to the question itself. I can reproduce the bug on VmWare "hardware".Royalroyalist
@Warren-p, I did as you suggested but I get the same black-screen.Voracity
Cosmin - What version of VMWare and edition (workstation, etc) are you using?Ambidexterity
Unable to reproduce problem using VMWARE 7.1.4 with Windows 7/x64 guest OS, using Glass with the VMWARE WDDM driver.Ambidexterity

© 2022 - 2024 — McMap. All rights reserved.