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

Transparent desktop icons

, 29 Dec 2004
Rate this:
Please Sign up or sign in to vote.
A brief discussion on what is involved in making the text background of the desktop icons transparent.


Several years ago, I downloaded a program called TransparentW that would make the text background of the desktop icons transparent. It was cool and made the desktop a whole lot prettier. What struck my fancy was the author's (Jay Guerette) comment about similar utilities asking for money considering how much time and code was involved.

I've used this utility on nearly all of the machines I've worked on and have never given it a second thought. Until today, that is. Curiosity got the best of me and I wanted to know just how much, or how little in this case, code was involved in accomplishing this task. Here are the relevant pieces of code. The first thing to do is find the listview window that owns the desktop icons.

Finding the right window

There are two ways of finding the correct window. One is a bit cleaner than the other, but I'll show both just for comparison purposes.

My first thought was to use GetDesktopWindow() to find the listview window, but the handle returned was not what I expected. I could, however, use it to enumerate all child windows of the desktop, stopping when the listview window was found.

    TCHAR   szClass[128];

    GetClassName(hWnd, szClass, sizeof(szClass));
    if (lstrcmp(szClass, "SysListView32") == 0)
        return FALSE;

    return TRUE;
hWnd = GetDesktopWindow();
if (NULL != hWnd)
    EnumChildWindows(hWnd, EnumProc, 0);

It looks good, but the problem is that the desktop owns several listview windows.

    TCHAR   szClass[128];

    GetClassName(hWnd, szClass, sizeof(szClass));
    if (lstrcmp(szClass, "SysListView32") == 0)
        GetClassName(GetParent(hWnd), szClass, sizeof(szClass));
        if (lstrcmp(szClass, "SHELLDLL_DefView") == 0)
            GetClassName(GetParent(GetParent(hWnd)), szClass, 
            if (lstrcmp(szClass, "Progman") == 0)
                // we now have the window that is a child of
                // "SHELLDLL_DefView" and a grandchild of "Progman"
                return FALSE;

    return TRUE;

Notice how the calls to GetParent() could get out of hand, or extra variables would be needed. The window handle can be saved in a global variable, or in the LPARAM parameter. The latter is done via:

*((HWND *) lParam) = hWnd;

assuming that EnumChildWindows() was called with a HWND* variable as the third parameter.

A slightly more elegant solution is to make a few calls to FindWindowEx(). This looks like:

hWnd = FindWindow("Progman", NULL);
// start with FindWindow() to get the initial hWnd

if (NULL != hWnd)
    hWnd = FindWindowEx(hWnd, NULL, "SHELLDLL_DefView", NULL);
if (NULL != hWnd)
    hWnd = FindWindowEx(hWnd, NULL, "SysListView32", NULL);

If you've never used Spy++ that ships with Visual Studio, this is a very good project to cut your teeth on. When you start the utility, open the Find Window dialog and select the Desktop, with the little crosshair. Notice that the window has no caption and the class is SysListView32. Click the OK button. In the ensuing Window Properties dialog, click the Windows tab. The listview control has a parent (click the handle) belonging to the SHELLDLL_DefView class. This window, in turn, has a parent (click the handle) belonging to the Progman class and has a Program Manager caption.

Making the change

Once the correct window handle of the listview control has been obtained, the background color can be changed. A check is done on the current background color to prevent an unnecessary change.

// if the window was found, ...
if (NULL != hWnd)
    COLORREF colorBackground = 
        ListView_GetTextBkColor(hWnd); // LVM_GETTEXTBKCOLOR
    if (0xffffffff != colorBackground)
        ListView_SetTextBkColor(hWnd, 0xffffffff); // LVM_SETTEXTBKCOLOR

        // add the 'desktop' to the update region
        InvalidateRect(hWnd, NULL, TRUE);

        // paint the update regions

Now since the desktop window can be refreshed at any time (e.g., games), the background color will then be reverted back to its non-transparent state. One solution is to couple this code with a timer of some sort and re-check the background color periodically.


While this method works fine (for most folks), it is still considered a "hack", and thus a more preferred method was born. See here for details. I don't agree with their "These programs not only consume valuable memory and processing time..." statement, however. Their solution actually modifies an OS file. That's all well and good, but they claim it is against company policy to disclose which file(s) are altered. I was able to get the name of the file, however.



This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Software Developer (Senior) Pinnacle Business Systems
United States United States

The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.
HTTP 404 - File not found
Internet Information Services

Comments and Discussions

QuestionThanks for the info! - just what I needed PinmemberFred Koschara11-Jun-06 2:49 
GeneralFinding Name of Icons PinmemberBBJ_NYC12-Aug-05 15:47 
GeneralRe: Finding Name of Icons PinmemberDavidCrow13-Aug-05 16:14 
GeneralRe: Finding Name of Icons PinmemberBBJ_NYC1-Sep-05 5:15 
GeneralRe: Finding Name of Icons PinmemberDavidCrow2-Sep-05 4:29 
GeneralRe: Finding Name of Icons PinmemberRocky-DTT15-May-06 18:21 
GeneralWorks Great! PinmemberJohn Simmons / outlaw programmer4-May-05 4:02 
QuestionSource code ? Sample ? PinmemberRazr33331-Dec-04 18:56 
AnswerRe: Source code ? Sample ? PinmemberSebastian Pipping13-Aug-06 5:08 
Generalcode doesn't work in VC++ 6.0 Pinmemberdrake2828-Dec-04 15:10 
GeneralPS. Pinmemberdrake2828-Dec-04 15:27 
GeneralRe: PS. PinmemberDavidCrow28-Dec-04 16:31 
GeneralRe: PS. Pinmemberdrake2829-Dec-04 12:42 
GeneralRe: PS. PinmemberDavidCrow30-Dec-04 2:32 
GeneralRe: PS. Pinmemberdrake2830-Dec-04 3:55 
GeneralRe: PS. PinmemberDavidCrow30-Dec-04 4:58 
drake28 wrote:
Namely, because I have an MFC app that allows user to change desktop content through the IActiveDesktop interface. Without controlling also the Background "color" this can yield ugly results. But, you are right, I decided not to waste my time with this solution and continue using SetSysColors instead. For my purposes, this works fine -- but who knows, maybe in the future I implement image blending or full-screen images and might be nice to find a better solution. I think there are plenty of reasons someone may want to use something like this in an MFC app.
Based on this, you are obviously not a beginner (i.e., beginners do not know that the 'I' in IActiveDesktop stands for interface, or that 'image blending' is a concept). How is it then that you were not able to take a few example lines of code and successfully plug them into an MFC application?
drake28 wrote:
I guess we're quarreling over semantics. If you call a shell dialog app with the function or class in question plugged in a "full-blown" app then I would agree. I saw a Win32 command line app demonstrating DLL's that you entered a number on the command line and it returned it's square from a dll function. I guess that would also qualify as a "full-blown" app.
Perhaps. A program's simplicity or size does not govern whether it is "full blown" or not.
drake28 wrote:
To say here a few lines of code, now go an buy some books to figure out how to use it COMPLETELY misses the point of this project.
Did you fail to read the scope of the article? The problem was to simply show how to make the desktop icons have transparent text, nothing more. I showed just that, nothing more. The goal is for the "answer" to match the "question."
drake28 wrote:
I meant for my original remarks to be constructive criticism.
What you meant to do and what you actually did were two different things. While you did criticize, there was nothing constructive about it. Had the code actually been wrong or had I failed to solve the problem mentioned at the top of the article, your remarks would have merit.
drake28 wrote:
But look at the articles rated 4.+ and the one's rated 2.+ and what I've discussed here is the difference.
It is very naive of you to think that 2.+ articles are "bad" and that 4.+ articles are "good." Those numbers are only meaningful to the person that voted them. That's almost as silly as going to see a movie soley based on what a critic says, or patronizing an auto mechanic solely because of an experience your neighbor had.

"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow

GeneralRe: PS. Pinmemberdrake2830-Dec-04 4:17 
GeneralRe: PS. PinmemberDavidCrow30-Dec-04 4:36 
GeneralRe: PS. Pinmembertom_dx30-Dec-04 4:40 
GeneralRe: code doesn't work in VC++ 6.0 PinmemberDavidCrow28-Dec-04 16:25 
Generaltranicon.exe, terminate and stay resident PinmemberKristijan M.22-Mar-04 3:40 
GeneralIntensive ways to deal with desktop icons Pinmemberchrisy26-Nov-03 0:43 
GeneralTry to implement another thing Pinmembersotnikov18-Nov-03 21:03 
GeneralAn idea... PinmemberRavi Bhavnani18-Nov-03 12:37 
GeneralRe: An idea... Pinmemberjdunlap18-Nov-03 13:43 
GeneralRe: An idea... PinmemberDavid Pritchard2-Dec-03 9:07 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.141015.1 | Last Updated 30 Dec 2004
Article Copyright 2003 by DavidCrow
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid