Making a transparent dialog

I am trying to make a transparent dialog. I have succeeded using a bitmap mask to set the windows region to render, however I need to animate the control within the dialog, and this does not work so well with the masking method.

I have managed to make the background appear transparent by intercepting WM_ERASBKGD, however the background moves with the dialog when it is dragged.

I am assuming that what I need to do is repaint all the windows behind my dialog when it is moved. Does this sound right? And if this is the right way to go about it, how do I repaint other windows?

200 points is for if someone can tell me the method and point me in the right direction. If there is a nice full solution or example someone can give me there are more points up for grabs.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.


If you want to make a window transparent, then it is easiest to use the Windows API function to do it.  It only works on Windows 2000 or higher, but the code looks like this:

      #ifndef WS_EX_LAYERED
      #define WS_EX_LAYERED           0x00080000
      #define LWA_COLORKEY            0x00000001
      #define LWA_ALPHA               0x00000002
      #endif // ifndef WS_EX_LAYERED

      // Preparation for the function we want to import from USER32.DLL
      typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);

      BOOL MakeWindowTransparent( CWnd* pWnd, BYTE nTransLevel )
            BOOL bSuccess = FALSE;
            OSVERSIONINFO os = { sizeof(os) };
            ::GetVersionEx( &os );

            if ( VER_PLATFORM_WIN32_NT == os.dwPlatformId && os.dwMajorVersion >= 5 )
                  lpfnSetLayeredWindowAttributes pSetLayeredWindowAttributes;

                  // Here we import the function from USER32.DLL
                  HMODULE hUser32 = ::GetModuleHandle(_T("USER32.DLL"));
                  pSetLayeredWindowAttributes =
                        (lpfnSetLayeredWindowAttributes)::GetProcAddress( hUser32, "SetLayeredWindowAttributes" );

                  if ( pSetLayeredWindowAttributes )
                        pWnd->ModifyStyleEx( 0, WS_EX_LAYERED );
                        bSuccess = pSetLayeredWindowAttributes( pWnd->m_hWnd, 0, nTransLevel, LWA_ALPHA );

                  ::FreeLibrary( hUser32 );
            return bSuccess;

The "nTransLevel" value is how transparent you want the window to be.  255 = Invisible, 0 = Totally Visible.  So, to set it to be 50/50, you would do this:
     MakeWindowTransparent( wnd, 128 );

Hope That Helps,

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

That function will work on any version of Windows... It just won't set the transparency on version of Windows before 2000.


Finally, here is a link that explains everything in more detail:

OWASP: Forgery and Phishing

Learn the techniques to avoid forgery and phishing attacks and the types of attacks an application or network may face.

AndyAinscowFreelance programmer / ConsultantCommented:
Your dialog will receive a WM_MOVE message when it is being moved.  Here you need to repaint the background of your dialog.
Maybe have a flag (bool member var) that switches on/off the normal erase background handler you have customised.
Other windows should repaint themselves normally.
completecontrolAuthor Commented:
Thanks for your help. Something urgent has come up at work, so I can't work on this till later in the week. I haven't abandoned the thread though. I'll try your suggestions and see how they go. One thing I should have mentioned though - it has to work on Win98 which is why I was using the SetWindowRgn method. What I really need help on is the repainting stuff.
AndyAinscowFreelance programmer / ConsultantCommented:
The MW_MOVE and WM_ERASEBACKGROUND should apply to Win98 without any problems.
Well, that won't work under Win98, but I'm not sure of anything that will.  When you say you need to make it "transparent", do you mean you need to make it so that you can half see your window and half see what's under it, or you do just want to set a region of the dialog to be completely clear (essentially, make a window that isn't a rectangle)?

completecontrolAuthor Commented:
Sorry about not getting back here. I haven't had a chance to work on the project since I first posted. I don't know whne I will either so I am going to award the points to Dexstar for replies above and beyond the call of duty
Thank you!  Good luck with that in the future!

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.