Making Any Application Transparent in Windows 2000/XP

Environment: VC6 SP4, Win 2000/Win XP

Introduction

There are many articles that demonstrate how you can use the new layering features of Windows 2000 or Windows XP to create applications that are translucent. This article adds to that and shows how you can use the same features to turn any application transparent even if you do not have sources for it.

By using this "WinTrans" application, you will be able to select any currently running application and turn it transparent by dragging and dropping the wand (icon at the top-left corner) on the title bar of that application. You can also control the transparency by using the slider. "WinTrans" has an interface very much like SPY and also demonstrates the usage of Win32 APIs to locate a window under the mouse pointer and extract details like the class associated with it, the caption of the window, and so forth.

"WinTrans" comes in handy if you want to work on a maximized window and at the same time keep a watch on some other application running in the background.

Background

In Windows 2000 and Windows XP, a new function named SetLayeredWindowAttributes has been added to User32.dll. To use this function, an application needs to set the WS_EX_LAYERED (0x00080000) bit in the window style, either while creating it or later, by using the SetWindowLong function. Once this bit is set, any application can call this function by passing a handle to a window and making either the whole window or a particular color on the window transparent. This function takes the following arguments:

  • HWND hWnd: Handle to the window
  • COLORREF col: Color to be made transparent
  • BYTE bAlpha: If this value is 0, the window becomes completely transparent; if it is 255, it becomes opaque
  • DWORD dwFlags: If this flag is 1, only the color col is made transparent. If it is 2, the whole window becomes transparent as dictated by the bAlpha value

Using the Code

We begin by defining the following member variables of the main dialog class in WinTransDlg.h:

bool m_bTracking;     //  will be true when the mouse is
                      //  being tracked
HWND m_hCurrWnd;      //  Handle to the window over which
                      //  the mouse was last present
HCURSOR m_hCursor;    //  The wand cursor

We also define a function pointer that points to the SetLayeredWindowAttributes function. This function is defined in the User32.dll.

//  Global definition
typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr,
              BYTE bAlpha, DWORD dwFlags);
lpfn g_pSetLayeredWindowAttributes;

In the OnInitDialog event handler for the dialog, we get the address of the SetLayeredWindowAttributes function and store it in g_pSetLayeredWindowAttributes. We also load the wand cursor and store the handle in m_hCursor.

BOOL CWinTransDlg::OnInitDialog()
{
    ....
    //  get the function pointer for SetLayeredWindowAttributes
    //  in User32.dll
    HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));
    g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32,
                 "SetLayeredWindowAttributes");
    if (g_pSetLayeredWindowAttributes == NULL)
        AfxMessageBox (
            "Layering is not supported in this version of Windows",
             MB_ICONEXCLAMATION);

    //  Load the wand cursor
    HINSTANCE hInstResource = AfxFindResourceHandle(
         MAKEINTRESOURCE(IDC_WAND), RT_GROUP_CURSOR);
    m_hCursor = ::LoadCursor( hInstResource,
                              MAKEINTRESOURCE(IDC_WAND) );
    ...
}

We then define handler for the WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE events. For the handler for WM_LBUTTONDOWN, we do the following:

void CWinTransDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
    ...
    SetCapture();              // make mouse move events to
                               // be directed to this window
    m_hCurrWnd = NULL;         // Currently, no window is to be
                               // made transparent
    m_bTracking = true;        // set the tracking flag
    ::SetCursor(m_hCursor);    // turn the mouse pointer into the
                               // wand cursor
    ...
}

For the mouse move event handler, the following code is used:

void CWinTransDlg::OnMouseMove(UINT nFlags, CPoint point)
{
    ...
    if (m_bTracking)
    {
        ...
        //  convert mouse coordinates to screen
        ClientToScreen(&point);
        ...
        //  get the window at the mouse coords
        m_hCurrWnd = ::WindowFromPoint(point);
        ...
        // Show details of the window like class, caption, etc.
        ...
    }
    ...
}

As long as the left mouse button is clicked anywhere inside the main dialog and is not released, the mouse pointer will change into the wand and the details of the window beneath the pointer will be displayed on the WinTrans dialog.

When the button is released, the event handler for WM_LBUTTONUP is called.

void CWinTransDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
    ...
    //  stop tracking the mouse
    ReleaseCapture();
    m_bTracking = false;

    //  If the window under the mouse is not of this application,
    //  we toggle its layer style flag and apply the alpha as set
    //  by the slider control
    if (g_pSetLayeredWindowAttributes && m_hCurrWnd != m_hWnd)
    {
        ::SetWindowLong(m_hCurrWnd, GWL_EXSTYLE,
                        GetWindowLong(m_hCurrWnd, 
                        GWL_EXSTYLE) ^ WS_EX_LAYERED);
        g_pSetLayeredWindowAttributes(m_hCurrWnd, 0,
                        (BYTE)m_slider.GetPos(), LWA_ALPHA);

        ::RedrawWindow(m_hCurrWnd, NULL, NULL,
                       RDW_ERASE | RDW_INVALIDATE | 
                       RDW_FRAME | RDW_ALLCHILDREN);
    }
    ...
}

Points of Interest

This application works correctly only when the wand is dropped on the title bar of another application or on the body of a dialog-based application. If, for example, the wand is dropped on the body of Notepad, it will not work.

To remove the transparent effect, you can simply drag-and-drop the wand again on that application. Because in OnLButtonUp we toggle the WS_EX_LAYERED bit, the transparency effect will also be toggled.

TransWand does not work on the command window.

Downloads

Download demo executable - 7 Kb
Download source - 13 Kb


About the Author

Abhinaba Basu

Abhinaba loves coding for the sheer fun of it. He started programming in 1995 with BASIC and then moved through Cobol, Pascal, Prolog, C, C++, VisualBasic and VC++. He received a Bachelor of Technology degree from University of Calcutta in 2001. Abhinaba is originally from the City of Joy, Kolkata in India, but now codes and lives in Noida close to Delhi. His hobby is coding which also happens to be his job. Besides coding he loves traveling.

Comments

  • transparency on overlay

    Posted by Chaos on 06/23/2004 01:24pm

    Works great but I want to do Tv Tuner player (DirectShow) with that effects. As far as now it doesn't work with overlayed windows. ATI MMC has this for example.

    Reply
  • Awesome

    Posted by Legacy on 12/11/2003 12:00am

    Originally posted by: meow

    very neat. Well done.

    Reply
  • Performance ...

    Posted by Legacy on 12/10/2003 12:00am

    Originally posted by: Philipp Grohs

    when i set the transperency to a complex window it flashes
    
    black and when i resize it it reacts very sluggish.
    i tried to write something like you have done sometime ago
    but there where the same problems.

    i use an AMD AthlonXP 2000+ with 512 MB RAM so it should not
    be a problem of the hardware.

    does anyone know how to solve this problem?

    Reply
  • pretty useful

    Posted by Legacy on 12/10/2003 12:00am

    Originally posted by: Joe Nellis

    You should consider packaging this as a service with the wand icon in the systray. There is an example of an icon service in the systray on this site I believe.

    This wins my simple and cool award. Great for folks who have cluttered desktops or are copying short bits of text. Also a reg hack for this so you can right click context menu the title bar and get it in the menu would be nice.

    good job.

    Reply
  • Awesome

    Posted by Legacy on 12/09/2003 12:00am

    Originally posted by: Mitesh Raj Pandey

    Great work!!! It's amazing to see through applications.

    I have one question for you.

    Can we achieve the same thing (transparancy) with Child Windows?

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • Best-in-Class organizations execute on a strategy that supports the multi-channel nature of customer requests. These leading organizations do not just open up their service infrastructures to accommodate new channels, but also empower their teams to deliver an effective and consistent experience regardless of the channel selected by the customer. This document will highlight the key business capabilities that support a Best-in-Class customer engagement strategy.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds