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

Cool, Semi-transparent and Shaped Dialogs with Standard Controls for Windows 2000 and Above

By , 28 Sep 2012
 
Prize winner in Competition "Best C++/MFC article of March 2009"

Introduction

First, let me show you some screenshots captured from the demo program.

SemiTranDlgWithCtrls/8.jpg

SemiTranDlgWithCtrls/3.jpg

The program demonstrates semi-transparent dialogs which are compatible with Windows 2000 and higher.

Background

Layered windows, supported from Windows NT 5.0, provide a way to create windows that have a complex shape with alpha blending effects. The major challenge is how to show standard controls on layered windows.

The following shows the mechanism:

SemiTranDlgWithCtrls/4.jpg

When the dialog is being created, a fake window is created by CreateWindowEx with the styles WS_EX_LAYERED, WS_EX_TRANSPARENT, and WS_EX_NOACTIVATE. The alpha value of the real window will be modified to 5 by SetLayeredWindowAttributes so that the real window is almost transparent.

The real window is in charge of processing user input events and Windows messages; the fake one is in charge of the presentation. The fake window is always kept the same size / position as the real one.

How do we show standard controls on the fake window? When the presentation needs to be refreshed, the background image is painted first. Then, all the 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.

When should we refresh the presentation? We need to refresh the fake window when there is an update on the UI. In the demo, it hooks into all the child controls recursively, and changes the WNDPROC address by SetWindowLongPtr with the parameter GWLP_WNDPROC.

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

Using the Code in Native C++ / MFC

First Step

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

Second Step

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.

Final Step

Replace the dialog base class from CDialog to CImgDialogBase.

// Load from disk file
CDemo2Dlg::CDemo2Dlg(CWnd* pParent /*=NULL*/)
    : CImgDialogBase( CDemo2Dlg::IDD
    , CUtility::GetModulePath() + _T("background.png")
    , pParent
    )
{

}

// Or load from resource
CDemo3Dlg::CDemo3Dlg(CWnd* pParent /*=NULL*/)
    : CImgDialogBase(CDemo3Dlg::IDD
    , IDB_PNG_DLG2
    , _T("PNG")
    , AfxGetResourceHandle()
    , pParent
    )
{

}

Using the Code in WinForms/.NET

First Step

Copy files in the /Src/*.* directory to your project.

Second Step

You need an image file to be the dialog background. You'd better choose PNG or TIFF which support alpha channel.

Final Step

Replace the dialog base class from Form to ImageDlgBase.

public partial class Form2 : CoolImageDlg.ImageDlgBase
{
    public Form2()
    {
        base.DlgBgImg = ImgDlgSample.Properties.Resources.DemoDlgBg2;
        //......
    }
}

Something Important

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.

Some of the controls cannot work with WM_PRINT; in that case, the control won't display correctly. In other words, not all controls are supported.

The sample code uses the GDI+ helper class from Zoltan Csizmadia. For those who do not want to use GDIPlus.dll, CxImage is another choice.

Most of the machines use 96 DPI as their monitor setting. For those machines which use an unusual DPI setting, please note the demo is not meant for such settings and the child controls will be misplaced. You need to add your own code to re-layout the child controls if you do need to support unusual DPIs.

License

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

About the Author

Jerry.Wang
Team Leader
China China
Member
Jerry is from China. He was captivated by computer programming since 13 years old when first time played with Q-Basic.
 

  • Windows / Linux & C++
  • iOS & Obj-C
  • .Net & C#
  • Flex/Flash & ActionScript
  • PHP / HTML / CSS / Javascript
  • Gaming Server programming / video, audio processing / image & graphics
 
Contact: 32775973(at)qq.com
Chinese Blog: http://blog.csdn.net/wangjia184

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

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberfredatcodeproject28 Apr '13 - 3:43 
pretty cool
Questionwhat if we need to add a fade in and fade out option ?memberFiras Kudsy14 Jul '12 - 19:50 
how about adding fade in and fade out ?
QuestionHello! I have a question to ask 【你好 我有个问题想问 】 [modified]memberMember 84836733 Apr '12 - 20:17 
good

modified 5 Apr '12 - 6:05.

QuestionHow to show Transparent Static Controlmemberreplyam30 Aug '11 - 0:19 
Hi Jerry, I would like to know how to show transparent static control. Even after handling below code inside CImgDialogBase::CtrlWndProc it shows the text with black rectangle. Thanks in advance, waiting for reply
case WM_PAINT:
case WM_CAPTURECHANGED:
    //case WM_NCPAINT:
    //case WM_CTLCOLOR:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORBTN:
//case WM_CTLCOLORSTATIC:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORDLG:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORSCROLLBAR:
    {
        iter->second.pImgDlg->Refresh();
        break;
    }
 
case WM_CTLCOLORSTATIC:
    {
        HWND pWnd = ::GetDlgItem(hWnd, IDC_STATIC_MYLABEL);
        if ( ((HWND)lParam) == pWnd )
        {
            SetBkMode((HDC)wParam,TRANSPARENT);
            SetTextColor((HDC)wParam, RGB(255,255,255));
            return (BOOL)GetStockObject( NULL_BRUSH );
        }
    }
    break;

GeneralMy vote of 5memberlimitswen23 Aug '11 - 20:14 
cool,well done!
GeneralMy vote of 5memberNowBie27 Jul '11 - 6:05 
Great input. thank you
GeneralMy vote of 5memberJamming117 Jun '11 - 11:40 
Very nice! Job well-done
GeneralMy vote of 5memberrahulrcn30 May '11 - 1:19 
My 5....
GeneralMy vote of 5memberwild23 Mar '11 - 21:34 
i am now learning about
UI designing,and it's great for newbee
GeneralWhen I added the slider control, it would not be print on fake windowsmemberxujingyu7 Oct '10 - 18:19 
And also, I wanna know if there is the way to filter the controls.
I want to make a window to overlap the basic window made by MFC.
I wanna redraw the some of the controls on the top layer window, and leave some of controls on the basic. forbid the message sending of some of controls.
Generalgood. win7's glass to xpmemberwave82612 Aug '10 - 3:32 
你是我的偶像! Wink | ;)
GeneralGreatJobmembergyrtenudre9 Aug '10 - 2:30 
Very Cool Indeed! Thanks!
GeneralMy vote of 5memberAzadar.H17 Jul '10 - 7:00 
i was never seen that type of tutorial. Thanks...........
QuestionAdd Panel controlmemberYoni923 Jun '10 - 4:13 
Hi, I want to add a panel with Transparent background, but it still colored with the form default color (gray)...
How can I remove any color from control and still see the transparent background of your code?
This because I want make a button on the transparent part of the form...
 
Thank you!
 
P.S : I tried the BitmapToRegion code, but it not working with your forms...
Generalfake windows and real windowsmemberGlen Hadi30 Mar '10 - 16:27 
I don't understand Why did you Create the fake windows.What's the fake windows function ?Can't you help me ,thank you!
GeneralA Questionmemberzhaoxy28506 Mar '10 - 19:58 
First, I'd like to thank you for the codes. When I use your code I have met a problem that when I start the dialog it becomes very slowly. Then I found it was slower than the normal dialog even just move the window. I wonder whether there is a solution to it.Thank you very much!
GeneralTransparent controlsmemberMickael124 Feb '10 - 21:10 
Really good job !
But Is there a way to manage transparent control (CStatic for example) ?
Thanks for help !
GeneralRe: Transparent controlsmemberJerry.Wang8 Mar '10 - 16:37 
I suggest you can have a look at DirectUIHWND
GeneralWM_PAINTmemberdima_kdl7 Nov '09 - 5:22 
Hi!
 
I saw in your code:
::SendMessage( pThis->GetSafeHwnd(), WM_PAINT, 0, 0);
 
From MSDN: The WM_PAINT message is generated by the system and should not be sent by an application.
 
Use Invalidate() instead.
After change to Invalidate I see what performance is increased.
 
Thanks!
GeneralRe: WM_PAINTmemberJerry.Wang7 Nov '09 - 13:28 
That is great, thank you very much
Generalgood job,good boy!memberhuangzongwu16 Oct '09 - 1:45 
very cool project and handsome boy!
GeneralCode is slow to executememberDiamonddrake3 Sep '09 - 5:44 
Drawing using this method is very slow, makes the window slugish when used on an older machine. I mean I have 3.66ghz p4 with 4 gigs of ram and a 256mb video card, and when dragging your window its jittery.
 
a better method might be to create a layered forground window with a client area that is just a transparent whole, then trim the whole out and use it as the background of the acutual form, so you get the same look, but without all the push painting.
 
then again. That's already been done. But I bet you could make some improvements on that design if you come up with something this complicated and got it to work this well.
GeneralRe: Code is slow to executememberD.K.Wang4 Sep '09 - 23:20 
My aricle can help you, please see Perfect Semi-transparent & Shaped Dialogs with Standard, ActiveX, and Translucent Controls for Windows 2000+
GeneralAnother Good Article, goto http://www.codeproject.com/KB/dialog/PerfectTranlucentDlg.aspxmemberD.K.Wang2 Sep '09 - 4:11 
Another good article based on this one, ref to Perfect Semi-transparent & Shaped Dialogs with Standard, ActiveX, and Translucent Controls for Windows 2000+. Any controls(standard controls, ActiveX controls & translucent controls) are supported without using WM_PRINT message.
GeneralRe: Another Good Article, goto http://www.codeproject.com/KB/dialog/PerfectTranlucentDlg.aspxmemberJerry.Wang3 Nov '09 - 8:30 
Thank you for sharing. any improvement is welcome.
I designed the first solution in one of my projects about three years ago, similar to yours, more systematic.
controls derived from base and painted via owner-drawing and also supports Flash.
 
But finnaly I give up in that way since it is not a generic way.
However, very glad to know your achievement. It make people pleasantly surprised.

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.130523.1 | Last Updated 28 Sep 2012
Article Copyright 2009 by Jerry.Wang
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid