1. Tech

Your suggestion is on its way!

An email with a link to:

http://delphi.about.com/od/formsdialogs/l/aa073101b.htm

was emailed to:

Thanks for sharing About.com with others!

A more powerful Delphi Form
Page 2: Examples of extended Form functionality.
 More of this Feature
• Page1: Form Creation

• Project Code

Printer friendly versionPrinter friendly version
 Join the Discussion
"Post your views, comments, questions and doubts to this article."
Discuss!
 Related Resources
• Form extensions
• OOP in Delphi
• Win/API articles
• Custom component dev.
 Elsewhere on the Web
• CreateWindowEx API

Messing with the creation process of a form object, or how to change the default style of a window when it gets created to suit your particular needs. Transparent forms, no caption forms, realy StayOnTop forms, ...

TaskBar button for every Delphi form
By default Delphi application only have one button on the Windows Task Bar for the whole application. When you, for example, minimize the main form Delphi minimizes the main form, and than hides all other windows in the application as well. If you want to have a separate taskbar button for each secondary window you need to change the extended style flag. When we add WS_EX_APPWINDOW bit to the ExStyle flag for the form, the form will not get minimized when the main form for the application is minimized. This is how the CreateParams should look:

procedure TForm1.CreateParams
   (var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle
                    or WS_EX_APPWINDOW;
end;

This approach has a side effect. If you click on a secondary forms taskbar button while another application is active this will bring all the applications forms to front. The reason for this behaviour lies in the fact that all secondary forms point to the main form of the application for parentage. One of the fields in the TCreateParams structure is WndParent. This parameter specifies the handle of the window that controls the display of the window being created. By setting the secondary form's parent window handle to the Desktop, you remove the link that would normally force the whole application to come to the top when this form comes to the top. Now the code loos like:

procedure TForm1.CreateParams
   (var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do begin
    ExStyle := ExStyle or WS_EX_APPWINDOW;
    WndParent := GetDesktopwindow;
  end;
end;

Note: you could think that it is enough to set ExStyle := WS_EX_APPWINDOW, but this would be wrong. The ExStyle already has some default value in it, we simply want to add the WS_EX_APPWINDOW and we do it by using the OR operator.

DO Stay on TOP
Even though you can set FormStye to fsStayOnTop, the form (not main) remains on top of the desktop and of other forms in the project, except any others that also have FormStyle set to fsStayOnTop. If one fsStayOntop form launches another, neither form will consistently remain on top.
To "stay on top" of all other windows on the desktop, you will have to make the form parent the Desktop (together with fsStayOnTop). For the application's main form, this is already the case, but not for any other forms in your project. To achieve this for your secondary form just override the CreateParams - by adding the WS_EX_TOPMOST to ExStyle flag. Then the StayOnTop property will work as you expect (not relative to all forms of your application but relative to all forms on the desktop).

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do begin
    ExStyle := ExStyle or WS_EX_TOPMOST;
    WndParent := GetDesktopwindow;
  end;
end;

Captionless form
There are many ways you can remove the title bar (the caption bar) from the form. One of them involves modifying the Style flag of the CreateParams record. The SW_CAPTION bit should be "removed" from the Style flag. However, this does not have the desired effect unless you have given the BorderStyle property the value bsNone. Finally, you need a way of moving a form that has no title bar.

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := Params.Style AND NOT WS_CAPTION;
end;

Form with a raised edge
When you are developing Delphi MDI applications, the main form for the application (FormStyle:=fsMDIForm) have that sunken edge that makes it look like a container (which it really is.) If you want an ordinary Delphi form to have an edge like that you'll need to change the CreateParams structure...

Raised edge

procedure TForm3.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle OR WS_EX_OVERLAPPEDWINDOW;
end;

Transparent form
To make a form transparent you should put these 2 lines in form's creation procedure:

procedure TForm1.FormCreate(Sender: TObject);
begin
 Form4.Brush.Style := bsClear;
 Form4.BorderStyle := bsNone;
end;

If you use only that you will notice that the form is transparent but if you put something over it, it will not clear its own background and traces of that object will be left on the form. To solve that you need to make sure that the transparent form's Paint procedure (WM_PAINT) will be called last. To do that you need to override the CreateParams procedure and set the Form's extended style ExStyle with WS_EX_TRANSPARENT.

transparent form

procedure TForm4.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle OR WS_EX_TRANSPARENT;
end;

   Final words
All the previous examples showed you how to add alter display and behaviour of the TForm class in Delphi. In the beginning of the article there was a statement that all controls that derive from TWinControl are created by the call to CreateWindowEx API and therefore have "their own" CreateParams method. This in turn means, that beside changing the look and feel of Delphi forms we can use the same technique to add more functionality to, let say, an Edit Box or a Button.

If you, for example, want a TButton that has a multi lined caption, you should derive a new button component and add BS_MULTILINE to the Style flag. Note that various controls (window, button, listbox, ...) have their own set of styles you can specify in the Style or ExStyle.
On the other hand, if you want to change the style of a control once it is already created you need to use the SetWindowLong (along with GetWindowLong) API call. The function changes an attribute (Style, ExStyle, Parent, ...) of the specified window. In this way you can have a Button with Multiline Caption.

If you have any questions, or you know of a great example of overriding the CreateParams, please post to the Delphi Programming Forum. Of course, download the code for this article befire you start messing on your own.

First page > Let there be a Delphi Form; Reveling the CreateParams structure. > Page 1, 2

©2017 About.com. All rights reserved.