Click here to Skip to main content
Click here to Skip to main content

Perfect Semi-transparent & Shaped Dialogs with Standard, ActiveX, and Translucent Controls for Windows 2000+

By , 9 Feb 2010
 

Introduction 

First, let me show you some screenshots captured from the demo program. The program demonstrates semi-transparent dialogs with standard, ActiveX (like WebBrowser Control, Flash Control) and translucent controls which are compatible with Windows 2000 and higher.  

Translucent Dialog with Standard Control

Translucent Dialog with WebPage

Translucent Dialog with WebPage

Background

Jerry.Wang has given a way in his article: Cool, Semi-transparent and Shaped Dialogs with Standard Controls for Windows 2000 and Above. In short, he creates two dialogs: one (the real dialog) is in charge of processing user input events and Windows messages, the other (the fake dialog) is in charge of the presentation. The fake one is created by CreateWindowEx with the styles WS_EX_LAYERED, WS_EX_TRANSPARENT, and WS_EX_NOACTIVATE, and always kept the same size / position as the real one. The real one is almost transparent because its alpha value is modified to 5 by SetLayeredWindowAttributes.

In his article, when the presentation needs to be refreshed, the background image is painted first. All the standard child controls will be captured by sending the WM_PRINT message, and painted at the same position on the fake window. Especially, for EDIT controls, EditBox / Editable ComboBox / etc., we need to draw the caret by ourselves.

But, there are some problems:

  • The dialog is NOT a real shaped one, i.e. the hit testing is NOT based on the shape and transparency of the dialog. This means that the areas of the dialog that are color-keyed or whose alpha value is zero will NOT let the mouse messages through.
  • NOT All standard controls are supported. Some of the controls such as slider, cannot work with WM_PRINT; in that case, the controls won't display correctly.
  • The ActiveX control is NOT supported. The ActiveX control like the WebBrowser control and Flash control is used to support a wide variety of OLE functionality and can be customized to fit many software needs. It cannot work with WM_PRINT too.
  • The dialog works in a way that if there is one pixel that needs to be updated, the whole window will be refreshed. Therefore, if the dialog is very large and complex, or has a lot of child controls, it may cause performance issues.

I'm going to propose another approach which can solve the above problems. The following picture shows the mechanism:

Showing the mechanism of translucent dialog

The translucent dialog is created with the styles WS_EX_LAYERED, and WS_OVERLAPPED. When it is being created, a standard dialog is created by CreateWindowEx with the styles WS_EX_LAYERED, WS_POPUP, NO WS_BORDER, NO WS_SIZEBOX, and NO WS_DLGFRAME.

The translucent dialog is in charge of processing the translucent background and the translucent controls; the standard dialog is in charge of processing the standard controls and ActiveX controls. The standard dialog is always kept the same size / position as the translucent one.

A translucent control which supports the per-pixel alpha value must be derived from the class CTranslucentWnd. You can override the method Render to draw it. In the source code, I has provided two translucent controls: CTranslucentButton and CTranslucentProgressBar. The CTranslucentButton is used to replace the CBitmapButton, and CTranslucentProgressBar is used to replace the CProgressCtrl.

For the standard controls and Active controls, you must put them on the standard dialog. Because the standard dialog covers the translucent dialog, the translucent controls cannot process the user input. How to solve it? The solution is making the standard dialog fully transparent. The API SetLayeredWindowAttributes with the zero alpha value can help you. But all the controls on it are also fully transparent.

But how to make the standard dialog fully transparent while the controls on it are opaque? This can be done by calling SetLayeredWindowAttributes with the color-key. In the OnInitDialog of the standard dialog, the API SetLayeredWindowAttributes is called with a certain color. In the processing of the message WM_CTLCOLOR with nCtlColor == CTLCOLOR_DLG, if it returns the solid brush that has the specified color, the standard dialog is fully transparent while the controls on it are also opaque.

You can get more details by looking into the source code.

Using the Code in Native C++ / MFC

Step 1

Copy all the files in /Core/*.* to your project.

Step 2

You need an image file to be the dialog background. You'd better choose PNG or TIFF which support the alpha channel. The image file can be embedded into a resource or placed on disk, judged by yourself.

Step 3

Design your standard dialog in the Resource View. In the Properties window, set the following properties:

Border: None
Overlapped Window: False
Style: Popup 

You'd better choose a certain color (i.e. transparent color) as the color-key, and drag some standard controls or ActiveX controls to it. Replace the dialog base class from CDialog to CStandardDialog.

// Here, the transparent color is green.

CDemoStandardDlg::CDemoStandardDlg(CWnd* pParent /*=NULL*/)
    : CStandardDialog(CDemoStandardDlg::IDD, RGB(0, 255, 0), pParent)
{

}

Step 4

Design your translucent dialog in the Resource View. In the Properties window, set the following properties:

Overlapped Window: False
Style: Overlapped 

Replace the dialog base class from CDialog to CTranslucentDialog.

// Load from disk file

CDemoTranslucentDlg::CDemoTranslucentDlg(LPCTSTR lpszFile, CWnd* pParent /*=NULL*/)
	: CTranslucentDialog(CDemoTranslucentDlg::IDD, lpszFile, pParent)
{
}

// Load from resource 
CDemoTranslucentDlg::CDemoTranslucentDlg(UINT nImgID, LPCTSTR lpszType
	/*=_T("PNG")*/, HINSTANCE hResourceModule/*=NULL*/, CWnd* pParent /*=NULL*/)
	: CTranslucentDialog(CDemoTranslucentDlg::IDD, nImgID, 
	lpszType, hResourceModule, pParent)
{
}

Step 5 (optional)

If you need some translucent controls, drag some controls (like button, checkbox, progress bar) to the translucent dialog. Subclasses your translucent controls to the corresponding CTranslucentWnd class, like subclass CButton to CTranslucentButton. The following demo source is from the demo program:

// In the CDemoTranslucentDlg.h
    CTranslucentButton m_btnTest;
    CTranslucentProgressBar m_ctrlProgress;

// In the CDemoTranslucentDlg.cpp
void CDemoTranslucentDlg::DoDataExchange(CDataExchange* pDX)
{
    CTranslucentDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BUTTON1, m_btnTest);
    DDX_Control(pDX, IDC_PROGRESS, m_ctrlProgress);
}

Step 6

Override the method CreateStandardDialog and OnInitChildrenWnds of your translucent dialog class. The method CreateStandardDialog is in charge of creating the corresponding standard dialog, and the method OnInitChildrenWnds is in charge of setting the translucent controls' properties and registering them to the translucent dialog. The following demo source is from the demo program:

// In the CDemoTranslucentDlg.cpp
CStandardDialog* CDemoTranslucentDlg::CreateStandardDialog()
{
	return ::new CDemoStandardDlg(this);
}

void CDemoTranslucentDlg::OnInitChildrenWnds()
{
	LPCTSTR szImageList[TWS_BUTTON_NUM] = { _T("res\\close_normal.PNG"), 
		_T("res\\close_disable.png"), _T("res\\close_over.PNG"), 
		_T("res\\close_down.PNG"), 0};
	m_btnTest.LoadImageList(szImageList);
	RegisterTranslucentWnd(&m_btnTest);

	m_ctrlProgress.MoveWindow(400, 400, 146, 61, TRUE);
	m_ctrlProgress.SetPos(50);
	m_ctrlProgress.SetFgImage(_T("res\\progress.png"));
	RegisterTranslucentWnd(&m_ctrlProgress);
}

Something Important

The article is based on the Jerry.Wang's article, and uses his CUtility class to load image. Thank you very much, Jerry.Wang.

The source code uses the GdiPlus to draw the translucent controls, so you must setup the Gdiplus environment before using my code.

The source code only provides two kinds of translucent controls. You can extend the CTranslucentWnd to support some other controls. But in my own projects, they are enough. If you can provide some other translucent controls, please share them with me.

If some controls on the standard dialog have some pixels whose colors are the same as the transparent color of the dialog, the pixels are also fully transparent. You can make use of the feature to create some effects, like making some controls become irregular.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

D.K.Wang
Team Leader
China China
Member
D.K.Wang is working for a leading interactive entertainment media company located in Shanghai, China. Skilled in Windows C++, MFC, WTL, PHP etc. Started with professional games development since 2005, now devoted to the core functionality such as graphics rendering, physics simulation and scene management for a household game engine.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberqazxsw889822 Jan '13 - 22:00 
QuestionCan you provide a sample to show web page? thank you.memberpinchen23 Sep '12 - 21:24 
Question透明按钮是放在TranslucentDialog,而其他一些控件却放在StandardDialog,数据交互的时候很麻烦memberpangguigao27 Aug '12 - 1:11 
QuestionGOOD JOBmemberHaflBit31 Jul '12 - 22:08 
Questionwindow can't be dragged, why?memberbeyonddoor14 Jun '12 - 21:43 
GeneralMy Vote of 5membercosfrist13 Jun '12 - 2:13 
QuestionGreat article but usage of the Translucent controls in demo would have been great. [modified]memberTyfix28 Apr '12 - 4:05 
Very nice article first off vote of 5 obviously.
 
Would have been great however if the demo was using some of the Translucent controls like the button. Setting these up yourself is explained in the article but I can't get the states working on the button at all (Not capturing mouse events), it always shows only the normal state image.

modified 28 Apr '12 - 10:17.

Questionplease share google like of sample to memembermcodeproject33436 Sep '11 - 23:21 
General如何做一个镂空窗体memberunidoz1 Jun '11 - 18:01 
GeneralRe: 如何做一个镂空窗体membershenyingj@gmail.com3 Aug '11 - 23:46 
GeneralMy vote of 5memberhangh1 Apr '11 - 16:42 
QuestionDalog crashed when minimizing windows continually.memberfisker.cui25 Mar '11 - 21:26 
AnswerRe: Dalog crashed when minimizing windows continually.memberMember 273388418 Jul '12 - 5:02 
Questioncan provide the source of TranslucentDialogLib.exe in demomemberbloken9 Mar '11 - 21:45 
GeneralThis is beautiful !memberevan36910 Feb '11 - 15:41 
GeneralCompiler errors when using MFC in Static LibrarymemberNico Cuppen7 Feb '11 - 5:26 
GeneralRe: Compiler errors when using MFC in Static LibrarymemberNico Cuppen9 Feb '11 - 23:58 
GeneralTab control in the dialogmemberNico Cuppen5 Feb '11 - 5:29 
GeneralRe: Tab control in the dialogmemberNico Cuppen7 Feb '11 - 5:13 
GeneralThe button can not show the statesmembergaxlin15 Nov '10 - 18:31 
GeneralMy vote of 5membersashoalm20 Sep '10 - 23:22 
General请问membershjik20 Sep '10 - 6:35 
Question你好!hello (是中国人吧?)chinese?memberlin986665218 Sep '10 - 23:44 
QuestionA problem that bothers mememberzhaoze8726 Jul '10 - 17:22 
AnswerRe: A problem that bothers mememberD.K.Wang3 Aug '10 - 4:16 
GeneralSmall bugmemberEnrico Detoma18 Jul '10 - 23:08 
GeneralRe: Small bugmemberD.K.Wang19 Jul '10 - 3:24 
GeneralBitmap Leak in CTranslucentDialog::UpdateView()memberDynamicAdventures11 Feb '10 - 7:56 
GeneralRe: Bitmap Leak in CTranslucentDialog::UpdateView()memberD.K.Wang17 Feb '10 - 3:16 
QuestionWhat is now in the upgradememberTage Lejon9 Feb '10 - 23:04 
AnswerRe: What is now in the upgradememberD.K.Wang11 Feb '10 - 4:19 
GeneralHeap corruption loading images from resource idmemberMGDBP1 Feb '10 - 0:49 
GeneralRe: Heap corruption loading images from resource idmemberD.K.Wang3 Feb '10 - 4:11 
GeneralRe: Heap corruption loading images from resource idmemberD.K.Wang6 Feb '10 - 17:31 
GeneralRe: Heap corruption loading images from resource idmemberMGDBP7 Feb '10 - 1:00 
Questionuse this code in winforms. net 2008 c #memberagvr30 Dec '09 - 3:37 
AnswerRe: use this code in winforms. net 2008 c #memberD.K.Wang3 Feb '10 - 4:05 
GeneralVery helpful!memberstjn118 Dec '09 - 2:59 
GeneralRe: Very helpful!memberD.K.Wang21 Dec '09 - 2:07 
QuestionWhy Translucent Button's Text became transparent ?memberjjksam8 Dec '09 - 21:55 
AnswerRe: Why Translucent Button's Text became transparent ?memberjjksam8 Dec '09 - 23:13 
GeneralGreat Articlememberenvmapping24 Oct '09 - 4:31 
Generalgood jobmemberiebrowser24 Oct '09 - 4:04 
GeneralMy vote of 1memberMaheshV0221 Oct '09 - 0:58 
GeneralRe: My vote of 1memberD.K.Wang21 Oct '09 - 4:34 
GeneralRe: My vote of 1memberOctopod16 Feb '10 - 5:45 
GeneralRe: My vote of 1memberPaul Belikian4 Jan '11 - 8:16 
Generalgreat articlememberafxfish2 Oct '09 - 21:31 
GeneralCEditmemberDynamicAdventures2 Oct '09 - 10:54 
AnswerRe: CEditmemberD.K.Wang3 Oct '09 - 4:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 9 Feb 2010
Article Copyright 2009 by D.K.Wang
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid