There is nothing wrong with your television set. Do not attempt to adjust the picture.
1 Apr 2008
The first thing to do is to create some stunning graphics for your splash screen. My artistic skills are somewhat, um, limited, so I usually just go with a logo or thematic symbol of some sort and apply some effects. Since we would like to show of the alpha blending, a fat drop shadow, some glow and maybe a lense flare is probably a good choice.
If you are lazy there’s plenty of free goodies you can use to get started. The important thing for now is that we should end up with an image that contains some semitransparent areas.
With your PhotoShop image at hand you should now be ready to practice the black art of creating a premultiplied bitmap. From my research on this topic it appears to be a closely guarded secret known only to a select few ninja PhotoShoppers, as none of the instructions I have found worked for me. The following however works:
Shift+Ctrl+E
).Shift+Ctrl+[
).Ctrl+Click
on the layer or Right-click on the layer+Select Pixels).With any luck you should now have created the magic bitmap. Now we just need an application to display it, so without further ado we move on to…
Ready? OK, fire up Delphi and… download the source code. I won’t guide you through the steps needed to create this tiny application. Instead let me explain the key points while you browse through the code:
The project file has been modified so the splash form isn’t created with TApplication.CreateForm
. This is important because the first form that is created with TApplication.CreateForm
automatically becomes the application’s main form and we don’t want that to happen. Why? Because the application terminates once the main form is destroyed. Instead the splash form is created anonymously and its Execute
method is called.
program AlphaSplashDemo; ... begin Application.Initialize; Application.MainFormOnTaskbar := True; with TFormSplash.Create(Application) do Execute; Application.CreateForm(TForm1, Form1); Application.Run; end.
Moving on to the splash form, the Position
property has been set to poScreenCenter
so the form will center itself on the screen and the FormStyle
property has been set to fsStayOnTop
so it will stay on top of other forms.
The OnFormClose
event handler makes sure the form is destroyed when it it closed and the OnKeyPress
event handler just makes it easier to close the form during tests.
procedure TFormSplash.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; procedure TFormSplash.FormKeyPress(Sender: TObject; var Key: Char); begin Close; end;
The WM_NCHITTEST
message handler makes it possible to move the form even though it hasn’t got a caption or a border.
procedure TFormSplash.WMNCHitTest(var Message: TWMNCHitTest); begin Message.Result := HTCAPTION; end;
The Execute
method contains the meat. In it we set the WS_EX_LAYERED
window flag, load the bitmap and resize the window to fit the bitmap. Then the alpha blending parameters are prepared and UpdateLayeredWindow
is called. Finally we start a timer to close the splash form after a short while. Don’t display the splash form for too long or you will just annoy your users.
procedure TFormSplash.Execute; var BlendFunction: TBlendFunction; BitmapPos: TPoint; BitmapSize: TSize; exStyle: DWORD; Bitmap: TBitmap; begin // Enable window layering exStyle := GetWindowLongA(Handle, GWL_EXSTYLE); if (exStyle and WS_EX_LAYERED = 0) then SetWindowLong(Handle, GWL_EXSTYLE, exStyle or WS_EX_LAYERED); Bitmap := TBitmap.Create; try Bitmap.LoadFromFile('splash.bmp'); ASSERT(Bitmap.PixelFormat = pf32bit, 'Wrong bitmap format - must be 32 bits/pixel'); // Resize form to fit bitmap ClientWidth := Bitmap.Width; ClientHeight := Bitmap.Height; // Position bitmap on form BitmapPos := Point(0, 0); BitmapSize.cx := Bitmap.Width; BitmapSize.cy := Bitmap.Height; // Setup alpha blending parameters BlendFunction.BlendOp := AC_SRC_OVER; BlendFunction.BlendFlags := 0; BlendFunction.SourceConstantAlpha := 255; BlendFunction.AlphaFormat := AC_SRC_ALPHA; // ... and action! UpdateLayeredWindow(Handle, 0, nil, @BitmapSize, Bitmap.Canvas.Handle, @BitmapPos, 0, @BlendFunction, ULW_ALPHA); Show; finally Bitmap.Free; end; // Start timer to hide form after a short while TimerSplash.Enabled := True; end;
When you run the demo application, with the sample bitmap, it should look something like this:
You can replace the bitmap I have provided with your own. Just copy it to the demo folder and name it splash.bmp.
In this part we used a windows bitmap for the splash screen. While this works just fine, 32-bit bitmaps can easily get quite big (the demo bitmap is almost 1Mb in size) and they add a considerable overhead to an application - with little benefit to the end user. Wouldn’t it be nice if we could compress the bitmap to minimize the overhead?
In the second part of this article, I will modify the demo application to use a compressed PNG image instead of a BMP. I will also move the bitmap to a resource file, demonstrate run-time premultiplication and enhance the splash screen with a few visual gimmicks.
The source code that accompany this article are known to be compatible with the following versions of Delphi:
D1 | D2 | D3 | D4 | D5 | D6 | D7 | D2005 | D2006 | D2007 |
This work is licensed under a
Creative Commons Attribution-Share Alike 3.0 Unported License.
Download: | Alpha Blended Splash Form - Part 1 |
---|---|
Version: | 1.1 |
Updated: | 27 May, 2008 |
Size: | 56.7 KB |
Notes: | Includes source and sample images. |
Downloads: | 15,341 |
Thanks from Argentina!
I'm looking for this a long time and with this article finally can understand something.
PD: sorry for my poor english
This AlphaBlending is REALLY GREAT!!! I've been looking for it ever since Konfabulator (Yahoo Widgets) came out!! You have saved my life!
The only thing I need now is to put other components onto the form. I completely undertsand why you can't but there must be a way …
How can this be done?
Thanks Anders. Can you explain how similar effects (alpha-blending) could be achieved for windowed controls (e.g.
TPanel
)?UpdateLayeredWindow
and friends only work on top level windows.For alpha blended controls, you'll have to resort to third party libraries.
Thanks heaps, this will help with my problems with trying to find a way to do this!
Waiting in anticipation on being able to use pngs to do this!
Any word on how far away part 2 will be?
I've been busy with the Drag and Drop Component Suite, but now that that's out the way I hope to get the last part finished within the next two weeks.
Part 2 has been posted.
For those dudes who will use it in Delphi 7:
To compile this demo using Delphi 7 you need to remark line
// Application.MainFormOnTaskbar := True;
Then, after message
RLINK32: Too many resources to handle
delete AlphaSplashDemo.res and delphi will recreate it.
Hi, I’m still having issues on Delphi7 with the line:
I have followed these steps but still
RLINK32: Too many resources to handle
Does anybody offer any solutions?
Regards ^^
Hi, First I want to thank the examples that you have placed on the web. But I have a doubt. How can I do to show the controls that I put on Splash form. For example buttons, labels and so on. The picture always hide my components.
I'm trying to make a splash and login screen in a single Form.
Thanks.
Olá vc conseguiu fazer aparecer os controles no form? se sim, poderia me passar como fez?
Muito Obrigado
Ivan
Rodrigo,
I also pointed this out, and unfortunately you must download or buy third-party components to do this, such as AlphaControls.com (freeware).
I will at some stage post a link of the farthest I have been to doing this. I made a little widget that shuts down your computer and performs other related tasks.
Will let you guys know…
very good, like, I would like to know if there is like putting buttons on that form, I would like to create a floating toolbar equal the http://rocketdock.com/
Good indeed, if you don't own the FXlib VCL:
"FXLib is an easy-to-use set of components that enables you to create amazing splash screens, form and image transition effects, using all the power of its advanced rendering engine. Over 70 families of animation and transition effects with hundreds of variations. Real-time rendering. WYSIWYG editing in both design-time and run-time, preview"
http://www.ksdev.com/
FXLib (by ksdev) does not support translucent PNG splash screen. It only masks, not the same thing…
Hey Anders!
Could you show some screenies in the photoshop tutorial, where you make the picture ready for the alpha blending? I am kinda stuck there. If you could show a screenie for each step it would be great!
Thanks!
A screen shot for each step? No, I don't think so. The steps are very simple and the description should be enough to get you through. Sorry.
Hi there, Anders I must say that i almost get what i wanted, i mean, i got the transparency and everything goes ok, but i still have the problem that i can not put standard controls on the layered window. My question is…
is there any way to do that??…at least any "triky" way or something?? I have searched through the inet and some people say something about making a "fake" window over the original or something about to draw our own controls, for example by sending the appropriate
WM_PRINT
messages with the correct DC, anyway, can you give me some tip about it???Thanks for such a great paper
Depending on what you need there are easier ways to get a transparent form.
1. Drop a TImage and load a bitmap BMP. The parts of the image that should be transparent should have a specific color e.g. clFuchsia.
2. Set the TImages Transparent property to True.
3 Set the Forms TransparentColor property to True, the TransparentColorValue to clFuchsia and the Color property to clFuchsia.
4. Set the Position, BorderStyle etc. properties on the form as you please.
If the TImage covers the entire form there's no need to set the forms color property. This does not seem to work with PNG images regardless if they are alpha-channel transparent or if they use a specific transparent color like clFuchsia so as far as I can tell your only option is to use BMPs.
Um… The whole point of this article is that the output is transparent and alpha blended.
The TForm.TransparentColor method, which I mentioned above in the section "Different Kinds of Transparency, Color Key transparency", does not support alpha blending.
Anders,
Of course, but I expect that many that just want a transparent form will read this article (as I did). It is not obvious that using transparentcolor does work with BMP but not with PNG (no alpha transparency used). This must be considered to be a bug in the VCL.
I just tried it with a PNG in Delphi XE. It worked fine.
Really? I had a test project that used a BMP that worked fine. I opened the BMP and re-saved it as PNG in Paint.NET and loaded that into the
TImage
. TheclFuchsia
color appeared then. Have you done any other steps?Color
=clFuchsia
,TransparentColor
=True
andTransparentColorValue
=clFuchsia
.TImage
control on the form and setAlign
=alClient
andStretch
=True
.TImage
.Be aware that any semi-transparent pixels in the PNG will appear as blended onto
clFuchsia
, so you need to make sure that all PNG pixels are either 100% opaque or 100% transparent.Thanks Anders,
I got it to work now. I must have messed it up when editing the image in Paint.NET.
After some time of researching, I finally have found a way to place child controls on layered windows. Thanks to this code of Jerry.Wang, I have reached my goal. You can read his article on codeproject.com for better understanding, but anyway, the whole point is this.
[edit: Excessive quote snipped]
Sorry for such a big comment, but I think this may be of help to someone as it was to me.
One more time, thanks Anders, for such a great paper, it is worthy of reading, thanks, bye.
thanks
Thanks, but i am searching for a TPanel or TLabel that has such alphablend.
I mean: A non transparent form and over it some Panels, one of them must let show what is under it.
For example: A Tipical Panel with "drawing in progress…" over the long time taking drawing proccess on the TForm.Canvas… so while the graphic is been painting the TPanel is shown, but lets see though it the TForm canvas.
Imagine you have a very long process that creates a curve on the TForm.Canvas… while drawing it you need to make Visible a TPanel, but you want to see what is under it with some alphablend, not opaque, not transparent.
So i need a way to add something like AlphaBlend properties of a TForm to a TPanel.
Hope it can be understand.