mastaraymond
2007-07-24 14:23:31
Ok, yesterday i learned Forms. I've read some tutorials, did some testing. And i found out something cool! You are able to load a form in a special shape for example: Circle!
For this tutorial you need:
1) Canvas knowledge.
2) Form knowledge
3) Little bit math, for making the shapes ;).
2 Examples before starting ;).

Lets start!
First we load a simple form without a bar. If we do this, we need a way of closing it. Thats why we add a simple button that closes the form, here we go:
A side note, [YourForm].color changes the color, but [YourForm].Brush.Color does also change it ;).
Brush styles change the way huh, what styles do we got?
Here you go:
bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross. O we see 1 special one! 'bsClear', yeah this one is the one we need! bsClear draws something a canvas transparent! So if we add 'OurForm.Brush.Style := bsClear;' we cannot see the window anymore, because its transparent! The coolest thing is now, we can still see the button. Notice: OurForm.Brush.Style := bsClear; must come AFTER the .color chooses! Otherwise, our form will not be transparent!
Cool, we got a button with a transparent form! Now, comes the coolest part, we can change the way our form is supposed to look! How? Quite simple, because we can still enter the Form canvas! So if we edit the canvas, the form canvas will be edited to! I made a simple example for you guys:
But, wait, you putted a Sender : TObject in it, why? Because we need to load this procedure, we are going to load this procedure when the form is going to paint his canvas. In our case it would be: OurForm.OnPaint := @PaintCircle;
Try it, add that line and run it! You should see a form in the shape of a circle right now!
I hope you got how it works :p. Otherwise just post ;).
Here below i posted my Form shape script with a few form shapes:Triangle,Box,Pacman or Circle.
EDIT: Small note: once its loaded, the transparent part, will not change:p. For example i got a black background, i load the form, it will have a black transparent part. Then somehow my background changes to white, the transparent part will stay black! :(. Unless you load the form again ;). So, if you want to prevent this, add a TTimer that makes the form invisible & visible every sec?
UPDATE: Dragging the form!
Ok, if you know how the shaped forms work, we need to add something: Dragging it! All credits for finding out how you can load a new 'transparent' background goes to Widget!
Lets start, first we are going to declare 2 variables:
Let me explain it! If we click at the form, it will activate procedure start:
1 Note, you need to hide scar, before calling the form, otherwise you will see trails. I have no idea why, it just is… *cough* Costed me 1 hour to find out ^^ *cough*
The updated script with dragging enabled!
~Raymond
For this tutorial you need:
1) Canvas knowledge.
2) Form knowledge
3) Little bit math, for making the shapes ;).
2 Examples before starting ;).

Lets start! First we load a simple form without a bar. If we do this, we need a way of closing it. Thats why we add a simple button that closes the form, here we go:
program New;
var
OurForm : TForm;
Button : TButton;
procedure InitAndLoadForm;
begin
OurForm := CreateForm;
OurForm.SetBounds(0, 0, 300, 300);
OurForm.Top := 50;
OurForm.Left := 50;
OurForm.Color := clBlack;
OurForm.BORDERSTYLE:= bsnone;
Button := TButton.Create(OurForm);
Button.Parent := OurForm;
Button.SetBounds(0,0,40,20);
Button.Top := 140;
Button.Left := 130;
Button.Caption := 'Close';
Button.ModalResult := mrOk;
Ourform.ShowModal;
end;
procedure SafeLoadForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitAndLoadForm', v);
end;
begin
SafeLoadForm;
FreeForm(Ourform);
end.Cool, it loads a black screen with a button in the middle. Click it and the form will close! Ok, lets go on. When a form gets loaded, it uses the brush to fill in the canvas of the form ( I think:rolleyes:). So basicly if we change the brush style, the way of filling it in, we can change how it looks!A side note, [YourForm].color changes the color, but [YourForm].Brush.Color does also change it ;).
Brush styles change the way huh, what styles do we got?
Here you go:
bsSolid, bsClear, bsHorizontal, bsVertical, bsFDiagonal, bsBDiagonal, bsCross, bsDiagCross. O we see 1 special one! 'bsClear', yeah this one is the one we need! bsClear draws something a canvas transparent! So if we add 'OurForm.Brush.Style := bsClear;' we cannot see the window anymore, because its transparent! The coolest thing is now, we can still see the button. Notice: OurForm.Brush.Style := bsClear; must come AFTER the .color chooses! Otherwise, our form will not be transparent!
Cool, we got a button with a transparent form! Now, comes the coolest part, we can change the way our form is supposed to look! How? Quite simple, because we can still enter the Form canvas! So if we edit the canvas, the form canvas will be edited to! I made a simple example for you guys:
procedure PaintCircle(Sender: TObject);
begin
Ourform.Canvas.Brush.Color := clBtnFace;
Ourform.Canvas.Pen.Color := clActiveBorder;
Ourform.Canvas.Ellipse(0,0,300,300);
SafeCopyCanvas(Ourform.Canvas, Ourform.Canvas, 0, 0, 280, 280, 0, 0, 280,280);
end; You see? First we edit the colors of the brush & pen, then we make a circle on the canvas and then we load it onto the original!But, wait, you putted a Sender : TObject in it, why? Because we need to load this procedure, we are going to load this procedure when the form is going to paint his canvas. In our case it would be: OurForm.OnPaint := @PaintCircle;
Try it, add that line and run it! You should see a form in the shape of a circle right now!
I hope you got how it works :p. Otherwise just post ;).
Here below i posted my Form shape script with a few form shapes:Triangle,Box,Pacman or Circle.
See below!EDIT: Small note: once its loaded, the transparent part, will not change:p. For example i got a black background, i load the form, it will have a black transparent part. Then somehow my background changes to white, the transparent part will stay black! :(. Unless you load the form again ;). So, if you want to prevent this, add a TTimer that makes the form invisible & visible every sec?
UPDATE: Dragging the form!
Ok, if you know how the shaped forms work, we need to add something: Dragging it! All credits for finding out how you can load a new 'transparent' background goes to Widget!
Lets start, first we are going to declare 2 variables:
StartX,StartY : Integer; This are integers of the mouse position at the start ;). Then we add 3 events!
OurForm.OnMouseDown := @Start;
OurForm.OnMouseMove := @DragTheForm;
OurForm.OnMouseUp := @Stop;
.Let me explain it! If we click at the form, it will activate procedure start:
procedure Start(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin;
GetMousePos(StartX,Starty);
end; We need to get the start position of the mouse ofcourse! So we clicked the form, now we want the form to move if we hold the left mouse button, thats why i made a procedure DragTheForm, on the event : OnMoveMouse!
Then if procedure DragTheForm(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
Tempx,Tempy : Integer;
begin;
GetMousePos(Tempx,Tempy);
if (ssleft in shift) and not (Starty=Tempy) and not (Startx = Tempx) then
begin;
OurForm.Visible := False;
OurForm.Top := OurForm.Top - (starty-tempy);
OurForm.Left := OurForm.Left - (startx-tempx);
Startx := Tempx;
Starty := Tempy;
OurForm.Visible := True;
end;
end; It gets the current position of the mouse, then it checks if the left button is down and the start coords aren't the same as the coords we have now. Then it hides the form, changes the position of the form and shows it again! With Visible := false & true, you can make the background 'transparent' again ;). Ok, cool, now we need only 1 more procedure. A procedure that is called if the stop holding the mouse!
procedure Stop(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin;
OurForm.Visible := False;
Sleep(50);
OurForm.Visible := True;
end; This procedure will make sure, you don't see any trails!1 Note, you need to hide scar, before calling the form, otherwise you will see trails. I have no idea why, it just is… *cough* Costed me 1 hour to find out ^^ *cough*
The updated script with dragging enabled!
program New;
var
OurForm : TForm;
Button : TButton;
StartX,StartY : Integer;
const
Shape = 'pacman'; //What shape you want our form to be? Triangle,Box,Pacman or Circle?
procedure DragTheForm(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
Tempx,Tempy : Integer;
begin;
GetMousePos(Tempx,Tempy);
if (ssleft in shift) and not (Starty=Tempy) and not (Startx = Tempx) then
begin;
OurForm.Visible := False;
OurForm.Top := OurForm.Top - (starty-tempy);
OurForm.Left := OurForm.Left - (startx-tempx);
Startx := Tempx;
Starty := Tempy;
OurForm.Visible := True;
end;
end;
procedure Start(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin;
GetMousePos(StartX,Starty);
end;
procedure Stop(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin;
OurForm.Visible := False;
Sleep(50);
OurForm.Visible := True;
end;
Procedure PaintTriangle(Sendet : TObject);
var
TempCanvas : TCanvas;
I,II : INteger;
begin;
TempCanvas := Ourform.Canvas;
Ourform.Canvas.Pen.Color := clBtnFace;
Ourform.Canvas.Pen.Width := 1;
For I:= 0 to 150 do
begin;
TempCanvas.Moveto(I,150-I);
TempCanvas.LineTo(I,150+I);
II := 300-I;
TempCanvas.Moveto(II,150-I);
TempCanvas.LineTo(II,150+I);
end;
Ourform.Canvas.Pen.Color := clActiveBorder;
Ourform.Canvas.Pen.Width := 1;
TempCanvas.MoveTo(150,0);
TempCanvas.LineTo(0,150);
TempCanvas.LineTO(150,300);
TempCanvas.Lineto(300,150);
TempCanvas.LineTo(150,0);
SafeCopyCanvas(TempCanvas, Ourform.Canvas, 0, 0, 300, 300, 0, 0, 300,300);
end;
Procedure PaintBox(Sender : TObject);
var
TempCanvas:Tcanvas;
begin;
TempCanvas := Ourform.Canvas;
Ourform.Canvas.Brush.Color := clBtnFace;
Ourform.Canvas.Pen.Color := clActiveBorder;
TempCanvas.RoundRect(0,0,300,300,50,50);
SafeCopyCanvas(TempCanvas, Ourform.Canvas, 0, 0, 300, 300, 0, 0, 300,300);
end;
Procedure PaintPacman(Sender: TObject);
var
TempCanvas:TCanvas;
begin;
TempCanvas := Ourform.Canvas;
Ourform.Canvas.Brush.Color := clBtnFace;
Ourform.Canvas.Pen.Color := clActiveBorder;
TempCanvas.Pie (0,0,300,300,300,50,300,250);
SafeCopyCanvas(TempCanvas, Ourform.Canvas, 0, 0, 300, 300, 0, 0, 300,300);
end;
procedure PaintCircle(Sender: TObject);
begin
Ourform.Canvas.Brush.Color := clBtnFace;
Ourform.Canvas.Pen.Color := clActiveBorder;
Ourform.Canvas.Ellipse(0,0,300,300);
SafeCopyCanvas(Ourform.Canvas, Ourform.Canvas, 0, 0, 280, 280, 0, 0, 280,280);
end;
Procedure ChooseShape(Sender : TObject);
begin;
Case LowerCase(Shape) of
'triangle': PaintTriangle(Sender);
'box' : PaintBox(Sender );
'pacman' : PaintPacman(Sender );
'circle' : PaintCircle(Sender );
end;
end;
procedure InitAndLoadForm;
begin
OurForm := CreateForm;
OurForm.SetBounds(0, 0, 300, 300);
OurForm.Top := 50;
OurForm.Left := 50;
OurForm.BORDERSTYLE:= bsnone;
OurForm.Brush.style := bsclear;
OurForm.OnMouseDown := @Start;
OurForm.OnMouseUp := @Stop;
OurForm.OnMouseMove := @DragTheForm;
OurForm.Onpaint := @ChooseShape;
Button := TButton.Create(OurForm);
Button.Parent := OurForm;
Button.SetBounds(0,0,40,20);
Button.Top := 140;
if LowerCase(Shape) = 'pacman' then
Button.Left := 110
else Button.Left := 130;
Button.Caption := 'Close';
Button.ModalResult := mrOk;
Ourform.ShowModal;
end;
procedure SafeLoadForm;
var
v: TVariantArray;
begin
setarraylength(V, 0);
ThreadSafeCall('InitAndLoadForm', v);
end;
begin
GetSelf.Hide;
SafeLoadForm;
FreeForm(Ourform);
GetSelf.Show;
end.If you see any spelling, grammar or other mistakes, tell me! This is my first tutorial and Im not good at English ;)~Raymond