Forms
From: bpeck@prairienet.org (Bob Peck)
You bet! First, select File|New Project and choose "CRT Application" from the Browse Gallery dialog. This will provide you with a project that is still a Windows program, but WriteLn, ReadLn will be allowed in a Window but work like they did in DOS. If you wish, you can remove the WinCrt unit from the uses statement (if no user input/output is required, but is nice for debugging).
I've done this before just to see how small an app can be and I've been able to create a simple EXE (it just beeps) that is only 3200 bytes or so in size! Try to do that in C++ these days!
BTW, these "formless" apps are still Windows applications, so they can still call the Windows API routines. You'll just need to add WinProcs, WinTypes to your uses clause. You'll probably also want to add SysUtils and any other unit you find yourself needing.
From: "Mark R. Holbrook" <markh@sysdyn.com>
It's pretty simple.
Create a form and put the logo on it using a Timage component. My example below assumes you have created a logo form called "logoform" Go to your project options and set the form to NOT be autocreated.
Then in your PROJECT.DPR file just after the begin statement do something like the following:
logoform := TLogoform.Create(nil); logoform.Show; { NOTE! show! NOT showmodal } . . { Do other app startup stuff here like open databases etc... } . . { Just after the block of code that creates all your forms and before the Application.Run statement do: } logoform.Hide; logoform.Release;
This will display your logo form until you actually start the app running.
From: mger@sbox.tu-graz.ac.at (Matthias Gerstgrasser)
The following is from DKBS Helpfile (Delphi Knowledge Base System), they state, that this is one of Borland's TI's:
Q: How can I make a form move by clicking and dragging in the client area instead of on the caption bar?
A: The easiest way to do this is to "fool" Windows into thinking that you're actually clicking on the caption bar of a form. Do this by handling the wm_NCHitTest windows message...
type TForm1 = class(TForm) private { Private-Deklarationen } public { Public-Deklarationen } procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.WMNCHitTest(var M: TWMNCHitTest); begin inherited; { call the inherited message handler } if M.Result = htClient then { is the click in the client area? } M.Result := htCaption; { if so, make Windows think it's } { on the caption bar. } end;
From: Bill Dekleris <quasar@prometheus.hol.gr>
You must trap WM_GETMINMAXINFO message:
in your form's class declaration put this :
procedure WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
and in the implementation section :
procedure TMyForm.WMGetMinMaxInfo(var Msg: TWMGetMinMaxInfo); begin { ---------------------------------------------} { Put your numbers in place of } { MIN_WIDTH, MIN_HEIGHT, MAX_WIDTH, MAX_HEIGHT } { } { To allow only horizontal sizing, put } { form's 'Height' property in place of MIN_HEIGHT, MAX_HEIGHT } { ---------------------------------------------} Msg.MinMaxInfo^.ptMinTrackSize := Point(MIN_WIDTH, MIN_HEIGHT); Msg.MinMaxInfo^.ptMaxTrackSize := Point(MAX_WIDTH, MAX_HEIGHT); inherited end;
It should work fine.
From: "James D. Rofkar" <jim_rofkar%lotusnotes1@instinet.com>
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'm 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...
From: Oliver.Bollmann@t-online.de (Oliver Bollmann)
Hallo, here are examples you need, I hope:
procedure SaveToField(FField:TBlobField;Form:TComponent); var Stream: TBlobStream; FormName: string; begin FormName := Copy(Form.ClassName, 2, 99); Stream := TBlobStream.Create(FField, bmWrite); try Stream.WriteComponentRes(FormName, Form); finally Stream.Free; end; end; procedure LoadFromField(FField:TBlobField;Form:TComponent); var Stream: TBlobStream; I: integer; begin try Stream := TBlobStream.Create(FField, bmRead); try {delete all components} for I := Form.ComponentCount - 1 downto 0 do Form.Components[I].Free; Stream.ReadComponentRes(Form); finally Stream.Free; end; except on EFOpenError do {nothing}; end; end;
From: AVONTURE Christophe <Christophe.AVONTURE@is.belgacom.be>
ShowWindow (Form1.Handle, SW_HIDE);
From: "James D. Rofkar" <jim_rofkar%lotusnotes1@instinet.com>
First, override the "CreateParams" method of your Form, by declaring this in either your Form's protected or public section:
procedure CreateParams(var Params: TCreateParams); override;
Then, in the actual CreateParams() method, specify something like this:
procedure TForm1.Createparams(var Params: TCreateParams); begin inherited CreateParams(Params); with Params do Style := (Style or WS_POPUP) and (not WS_DLGFRAME); end;
Hopefully, you'll provide some UI mechanism for moving and closing the window.
From: ao@atlas.sto.foa.se (Anders Ohlsson)
Someone asked for some code to make a form with no title bar moveable, kind of like a floating toolbar, for example FreeDock. Actually, for some of the stuff in here I spied on the FreeDock sources...This requires the use of some WinAPI functions. All WinAPI functions are however available at a touch of a key (F1 - OnLine Help)...
Here's some code that does this (about 100 lines)...
To make this work like intended:
OR start a new project, make the form's borderstyle bsNone, add a panel, set the border style of the panel to bsSingle, add another panel with some caption, add a button that says 'toggle title bar', cut out the below code and insert it were it should be, enable the panel's three event handlers (MouseDown, MouseMove, MouseUp), enable the button's event handler (Click). Hope I didn't forget anything... ;-) It's done faster in Delphi than it's written here... ;-)
unit Unit1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm1 = class(TForm) Panel1: TPanel; Panel2: TPanel; Button1: TButton; procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button1Click(Sender: TObject); private { Private declarations } OldX, OldY, OldLeft, OldTop : Integer; ScreenDC : HDC; MoveRect : TRect; Moving : Boolean; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then begin SetCapture(Panel1.Handle); ScreenDC := GetDC(0); OldX := X; OldY := Y; OldLeft := X; OldTop := Y; MoveRect := BoundsRect; DrawFocusRect(ScreenDC,MoveRect); Moving := True; end; end; procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Moving then begin DrawFocusRect(ScreenDC,MoveRect); OldX := X; OldY := Y; MoveRect := Rect(Left+OldX-OldLeft,Top+OldY-OldTop, Left+Width+OldX-OldLeft,Top+Height+OldY-OldTop); DrawFocusRect(ScreenDC,MoveRect); end; end; procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Button = mbLeft then begin ReleaseCapture; DrawFocusRect(ScreenDC,MoveRect); Left := Left+X-OldLeft; Top := Top+Y-OldTop; ReleaseDC(0,ScreenDC); Moving := False; end; end; procedure TForm1.Button1Click(Sender: TObject); var TitleHeight, BorderWidth, BorderHeight : Integer; begin TitleHeight := GetSystemMetrics(SM_CYCAPTION); BorderWidth := GetSystemMetrics(SM_CXBORDER)+GetSystemMetrics(SM_CXFRAME)-1; BorderHeight := GetSystemMetrics(SM_CYBORDER)+GetSystemMetrics(SM_CYFRAME)-2; if BorderStyle = bsNone then begin BorderStyle := bsSizeable; Top := Top-TitleHeight-BorderHeight; Height := Height+TitleHeight+2*BorderHeight; Left := Left-BorderWidth; Width := Width+2*BorderWidth; end else begin BorderStyle := bsNone; Top := Top+TitleHeight+BorderHeight; Height := Height-TitleHeight-2*BorderHeight; Left := Left+BorderWidth; Width := Width-2*BorderWidth; end; end; end.
From: Steve Teixeira
unit Dragmain; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.WMNCHitTest(var M: TWMNCHitTest); begin inherited; { call the inherited message handler } if M.Result = htClient then { is the click in the client area? } M.Result := htCaption; { if so, make Windows think it's } { on the caption bar. } end; procedure TForm1.Button1Click(Sender: TObject); begin Close; end; end.
Ti2861 - Form display with different screen resolutions.
from the Delphi Technical Support area of our web site at www.borland.com.