Search code examples
delphithemesaero

How to change Form Border to Windows Basic instead of Aero Style?


I want to know if it is possible, and if so how to change a forms border style to Windows Basic instead of the Aero theme? Obviously taking into consideration whether Aero is enabled or not in the first place, if it is not then there is no need to attempt to change the border style.

So instead of:

enter image description here

We would have: (mock-up image)

enter image description here

MDI Applications already do this for the child forms but I don't want or need an MDI Application. I tried looking through the source of Vcl.Forms to see if I could find anything related but I was unable to - I could be wrong but I actually think the way that MDI Forms are drawn is determined by Windows, not Delphi.

DSiWin32 contains a couple of functions related to Aero, such as determining whether or not Aero is enabled or not, as well as been able to Enable and Disable Aero - However this appears to be a system wide change and not on a per Form/Window basis, it also causes a screen delay while the theme is changed which is not good.

I am unsure where to go from at this point. Is there something simple I may have overlooked? Do we need to create and override our own TForm with some specific flags etc to achieve this, or possibly there is a way to change the form style at any point, eg Enable/Disable Aero for the form?

Simply put, I want to know if it is possible without resorting to MDI Applications, can we change any Form/Window Border to Windows Basic theme, provided Aero is enabled in the first place?


Solution

  • Call DwmSetWindowAttribute passing the DWMWA_NCRENDERING_POLICY attribute with a value of DWMNCRP_DISABLED.

    type
      TForm1 = class(TForm)
      protected
        procedure CreateWnd; override;
      end;
    
    procedure TForm1.CreateWnd;
    var
      Policy: Integer;
    begin
      inherited;
      Policy := DWMNCRP_DISABLED;
      DwmSetWindowAttribute(WindowHandle, DWMWA_NCRENDERING_POLICY, @Policy, 
        SizeOf(Policy));
    end;
    

    I've ignored error checking here. You may determine that responding to errors is worthwhile. I also didn't do any testing whether or not the operating system supports this function call, but again you could choose to do so if you need to support XP.

    Note that CreateWnd is the right place to call DwmSetWindowAttribute. The window handle is created in CreateWnd, and we want to apply this policy as soon as possible. Putting the code in CreateWnd also makes it robust against re-creation.

    Normal Aero form:

    enter image description here

    Form with the call to DwmSetWindowAttribute:

    enter image description here