dcsimg
 

Transparent Window

Thursday Dec 3rd 1998 by Franz Polzer

Transparent Window

This article is based on the idea of Jason Wylie, the author of the article Transparent Dialog, but it uses a mask bitmap instead of getting the transparency information out of the bitmap. This way many funny things can be done...

Transparent Window Picture

In some cases it's nice to have a window that not always looks the same (I mean rectangular). So I created this CWnd based window class which implements a transparent window. The transparency information is supplied by a mask bitmap.

To include this transparent window type into your application copy the Transparent Window class files to your project's directory. Create an object of this class and call the CreateTransparent() method for it. The parameters are a window caption, a RECT structure an ID for the mask bitmap and annother one for the background bitmap.

So your InitInstance() function should look like this:

BOOL CDrawtestApp::InitInstance()
{
    CRect rect(0, 0, 320, 150);
    CTransparentWnd* pTWnd = new CTransparentWnd;
    m_pMainWnd = pTWnd;
    pFrame->CreateTransparent("Transparent Test", rect, IDB_MASK, IDB_BACK);
    pFrame->ShowWindow(SW_SHOW);
    pFrame->UpdateWindow();
    return TRUE;
}

The mechanism this window is working with is to set a proper window-region. This window region is setup by the function SetupRegion(). The process is to load the specified monochrome mask bitmap and to check for each pixel if it is set or not. For each set pixel add this pixel's position to the window region. This is very slow, but only done once at startup. Therefore this window is not resizeable.

The code for the SetupRegion() function:

void CTransparentWnd::SetupRegion(CDC *pDC, unsigned short MaskID)
{
    CDC              memDC;
    CBitmap         cBitmap;
    CBitmap*        pOldMemBmp = NULL;
    COLORREF        col;
    CRect            cRect;
    int              x, y;
    CRgn             m_Rgn, rgnTemp;

    GetWindowRect(&cRect);

    cBitmap.LoadBitmap(MaskID);
    memDC.CreateCompatibleDC(pDC);
    pOldMemBmp = memDC.SelectObject(&cBitmap);

    m_Rgn.CreateRectRgn(0, 0, cRect.Width(), cRect.Height());
    for(x=0; x<=cRect.Width(); x++)
    {
        for(y=0; y<=cRect.Height(); y++)
        {
            col = memDC.GetPixel(x, y);
            if(col == 0)
            {
                rgnTemp.CreateRectRgn(x, y, x+1, y+1);
                m_Rgn.CombineRgn(&m_Rgn, &rgnTemp, RGN_XOR);
                rgnTemp.DeleteObject();    
            }
        }
    }
    if (pOldMemBmp) memDC.SelectObject(pOldMemBmp);
    SetWindowRgn((HRGN)m_Rgn, TRUE);
}

The next proble is to make this window moveable. There are two possibilities. You can override the ONNcHittest() function and redirect all HTCLIENT results to HTCAPTION result, or you only override the OnLButtonDown() function and send the correct hittest result to the framework.

void CTransparentWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
    CWnd::OnLButtonDown(nFlags, point);
    PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x,point.y));
}

Now you can move the window by clicking anywere inside the window region.

Download demo project - 23 KB

Download source - 3 KB

Home
Mobile Site | Full Site
Copyright 2018 © QuinStreet Inc. All Rights Reserved