Summary of implementation of layered window transparent form

Source: Internet
Author: User


This piece of article is written before, just opened a new blog, sent to share with you.

This article is mainly about the VC in a variety of layered, transparent, irregular window implementation, basically includes GDI, GDI + can use all methods.

This article describes three ways in which the first method has two different effects, and the third method has two different implementations. GDI + is used in this article to make

Please consult your own information, this article does not conduct a detailed statement.


Method One: The form is overall transparent, support the child controls transparent, support OnPaint redraw.

This method is relatively simple, using the Win32 Api SetLayeredWindowAttributes

function, you can query MSDN for this function in two ways:

effect 1: The form is transparent, the child controls are transparent, and translucent effects can be achieved

The first step is to modify the form properties, ws_ex_layered support Transparent

LONG Lwindowstyle =:: GetWindowLong (hwnd, Gwl_exstyle) |


Set Alpha opacity

BYTE Bytealpha = 150;

Note that the last parameter is Lwa_alpha, and the second parameter is a color mask (transparent

Color useless)

SetLayeredWindowAttributes (M_hwnd, 0/*any*/, Bytealpha,

-----------------------Page 2-----------------------


Effect 2: The form is overall transparent, the child controls are opaque, the irregular form is implemented, and the area is transparent.

First you need a background bitmap, a transparent place to fill with a single color, and then

Posted on the background, the code is as follows

The first step is the same as the effect one. Modify Form Properties

:: SetWindowLong (hwnd, Gwl_exstyle, Lwindowstyle);

Set red to transparent, note that the transparent area of the mouse does not penetrate RGB (255, 0, 0)

To Transparent Color

Note that the last parameter is Lwa_colorkey, and the third parameter is not transparent

:: SetLayeredWindowAttributes (hwnd, RGB (255, 0, 0), 111/*any*/,


It is important to note that effect 1 and effect 2 can be used together, and the last parameter is changed to

Lwa_colorkey | Lwa_alpha can be. Use

SetLayeredWindowAttributes functions make irregular shapes simple, but usually

It can be difficult to deal with aliasing.

Method Two: Region clipping according to the bitmap, key function Combinergn and SetWindowRgn.

This method, like method One, requires the background bitmap to be transparent.

Place fills in a single color, the principle of this method is to traverse each pixel in the bitmap and will need to

To transparent pixel filtering, use other areas that do not need to be transparent

The Combinergn function joins to form an area and then uses the SetWindowRgn to paste

The form of a good background map is put into this area. The advantage of this method is that the skeleton can be implemented, i.e. the mouse

Penetrate transparent areas. The disadvantage is that traversing each pixel is a high time complexity for large bitmap algorithms,

Efficiency is low. The code is as follows:

voidCmeterheaddlg::setupregion (CDC &PDC, hbitmap cbitmap,colorref transcolor) {CDC MEMDC; Hbitmap poldmembmp=NULL; BITMAP bit; CRect rect; GetWindowRect (rect); CRGN Wndrgn;//created on a temporary DC that is compatible with the incoming DCMemdc.createcompatibledc (PDC);//to get the bitmap parameter, use its length and width ¨ª:: GetObjectA (M_hbkbitmap,sizeof(bit), &bit);//to select a bitmap into a temporary DCpoldmembmp=Memdc.selectbitmap (m_hbkbitmap);//Create a total form regionWndrgn.createrectrgn (0,0, Rect. Width (), Rect. Height ()); for(inty=0; Y<rect. Height () +1; y++){CRgn rgntemp;//Save Staging AreaintIX =0; Do{//equals Transparent Color skip find next non-transparent colorif(Memdc.getpixel (IX, y) = =Transcolor) {Rgntemp.createrectrgn (Ix,y,ix+1, y+1);//Merge Region, note comebinergn The last parameter is "XOR"wndrgn.combinergn (Wndrgn, Rgntemp, rgn_xor);//Delete temporary regionrgntemp.deleteobject ();} IX++;} while(IX <rect. Width () +1); IX=0;}if(poldmembmp) Memdc.selectbitmap (poldmembmp); SetWindowRgn (wndrgn,true); SetForegroundWindow (m_hwnd);DeleteDC (MEMDC);}

Method Three: Use transparent PNG maps and make transparent areas transparent.

The advantage of this method is that irregular shape maps can be implemented, the mouse can penetrate transparent areas, and the edges are non-aliased.

The method can be divided into two methods according to the implementation mode.

1, using CImage (ATL and MFC have this class, directly with the Win32 API without CImage, it would be troublesome to use the CreateFile function to load) drawing.

Why does our normal use of cimage loading PNG transparent areas always have a white background? We've got a lot of information.

Found this is actually Microsoft GDI + design problem, PNG image is ARGB, using GDI +

When loading a picture, GDI + defaults to a pre-left operation (PARGB), which is

The actual value per pixel is the result of a proportional multiplication of the alpha value, which actually

There is no pre-multiplication, in the use of transparent images of the Pixel alpha channel,

CImage inside is the call of the AlphaBlend, no pre-multiply image as a pre-multiply picture

The result of the processing is that this is equivalent to a single white background with a pre-left, so the image is always

A white background is present. So we just need the remedy, load the picture before and deal with that


if(IMAGE.GETBPP () = = +)//confirm that the 32-bit contains alpha channel for(i =0; I < image.getwidth (); i++){ for(j =0; J < Image.getheight (); J + +){byte*pbyte = (byte*) Image.getpixeladdress (i, j);pbyte[0] = pbyte[0] * pbyte[3] /255;p byte[1] = pbyte[1] * pbyte[3] /255;p byte[2] = pbyte[2] * pbyte[3] /255;}}}

The last call to the draw method in CImage is available.

2, using GDI + mapping, using Updatelayeredwindow

The function implements transparent PNG transparent areas. This function should be queried for MSDN. This method does not support sub-

The control is transparent and does not support the OnPaint redraw code as follows:

First, modify the form properties in OnInitDialog

ModifyStyleEx (0, ws_ex_layered | ws_overlapped);

The following is the mapping function, note that because OnPaint is not supported, it is necessary to redraw the manually called

Map functions, using the map to GDI +

M_pbkimage is initialized in OnInitDialog, M_pbkimage is

Gdiplus::image pointer, image::fromfile import PNG from the outside folder

If you are importing from a local resource file, you need to use a different method.

M_pbkimage = Image::fromfile (g_strrespath+_t ("main_.png"));

The following is a map function

//The function is called in OnInitDialog when it is initialized, and after it needs to be refreshed, manually//called, the method-pasted background map cannot respond to the WM_PAINT message, nor can it//the drawing method is called in the OnPaint function. voidCmainpanel::D rawalphapng () {CRect rcclient; GetClientRect (&rcclient); CCLIENTDC DC (m_hwnd); CDC Memdc;memdc.createcompatibledc (DC.M_HDC); CBitmap bmp;bmp. CreateCompatibleBitmap (DC.M_HDC, Rcclient.width (), Rcclient.height ()); Memdc.selectbitmap (BMP);//display pictures with GDI +Graphics graph (MEMDC.M_HDC); graph. DrawImage (M_pbkimage,0,0, Rcclient.width (), Rcclient.height ()); Blendfunction _blend;_blend.blendop=0; _blend.blendflags=0; _blend.alphaformat=1; _blend.sourceconstantalpha=255;SIZE sz={rcclient.width (), Rcclient.height ()};// :: Updatelayeredwindow(M_hwnd, HDC, &Ptwinpos, &sizewindow,//hdcmemory, &ptsrc, 0, &stblend, ulw_alpha);Updatelayeredwindow (m_hwnd, DC,&cpoint (0,0), &sz, MEMDC,&cpoint (0,0),0, &_blend, Ulw_alpha); BMP. DeleteObject (); graph. RELEASEHDC (MEMDC.M_HDC); ReleaseDC (DC.M_HDC);}

It is important to note that the second method of using method three does not appear jagged, but

will cause all of the sub-spaces on the interface to be transparent so that the controls we add to the interface are not

Use. I tried to create and redraw the controls on the interface using the Create method, but it didn't work. Solution

The solution to this problem is to combine the effects of method one in two . Requires two windows a (background

window), B (for placing the control). Using the method three second way to implement window A, the use of

Method A second effect creates a b,mfc in which the background can be set in the OnCtlColor function

Color is set to a single color, ATL does not have OnCtlColor, the simplest way is to

OnEraseBkgnd returns true in the Message function (the background turns white), and then the back

The view color is set to transparent (then the B-window is fully transparent, but its controls are not transparent),

Place the desired control on a to the corresponding position on B, and the b window overlaps

(because B is transparent, b controls look like on a). Move the b window while moving

Move a window. This will achieve the effect we want.

In addition to these three methods, using the TRANSPARENTBLT function in GDI can also be implemented

Transparent, this function can paste a background map with a background sticker on the form. About the

function usage is no longer covered, you can query MSDN

All of the three methods described above have been tried and are feasible. If you have any questions, please ask me


Summary of implementation of layered window transparent form

Related Article

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.