Form - Colocando componentes no Caption Bar

Top  Previous  Next

Here's the trick:

 

Treat your controls like they belong in a separate modeless dialog that just so happens to track the movement and resizing of your main form. In addition, it always appear over the main form's caption area. 

 

This said, here's a simple hack that involves 2 forms and a drop-down listbox. After running this program, the drop-down listbox will appear in the Main form's caption area. Two key issues are: 1) trapping the Main form's WM_MOVE message; and 2) returning focus back to the Main form after users press any focus-grabbing controls (like a TComboBox, TButton, etc.)

 

[FYI, I'using 32-bit Delphi 2.0 Developer under Win95 -- even though this technique should work for all versions of Delphi]

 

Here's the source for the Main form:

 

 

--------------------------------------------------------------------------------

 

   unit Unit1;

 

   interface

 

   uses

     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

     Dialogs,  StdCtrls;

 

   type

     TForm1 = class(TForm)

       procedure FormResize(Sender: TObject);

       procedure FormShow(Sender: TObject);

       procedure FormHide(Sender: TObject);

     private

       { Private declarations }

     public

       { Public declarations }

       procedure WMMove(var Msg: TWMMove); message WM_MOVE;

     end;

 

   var

     Form1: TForm1;

 

   implementation

 

   uses Unit2;

 

   {$R *.DFM}

 

   procedure TForm1.FormResize(Sender: TObject);

   begin

        with Form2 do

           begin

           {Replace my magic numbers with real SystemMetrics info}

           Width := Form1.Width - 120;

           Top := Form1.Top + GetSystemMetrics(SM_CYFRAME);

           Left := ((Form1.Left + Form1.Width) - Width) - 60;

           end;

   end;

 

   procedure TForm1.FormShow(Sender: TObject);

   begin

        Form2.Show;

   end;

 

   procedure TForm1.FormHide(Sender: TObject);

   begin

        Form2.Hide;

   end;

 

   procedure TForm1.WMMove(var Msg: TWMMove);

   begin

        inherited;

        if (Visible) then FormResize(Self);

   end;

 

   end.

 

 

--------------------------------------------------------------------------------

 

Here's the source for the pseudo-caption area form. This is the form that contains the VCL controls you wish to place in the Main form's caption area. Essentially, it's a modeless dialog with the following properties:

 

 

--------------------------------------------------------------------------------

 

   Caption='' {NULL string}

   Height={height of caption area}

   Width={width of all controls in form}

   BorderIcons=[] {none}

   BorderStyle=bsNone

   FormStyle=fsStayOnTop

 

 

--------------------------------------------------------------------------------

 

Anyhow, here's the source for Form2:

 

 

--------------------------------------------------------------------------------

 

   unit Unit2;

 

   interface

 

   uses

     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

     Dialogs, StdCtrls;

 

   type

     TForm2 = class(TForm)

       ComboBox1: TComboBox;

       procedure FormCreate(Sender: TObject);

       procedure ComboBox1Change(Sender: TObject);

       procedure FormResize(Sender: TObject);

     private

       { Private declarations }

     public

       { Public declarations }

     end;

 

   var

     Form2: TForm2;

 

   implementation

 

   uses Unit1;

 

   {$R *.DFM}

 

   procedure TForm2.FormCreate(Sender: TObject);

   begin

        Height := ComboBox1.Height - 1;

        Width := ComboBox1.Width - 1;

   end;

 

   procedure TForm2.ComboBox1Change(Sender: TObject);

   begin

        Form1.SetFocus;

   end;

 

   procedure TForm2.FormResize(Sender: TObject);

   begin

        ComboBox1.Width := Width;

   end;

 

   end.

 

 

--------------------------------------------------------------------------------

 

The project file (.DPR) is fairly straightforward:

 

 

--------------------------------------------------------------------------------

 

   program Project1;

 

   uses

     Forms,

     Unit1 in 'Unit1.pas' {Form1},

     Unit2 in 'Unit2.pas' {Form2};

 

   {$R *.RES}

 

   begin

     Application.Initialize;

     Application.CreateForm(TForm1, Form1);

     Application.CreateForm(TForm2, Form2);

     Application.Run;

   end.

 

 

--------------------------------------------------------------------------------

 

That's it!

 

Although some Delphi book authors state:

 

"You can't place a Delphi component on the title bar, so there's literally no way to put a button there."

 

you can at least "fake" the illusion...