How To Use UpdateLayeredWindow
In this post I will briefly explain how to use layered windows and specifically how to use UpdateLayeredWindow.
The first thing you need to do is add the WS_EX_LAYERED style to your window. This can for example be done with a call to CreateWindowEx:
hWnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
After your window is created we will load a PNG file with an alpha channel and use UpdateLayeredWindow to render the PNG on the window using the alpha channel of the PNG file as the transparency level for the window. This is done as follows:
// Load our PNG image CImage img; img.Load("circle.png"); // Get dimensions int iWidth = img.GetWidth(); int iHeight = img.GetHeight(); // Make mem DC + mem bitmap HDC hdcScreen = GetDC(NULL); HDC hDC = CreateCompatibleDC(hdcScreen); HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight); HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, hBmp); // Draw image to memory DC img.Draw(hDC, 0, 0, iWidth, iHeight, 0, 0, iWidth, iHeight); // Call UpdateLayeredWindow BLENDFUNCTION blend = {0}; blend.BlendOp = AC_SRC_OVER; blend.SourceConstantAlpha = 255; blend.AlphaFormat = AC_SRC_ALPHA; POINT ptPos = {0, 0}; SIZE sizeWnd = {iWidth, iHeight}; POINT ptSrc = {0, 0}; UpdateLayeredWindow(hWnd, hdcScreen, &ptPos, &sizeWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA); SelectObject(hDC, hBmpOld); DeleteObject(hBmp); DeleteDC(hDC); ReleaseDC(NULL, hdcScreen);
Because I’m using CImage, you need to include the atlimage.h header.
That’s all that is required for the basics of UpdateLayeredWindow.
NOTE: The example above does not include any error checking. That is left for the reader as an excercise.
Kay said,
Wrote on June 17, 2009 @ 10:30 am
Hi, thanks for that post.
Could you maybe extend this example to show how to use UpdateLayeredWindow with UI Controls like buttons etc?:)
I cant find any solution for this. What i exactly need is to know how i can Use my PNG with alpha channel as background and a set of other pngs as buttons/ui controlls
Marc Gregoire said,
Wrote on June 17, 2009 @ 12:21 pm
In my example I have this device context called hDC which will be used in the call to UpdateLayeredWindow. This is just a 32bit device context, so RGB and A channels. If you want to add PNG based buttons, load the PNGs (maybe using CImage class) and then render those PNGs at the right position in the hDC. Store the coordinates of your PNG buttons somewhere so you can use the coordinates in your WM_MOUSEMOVE and mouse button messages. Once everything is rendered to hDC, call UpdateLayeredWindow. I think this should give you what you want.
Ovidiu said,
Wrote on July 5, 2009 @ 7:12 pm
Hi, Marc,
Is it possible the inverse operation, i.e. saving A channel in a (png) file given a layered window?
Marc Gregoire said,
Wrote on July 5, 2009 @ 7:34 pm
Hi Ovidiu 🙂
I don’t know if that would be possible. I never tried it myself. Why do you need something like that?
Did you try to get the HDC of the layered window? Maybe that HDC is a 32bit device context including the alpha channel…
Tom said,
Wrote on December 13, 2009 @ 1:09 am
Hello
I have VC++ 6.0 which doesn’t seem to have the CImage class (atlimage.h).
Could you possibly write another version that simply loads a BMP?
I believe the latest version of BMP does support transparency.
Thank you
Marc Gregoire said,
Wrote on December 13, 2009 @ 12:34 pm
I tried to make a BMP file with an alpha channel in two photo editors but they don’t allow it.
Maybe you can use another library to load PNG files?
Maybe this one: http://www.codeguru.com/cpp/g-m/bitmap/otherformats/article.php/c4899/ ?
neptunecentury said,
Wrote on December 29, 2009 @ 6:13 pm
@Marc
GIMP for Windows is an excellent image editor and supports 32-bit BMPs. I have created transparent bitmaps with editor for use in my applications, but I have no use for 32-bit bmps as I now use the GDI+ library and it supports loading png files. However, if you want to create an example with loading just BMPs, you could create them with GIMP. http://www.gimp.org/windows/
Marc Gregoire said,
Wrote on December 30, 2009 @ 1:39 pm
Interesting. I have used GIMP before, but didn’t know it supports 32 bit BMP files.
When I find some more time I might give it a try.
Prabhat said,
Wrote on March 17, 2010 @ 11:43 am
Hi ,
I want to use Webbrowser control with transparent dialog. dilaog box should transparent but webbrowser control part should not transparent.
Thanks,
prabaht singh.
Marc Gregoire said,
Wrote on March 17, 2010 @ 3:53 pm
Try the above procedure. Create your bitmap and make sure the part where the webbrowser control should appear is not transparent;
DavidFeng said,
Wrote on September 13, 2010 @ 9:46 am
Hi:
Prabhat said,
Wrote on March 17, 2010 @ 11:43 am
Hi ,
I want to use Webbrowser control with transparent dialog. dilaog box should transparent but webbrowser control part should not transparent.
Thanks,
codeproject.com have at least two examples shows that how to use common windows control and web browser control with layered window,
they use another window with the layered window to use both controls and semi-trans.
you may search it.
I know this is a reply to late, but maybe it would be helpful for some else who read this post.
David Feng
2010-09-13
Niny said,
Wrote on April 17, 2011 @ 9:44 am
Hello Marc.
First, thanks for your good code about using layered windows.
Second, I’m working on using layered windows in win32. I’ve used your code with a arbitary png file, and program runs correctly, but there is a problem. When It loads a png file, for alpha channel areas, program shows irregular colors!
I’ve googled and found a tutorial that has a circle.png file. And when compile with your code, it runs correctly! Maybe there is two kind of png or, something is tricky!
I’ve search some days and have seen every tutorial and codes about layering a window with png file, even bmp. Some of them explain how we can load a png file to resource, some other load a png to a stream, and some loading a bmp file from scratch.
At last, when we used bmp file with alpha channel (adding by photoshop) it works correctly, But you know after adding an alpha channel to bmps, we cannot have some effects like window shadow.
Could you please, help me! Why the code does not show arbitary png file correctly? and what I should do?
Good Luck.
Marc Gregoire said,
Wrote on April 17, 2011 @ 11:33 am
How are you creating your PNG files?
Are you sure the alpha channel you create is correct?
Send me one of your PNG files.
Niny said,
Wrote on April 18, 2011 @ 7:37 am
Dear Marc.
The files is sent to your mail at nounsoft.com .
Thanks to your attention.
Asight said,
Wrote on August 1, 2011 @ 4:25 pm
Hi
I met a big problem.
I used this api to make a window that only display text with transparent background, the invoke was succesful,but my dialog shown nothing ,i fist used gdi+ to draw string,and then updateLayeredWindow,everything is transparent and i cant recieve WM_APINT anymore. O__O!
Asight said,
Wrote on August 2, 2011 @ 3:18 am
HI Marc:
I solved my problem, thank you for your blog article
Marc Gregoire said,
Wrote on August 2, 2011 @ 7:14 am
Could you post your solution, so it might help others with the same problem?
adam said,
Wrote on December 10, 2012 @ 10:11 am
Hi Marc.
problem: I want to load a png file from resource section of a win32 project.
experience: I’ve googled about it, but there were to type of answers:
1-LoadFromResource member function of CImage, that does not work! like following example:
img.LoadFromResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_PNG)); // I’ve checked IDB_PNG as BITMAP and RCDATA type of resource. //
2-Using an extra library like pnglib, that need extra work and so complicated as a new library!
now marc, If you have any way to do this, please show me a working example.
thanks again.
Marc Gregoire said,
Wrote on December 10, 2012 @ 7:01 pm
Take a look at the class in the following CodeProject article:
http://www.codeproject.com/Articles/3537/Loading-JPG-PNG-resources-using-GDI
adam said,
Wrote on December 11, 2012 @ 11:00 am
Thanks to your attention.
Using article code, first I used stream and then loaded resource with “img.Load(IStream* pStream);” member function.