Академический Документы
Профессиональный Документы
Культура Документы
Applications
by Zarko Gajic
Updated May 13, 2018
The most basic splash screen is just an image, or more precisely, a form with an image, that
appears in the center of the screen when the application is loading. Splash screens are
hidden when the application is ready to be used.
Below is more information on the different types of splash screens you may see, and why
they're useful, as well as steps for creating your own Delphi splash screen for your
application.
If you are a shareware developer, you could use splash screens to remind users to register
the program. These may pop up when the program first launches, to tell the user that they
can register if they want special features or to get email updates for new releases.
Some applications use splash screens to notify the user of the progress of a time-consuming
process. If you look carefully, some really large programs use this type of splash screen
when the program is loading background processes and dependencies. The last thing you
want is for your users to think that your program is "dead" if some database task is
performing.
In this example, depending on the speed of your computer, you will barely see your new
splash screen, but if you have more than one form in your project, the splash screen will
certainly show up.
For more information on making the splash screen stay a bit longer, read through the code
in this Stack Overflow thread.
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
uSplashScreen in 'uSplashScreen.pas' {frmSplashScreen};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
frmSplashScreen := TfrmSplashScreen.Create(nil);
try
frmSplashScreen.Show;
// Create your application forms here
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
unit uSplashScreen;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, ExtCtrls;
type
TfrmSplashScreen = class(TForm)
Timer1: TTimer;
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
Completed: Boolean;
end;
var
frmSplashScreen: TfrmSplashScreen;
implementation
{$R *.dfm}
end.
The splash screen will be visible for minimum time of 3 seconds or more if it will take
more time to create all the forms of your application.
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
On the form which will be the 'splash screen' add the timer, enabled at 3000 interval (3s)
with the following event handler
During the early development stages of the Terian ID Software and related products I was
inspired by the “Creating User Experiences: Fundamental Design Principles” Pluralsight
training course by Billy Hollis. I wanted my software to have specific theme or style that
would make each product identifiable to the same family.
The problem being I am not an artistic type of person, and ideas I have in my head for what
I like and want don’t necessarily translate well to an explanation (As anyone that has tried
to do design work for me can attest to). Fortunately one of the demo’s Billy Hollis
demonstrates has a form design which struck a chord with me. Basically the form was
borderless, with the top right corner cut away.
Having an idea is one thing, however implementing it is another. Not having any
experience with custom form shapes in Delphi I did a bit of research and one common
method involves utilising a transparent image cut to the appropriate shape. This custom
image is combined with a form that has its Color and TransparentColorValue properties set
to a rarely used colour.
▪ Set Height/Width
▪ Set BorderStyle = bsNone
▪ Cleared BorderIcons
▪ Set Color = clTeal (Figured this was a Rarely Used Colour)
▪ Set TransparentColorValue = clTeal
▪ Set TransparentColor = True
These are the basic form properties to allow for a transparent form (when used with a
transparent custom shaped image).
The next step is to add the form objects, which results in the following form structure…
This method works great initially, however it will become cumbersome and time
consuming if you need to add more than half a dozen forms to an application.
Some forms will require resizing functionality, and due to setting the BorderStyle property
to bsNone we can no longer rely on the standard Windows resizing functionality. A
workaround for this is to provide a custom control that mimics a Size Grip in the lower
right corner of the form.
The TSjonesSizeGrip custom control is a simple 10×10 pixel control that descends from
TGraphicControl and contains the Size Grip Image…
If all form objects are anchored appropriately then this is all that is required to enable form
resizing. The only downside is that form resizing is only available by dragging the
SizeGrip, where as standard dialogs can be resized using their borders.
Wanting to find an easier and quicker method I did some additional research and came
across a method that utilises the ‘CreatePolygonRgn’ and ‘SetWindowRgn’ Windows API
calls. These calls would allow me to define a polygon region and then assign that as the
visible region of a form.
As the desired custom shape is the same across all forms, the following Procedure is used
to set the custom form shape
Procedure SetTerianFormShape(wnd : HWND; rect : TRect; rgn : HRGN);
Var
arPts : Array[0..4] of TPoint;
Begin
// Point 1
arPts[0].X := 0;
arPts[0].Y := 0;
// Point 2
arPts[1].X := rect.Width - 30;
arPts[1].Y := 0;
// Point 3
arPts[2].X := rect.Width;
arPts[2].Y := 30;
// Point 4
arPts[3].X := rect.Width;
arPts[3].Y := rect.Height;
// Point 5
arPts[4].X := 0;
arPts[4].Y := rect.Height;
Each form requires its own Polygon Region handle, so we need to add a private variable to
each form to contain this.
private
{ Private declarations }
TerianFormShapeRGN : HRGN; // Variable to hold Polygon Region Handle
To set the custom shape for each form, the OnCreate Event calls the SetTerianFormShape
Procedure…
The form Color property is set to the desired background colour, and no additional shape
objects are required.
Form resizing is handled in a similar way to method 1. However, due to the Window
Region being set via a static polygon on form creation you need to reset the polygon region
to allow the form to be visible outside the initial bounds of the form (in the event of
increasing the form size). To perform this you simply Unset the Custom Form shape,
perform the resize, and then reset the Form Shape like follows…
UnSetTerianFormShape(self.Handle);
// 11/Mar/2013 - ADowling
// ---
// We temporarily set doublebuffering here to help reduce the amount
of flickering that occurs when
// resizing the form.
// ---
self.DoubleBuffered := True;
ReleaseCapture;
Perform(wm_SysCommand, sc_DnRightsize, 0);
self.DoubleBuffered := False;
SetTerianFormShape(self.Handle, self.ClientRect,
self.TerianFormShapeRGN);
CustomResizing := False;
end;
Note: The additional variable called CustomResizing (defined in forms
implementation) helps ensure the FormResize event does not attempt to reset the custom
form shape when using the SizeGrip.
Similarly to the method 1 if all form objects are anchored appropriately no other processes
are required to handle form resizing.
If method 2 is used to provide a custom form shape for the main form of an application,
there is a small issue in regards to form resizing. If an applications shortcut is set to run the
application Maximised then the custom form shape is not reset, and part of the form will
not be displayed.
To avoid this issue you need to reset the custom form shape as part of the Form onResize
event…
So far it works:
So far using method 2 has worked a charm, and from the end user perspective they seem
quite happy. Granted method 1 also worked well, and from the end user perspective they
noticed no difference, however the ease of creating new forms with method 2 is certainly
far superior than messing around with multiple shape objects.
One item still on my to-do list, is testing these methods with font scaling to see how that
might affect the forms and/or resizing.