Kevin Jacobs
Kevin Jacobs

Reputation: 69

Dimming the screen with Delphi

I am looking to create an effect similar to the lightbox effect seen on many website where the background of the screen fades out and the content you want to emphasize does not. What would be the best way to go about creating such an effect in delphi ?

The content I want to emphasize in this case is a movable panel located on my form and basically all I want to do is to fade out any area of the screen that is not directly under that panel.

Thanks. Oscar

Upvotes: 2

Views: 4109

Answers (2)

Warren  P
Warren P

Reputation: 68922

Create a new form and add this code to the FormCreate method. You could also change the properties using the properties inspector, but I'm choosing to show you the relevant properties using code:

unit Unit1;
// This is a full screen partially transparent black form.
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation
uses Unit2;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  BorderStyle := bsNone;
  Self.WindowState := wsMaximized;
  AlphaBlend := true;
  Alphablendvalue := 127;
  Color := clBlack;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Form2.Show;
end;

procedure TForm1.FormClick(Sender: TObject);
begin
  Close;
end;

end.

Here's a second form which has no border, which I am showing over top. It does not have alpha blending turned on, and the form style should be fsStayOnTop, or else you should use the ParentWindow property (on versions of Delphi that support that).

unit Unit2;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm2 = class(TForm)
    Label1: TLabel;
    procedure FormDeactivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FAutoDeactivate: Boolean;
    FCounter: Integer;
    procedure WMUser1(var Message:TMessage); message WM_USER+1;
  public
    property AutoDeactivate:Boolean read FAutoDeactivate write FAutoDeactivate;
  end;

var
  Form2: TForm2;

implementation
uses Unit1;

{$R *.dfm}

procedure TForm2.FormDeactivate(Sender: TObject);
begin
  if Self.Visible and FAutoDeactivate then
  begin
    FAutoDeactivate := false;

    Form1.Close;
  end;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Form1.Close;
end;

procedure TForm2.FormActivate(Sender: TObject);
begin
  PostMessage(Self.Handle, WM_USER+1, 0, 0);
end;

procedure TForm2.WMUser1(var Message: TMessage);
begin
 FAutoDeactivate := true;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  BorderStyle := bsNone;
  Color := clWhite;
  FormStyle := fsStayOnTop; // or set parent 
end;

end.

That addresses how to make the whole screen "go dim", and then show something on top of that "dimmed area", but what you describe as "showing a panel in your main form" would require you to move that content out of your main form, or else clip a region out of form1, or use a combination of alpha blend plus transparency, but I don't have any code for those to show you.

If I was doing it, I would just float the thing I want not to be dimmed, above the full screen borderless 50% alpha form, as shown below.

But as you see, the screen isn't dimmed (screen brightness is not reduced), it's merely that we've done a 50% transparent layer of black which has blended in and darkened the overall screen appearance.

enter image description here

Upvotes: 9

sellgisfist
sellgisfist

Reputation: 1

I have the same need as Oscar. After some search on the net, I found what is shown here. It has helped me to do this, since it works. You can move what is emphasized in a Form instead of a Panel. I use two forms. The first is use as "fader" and the second as dialogbox. First

unit uFormFaded;

interface

uses
   ...

type
  TFormFaded = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  FormFaded: TFormFaded;

implementation

{$R *.dfm}

procedure TFormFaded.FormCreate(Sender: TObject); 
begin
  Align := alClient;
  AlphaBlend := true;
  AlphaBlendValue := 100;
  BorderStyle := bsNone;
  Color := clBlack;
  Enabled := false;
  FormStyle := fsStayOnTop;
end;

end.

Second

unit UFormDlgBox;

interface

uses
   ...

type
  TFormDlgBox = class(TForm)
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  FormDlgBox: TFormDlgBox;

implementation

{$R *.dfm}

uses uFormFaded;

procedure TFormDlgBox.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FormFaded.Close;
end;

procedure TFormDlgBox.FormShow(Sender: TObject);
begin
  FormFaded.Show;
end;

end.

The use

FormDlgBox.ShowModal;

I tried to reproduce this schema creating the forms in run-time an make the TFormDlgBox Owns and create the TFormFaded but it doesn't work. It seems it works only with forms created in design-time.

Upvotes: 0

Related Questions