Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to Create a form without a title bar Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
08-Jan-03
Category
VCL-Forms
Language
Delphi 2.x
Views
116
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Lou Adler

How can I create a form that doesn't have a caption, but can be re-sized?

Answer:

Solve 1:

As they say, "There's more than one way to skin a cat," and I can't agree more as 
far as programming is concerned. Let me share a little anecdote with you...

Being the "artistic dude" in my company, I'm always in search of new ways to 
present information to users. I do this by creating non-standard user interfaces 
(which I find rather boring), spicing them up with graphics and multimedia 
features. My philosophy centers around this question: Why should information 
retrieval be a boring task? Well, it shouldn't. And an extension to this question 
could be: Why do business programs have to all look the same? Well, they don't. So 
I choose to build "odd" business user interfaces.

My latest designs have followed game interfacess that use a plethora of high- 
resolution graphics and captionless forms (this is where it all kicks in). In the 
past, I didn't need my forms to move anywhere. But as my interfaces have become 
more complex, I've had to start providing ways to move them. Unfortunately, the 
method that I employed in the original article here, didn't account for clicking 
only in a certain area on a form. You just click and hold the mouse button down 
anywhere on the form, and the form will move. Unfortunately, that isn't always the 
best solution.

For instance, with one of my forms, I created a "pseudo" caption by aligning a 
TPanel at the top of the client area of my form. There's a bit more functionality 
built into the panel, but I wanted it to act very much like a regular caption: a 
click and drag would drag the form, and a double-click would maximize it. With that 
in mind, I set about writing the panel's click and drag method using what I 
originally wrote as a base. It didn't work. So doing a little research and asking a 
couple of questions around the newsgroups, Kerstin Thaler, a very helpful person, 
showed me a real cool method for implementing what I needed to do. Here it is:

1   procedure TMainFrm.Panel1MouseDown(Sender: TObject; Button:
2     TMouseButton;
3     Shift: TShiftState; X, Y: Integer);
4   const
5     SC_DRAGMOVE = $F012;
6   begin
7     if Button = mbLeft then
8     begin
9       ReleaseCapture;
10      Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
11    end;
12  end;


This is such incredibly easy code! Instead of overriding the default NC_HITTEST 
message handler, I could accomplish form movement from the MouseDown of my panel! 
Basically, all the method does is send a WM_SYSCOMMAND message to the form with the 
SC_DRAGMOVE constant to perform a drag move. Kerstin did say, that the $F012 isn't 
documented. But hey! the method works and it works well. So if you have a 
captionless form and want to move it by dragging from one of its child components, 
this is the way to do it!


Solve 2:

Many folks would say, "Just set the BorderStyle of the form to bsNone and you'll 
remove the caption." However, there's a problem with that suggestion: Not only do 
you lose the caption bar, you lose the entire border, which means you can't resize 
the form. The only way to get around this is to go behind the scenes in Delphi. 
Fortunately, it's a relatively simple process.

Delphi is not just ObjectPascal; it is also a very effective wrapper of the Windows 
API (Don't worry, we won't get into the Windows API too much in this article). In 
Windows, every window is created using one of two standard functions: CreateWindow 
and CreateWindowEx. CreateWindow makes a window with standard window styles, while 
CreateWindowEx is the same as CreateWindow, but you can add extended window styles 
to the window you want to create. (I encourage you to read through the help file 
for a thorough discussion of these two API calls since I won't be going into detail 
with these topics.)

When a form is created in Delphi, a call is made to CreateWindowEx &mdash TForm's 
Create method is the wrapper function for this call &mdash and Create passes a 
record structure to CreateWindowsEx through a virtual method of TForm called 
CreateParams.

CreateParams is a virtual method of TForm. This means you can override it which, in 
turn, means you can change the default style of a window when it's created to suit 
your particular needs. For our purposes, we want to eliminate the caption. That's 
easily done by changing the style bits of the LongInt Style field of the 
TCreateParams structure, the record that's passed to CreateWindowEx. Look at the 
code; we'll discuss particulars below:

13  unit NoCap;
14  
15  interface
16  
17  uses
18    SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
19    Controls, Forms, Dialogs, StdCtrls, Buttons, BDE, DB;
20  
21  type
22    TForm1 = class(TForm)
23      Button1: TButton;
24      procedure Button1Click(Sender: TObject);
25    private
26      {Here's what we're overriding}
27      procedure CreateParams(var Params: TCreateParams); override;
28      procedure WMNCHitTest(var Msg: TWMNcHitTest); message WM_NCHITTEST;
29    end;
30  
31  var
32    Form1: TForm1;
33  
34  implementation
35  {$R *.DFM}
36  
37  procedure TForm1.CreateParams(var Params: TCreateParams);
38  begin
39    inherited CreateParams(Params);
40    with Params do
41      Style := (Style or WS_POPUP) and (not WS_DLGFRAME);
42    {or... Style := Style + WS_POPUP - WS_DLGFRAME; which is the
43     equivalent to the above statement}
44  end;
45  
46  procedure TForm1.WMNCHitTest(var msg: TWMNCHitTest);
47  begin
48    inherited;
49    if (msg.Result = htClient) then
50      msg.Result := htCaption;
51  end;
52  
53  procedure TForm1.Button1Click(Sender: TObject);
54  begin
55    Close;
56  end;
57  
58  end.


Notice in the line in CreateParams where I set the Style for the form: Style := 
(Style OR WS_POPUP) AND (NOT WS_DLGFRAME);. My first bit manipulation is Style OR 
WS_POPUP. This means give me the default style bits and make the window a regular 
pop-up window with a resizeable border. The second portion says don't include a 
dialog frame. With respect to this, the WS_DLGFRAME will produce a frame typical of 
dialog boxes. By masking it out, you remove the title bar. WS_POPUP ensures you 
have a resizeable border with which to work.

What about the WMNCHitTest message handler? Well, if you have a form with no title 
bar, you have absolutely no way to move it, because by convention, forms are moved 
by dragging the title bar. By trapping a mouse hit with the WM_NCHITTEST message 
and changing the default behavior of the mouse hit, you can allow dragging of the 
form from the client area.

Read through the Windows API help and look at all the style bits you can set. Play with different combinations to see what you get.

			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC