Click here to Skip to main content
15,884,388 members
Articles / Desktop Programming / MFC
Article

Transparent windows under W2K or WXP

Rate me:
Please Sign up or sign in to vote.
4.25/5 (9 votes)
27 Apr 20013 min read 134.6K   3.6K   31   19
Transparency for standard controls.

screenshot - pellucid.gif

Note: this would run only under Windows 2000 and the successors.

Introduction

Well - some time ago I wrote a few lines of code which came out to be a hit to some companies. This happened nearly 10 years ago. Those people were used to rent a software - so I finally gave in :)

Nowadays nearly everything is going to get not cheaper - I thought this would be the right time to give my old settled customers the opportunity to pay back my patience. I changed nearly every bit of code I knew working well to some code I expect to do the same ;) I didn't touch a piece of code on which I forgot the usage, so it wasn't much to do!

Multithreading, Inter Process Communication, Kernel Mode Execution, Native API-Support - hmmm, this you can talk to a sales engineer for centuries, he would keep on looking the same cool inter-face which means - he doesn't know what's going on but he has the key to the safe.

Time to posh up my UI ( Unique Identity - also known as User Interface )

My program is used by officials in charge - means: busy, critical on every change that doesn't make them do their job better.

They do need some information temporary but also need to view what they have in front with no change. This sounds like a popup window is needed and indeed this is what I have done there. The general feedback was: Yes we need what you show in your popup, and thanks, really nice but: We also need to see the things underneath the popup so we always don't have to move your information popup window around on the screen. Not so nice.

Pellucid was born. A popup-window showing the additional information in a flexible way by letting view the covered section of the original window. Reducing the amount of window-moves while looking cool.

This code does not work on machines with OS-versions lower than W2K because of the usage of window style WS_EX_LAYERED.

The classes

There are 3 classes doing the whole work:

PellucidChild is derived from CWnd and functions as a shell for the original control. It replaces the control's window procedure with its own. The reason for this was the requirement for the control being dragged by mouse as you do this on main windows by dragging the caption bar.

PellucidSelf is derived from CFrameWnd because this gives the opportunity of being placed anywhere on the screen. PellucidSelf becomes the parent of PellucidChild

Pellucid is the shell setting up all required connections between the original control, PellucidSelf and PellucidChild. It also makes the transparency by calling the appropriate functions in Pellucid::CreateSelf().

Usage

  1. Include the header Pellucid.h where you want the transparent windows to be shown e.g.: MainFrm.h or any CDialog-derived window or ...
  2. Add member variables of type Pellucid
  3. Add member variables of type of control you want to be shown e.g. CEdit, CTreeCtrl ...
  4. Create the control by using the appropriate Create functions
  5. Create Pellucid
  6. If you want to process the notification messages send by the controls then you have to insert message handler for WM_COMMAND and WM_NOTIFY messages
  7. If you are done with Pellucid - the destructor will do the job or just call Pellucid::Destroy()

Sample for 1,2,3

///////////////////////////////////////////////////////////
// >> demo extension
//
#include "Pellucid.h"
///////////////////////////////////////////////////////////
// << demo extension
//
#include "ChildView.h"
class CMainFrame : public CFrameWnd
{
public:
    CMainFrame();
protected:
    DECLARE_DYNAMIC(CMainFrame)
// Attributes
public:
///////////////////////////////////////////////////////////
// >> demo extension
//
    Pellucid m_pellucid1;
    Pellucid m_pellucid2;
    Pellucid m_pellucid3;
    Pellucid m_pellucid4;
    Pellucid m_pellucid5;
    Pellucid m_pellucid6;
    CListBox m_listbox;
    CEdit m_edit;
    CTreeCtrl m_tree;
    CButton m_button;
    CButton m_button2;
    CButton m_checkbox;
///////////////////////////////////////////////////////////
// << demo extension
//

Sample for 4,5

///////////////////////////////////////////////////////////
// << demo extension
//
void CMainFrame::OnShow()
{
///////////////////////////////////////////////////////////
// >> demo extension
//
    int id = 42;
    m_listbox.Create (WS_CHILD | WS_VSCROLL | LBS_NOTIFY, 
                                    CRect(0,0,0,0),this,id);
    int i;
    // add some fake data to the listbox
    for(i = 0; i < 100; i ++) {
        CString s;
        s.Format (TEXT("listboxitem %d"),i+1);
        m_listbox.AddString (s);
    }
    CRect rw; // parent rectangle
    GetWindowRect(rw);
    CRect rp; // pellucid rectangle
    rp.SetRect (rw.left + 20,rw.top + 70,rw.left + 220,rw.top + 250);
    // m_pellucid1 is a container for m_listbox
    // note: the rectangle for the container is in screen coordinates,
    // the child rectangle is in client coordinates regarding to the
    // container
    m_pellucid1.Create (
        this,         // parent
        rp,         // position and size in screen coordinates
        &m_listbox,     // childwindow to capture
                // position and size of child
        CRect(15,15,rp.Width() - 15,rp.Height () - 15)
    );
    ///////////////////////////////////////////////////////
    //
    // Next pellucid plz - an edit control capture by pellucid2
    //
    id ++;
    m_edit.Create (WS_CHILD | ES_WANTRETURN | ES_MULTILINE, 
                                   CRect(0,0,0,0),this,id);
    m_edit.SetWindowText (TEXT("this editcontrol\r\nis made for you"));
    // m_pellucid2 is a container for m_edit
    rp.OffsetRect (rp.Width () + 10,0);
    rp.bottom = rp.top + 400;
    m_pellucid2.Create (
        this,           // parent
        rp,             // position and size in screen coordinates
        &m_edit,        // childwindow to capture
        CRect(15,15,185,375),     // position and size of child
        CSize(0,0),     // rounded corners ?
        RGB(0,128,128), // backgroundcolor of parent of childwindow
        170,            // how many steps to get visible
        170,            // how many steps to hide
        170,            // ( 0 == invisible .... 255 = opaque )
        true,           // special effect when mouse is over
        220);           // nearly opaque while mouse is over

...

Sample for 6

//////////////////////////////////////////////////////
// >> demo extension
//
BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam)
{
            // ancient controls will yell on this message
            int lw = LOWORD(wParam);
            int hw = HIWORD(wParam);
            int sel;
            TCHAR s[100];
            CString s2;
            //
            // note : this is hardcoded - replace it with your
            // own smart encoding-algorithm for identifiers
            //
            if(lw == 42) {
                // this is our listbox thing
                switch(hw) {
                case LBN_SELCHANGE:
                    sel = ::SendMessage ((HWND) lParam,LB_GETCURSEL,0,0);
                    ::SendMessage((HWND)lParam,
                        LB_GETTEXT,sel,(LONG)(LPSTR)s);
                    SetWindowText(s);                            
                    break;
                case LBN_DBLCLK:
                    sel = ::SendMessage ((HWND) lParam,LB_GETCURSEL,0,0);
                    ::SendMessage((HWND)lParam,
                        LB_GETTEXT,sel,(LONG)(LPSTR)s);
                    s2 = s;
                    s2 +=  " double clicked";
                    SetWindowText(s2); 
                    break;
                }
            }

...


BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
            // some controls feel special so they yell on this ....
            NMHDR *pnmhdr;
            pnmhdr = (NMHDR*)lParam;
            CString s;
            bool treeee = false;
            if(wParam == 44) {
               switch(pnmhdr->code) {
               case NM_CLICK:
                  s = " treecntrl click";
                  treeee = true;
                  break;
               case NM_DBLCLK:
                  s = " treecntrl dblclk";
                  treeee = true;
                  break;
                        }
               if(treeee)
                  // this is our tree thing
                  SetWindowText(s);
            }
           
            return CFrameWnd::OnNotify(wParam, lParam, pResult);
}

Sample for 7

void CMainFrame::OnPellucidDestroy()
{
   m_pellucid1.Destroy();
   m_pellucid2.Destroy ();
}

License

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


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralAdding string to a listbox Pin
GoranPrpic4-Nov-06 16:23
GoranPrpic4-Nov-06 16:23 
Generallike vista Pin
TheCardinal22-May-06 16:13
TheCardinal22-May-06 16:13 
GeneralNice piece of Coding... Pin
mjpetersonsc4-Aug-03 15:22
mjpetersonsc4-Aug-03 15:22 
Questionwhat about the pellucid act like a child of the main window? Pin
skygg9-Jun-03 15:28
skygg9-Jun-03 15:28 
GeneralNeed controls' position all in dialog and process all their notification messages, Pin
skygg9-Jun-03 3:26
skygg9-Jun-03 3:26 
Generalbackward compatible Pin
bluntagain19-Apr-02 7:47
bluntagain19-Apr-02 7:47 
Generalno move Pin
30-Jan-02 12:42
suss30-Jan-02 12:42 
GeneralObject position Pin
30-Jan-02 6:26
suss30-Jan-02 6:26 
Generalmissing functions - missing constants Pin
29-Jan-02 9:44
suss29-Jan-02 9:44 
GeneralGuido's question Pin
29-Jan-02 9:28
suss29-Jan-02 9:28 
GeneralSet Text after pellucid is created. Pin
29-Jan-02 8:21
suss29-Jan-02 8:21 
GeneralOn our 2K platform = OPAQUE Pin
Michel Yossef David15-Dec-01 22:39
Michel Yossef David15-Dec-01 22:39 
GeneralRe: On our 2K platform = OPAQUE Pin
2-Mar-02 11:43
suss2-Mar-02 11:43 
GeneralRe: On our 2K platform = OPAQUE Pin
Mandalay22-Jul-02 22:44
Mandalay22-Jul-02 22:44 
right .. some progs uses only 16bit depth .. but some - i'doesn't meter. it's depends how your are making this window tranparent ...(layered).

----------------------------
my eng is bad, so am i .. (:
GeneralDon't compile Pin
16-Sep-01 18:50
suss16-Sep-01 18:50 
GeneralRe: Don't compile Pin
Christian Graus16-Sep-01 19:02
protectorChristian Graus16-Sep-01 19:02 
GeneralIt's so cool, but the compile is failed Pin
zhangyuwu20-Jul-01 22:31
zhangyuwu20-Jul-01 22:31 
GeneralInstall the latest Platform SDK Pin
Uwe Keim6-Sep-01 5:51
sitebuilderUwe Keim6-Sep-01 5:51 
GeneralIf you don't wanna install Platform SDK, get these files Pin
npcomple13-Jan-03 23:20
npcomple13-Jan-03 23:20 

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

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