Search code examples
delphidwmaero-glasstabbed-interface

Google Chrome style tabs on glass in Delphi


I am trying to implement Google Chrome style tabs, in Windows 7, in a Delphi application.

The elements of this are:

  • tabs may extend into the non-client area as they do in google chrome itself.
  • draws properly on Vista and Windows 7 when glass is enabled
  • tabs work just like google chrome, and look like google chrome, over glass.

enter image description here

I have found that the challenges I have to overcome are:

  • How do I get a control (VCL control) to extend into the non-client area? (A good sample of a control that does this is the Ribbon control included in the VCL sources, but I haven't seen anybody else do it, and it takes some wicked hacking to get the Ribbon to function)
  • How to draw bitmaps properly over glass? (DWM API). A related question already answers that aspect, here, this question was also asked by me.

Solution

  • You don't want a full glass window, but you will have to draw the tabs yourself as there isn't a control that I am aware of that will give you the exact look your looking for. If you use the GlassFrame properties of the current form, enable it and set the top to the height you will want for your tabs, drop a paintbox on this area and use GDI+ calls to draw your tabs manually. A good library that should work for this is available on the EDN (http://cc.embarcadero.com/Download.aspx?id=26950). Without using GDI+ you will be able to draw to the paint box, but black will become transparent. With GDI+ you can draw freely to the glass in any color. For example:

    running example

    Source:

    unit Unit6;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, GdiPlusHelpers, GdiPlus, StdCtrls, ExtCtrls;
    
    type
      TForm6 = class(TForm)
        pb1: TPaintBox;
        procedure pb1Paint(Sender: TObject);
      private
        { Private declarations }
       public
        { Public declarations }
      end;
    
    var
      Form6: TForm6;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm6.pb1Paint(Sender: TObject);
    var
      Graphics : IGPGraphics;
      Brush: IGPSolidBrush;
      FontFamily: IGPFontFamily;
      Font: IGPFont;
      Point: TGPPointF;
      Pen: IGPPen;
    begin
      Graphics := Pb1.ToGPGraphics;
      Brush := TGPSolidBrush.Create(TGPColor.Create(255, 0, 0, 0));
      FontFamily := TGPFontFamily.Create('Consolas');
      Font := TGPFont.Create(FontFamily, 12, FontStyleRegular, UnitPoint);
      Point.Initialize(1, 0);
      Graphics.TextRenderingHint := TextRenderingHintAntiAlias;
      Graphics.DrawString('GDI+ Black Text', Font, Point, Brush);
      Pen := TGPPen.Create(TGPColor.Create(255, 0, 0, 0));
      Graphics.DrawLine(Pen, 0, 0, 200, 100);
    end;
    
    end.
    

    Form:

    object Form6: TForm6
      Left = 0
      Top = 0
      Caption = 'Form6'
      ClientHeight = 282
      ClientWidth = 418
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      GlassFrame.Enabled = True
      GlassFrame.Top = 22
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object pb1: TPaintBox
        Left = 0
        Top = 0
        Width = 313
        Height = 105
        OnPaint = pb1Paint
      end
    end
    

    EDIT Updated to anti-alias the text so it looks better.