Transparent Static Control

Introduction

There are many ways to develop a transparent static control. I like two approaches in particular, because they are simple and they get the job done. When you think about placing a static control with a transparent background on your window, you have to consider one important thing: Is the background static or dynamic? The problem of having a static control changes depending on what is displayed in the background.

Method 1

If the background is static, the best approach is to make a copy of the area on the parent window behind the static control before it is drawn for the first time, and then simply copy the image back to the parent every time the static control needs to be redrawn. The advantage of this approach is its flicker-free display every time the static control is changed.

LRESULT CTransparentStatic2::OnSetText(WPARAM wParam,LPARAM lParam)
{
   LRESULT Result = Default();
   Invalidate();
   UpdateWindow();
   return Result;
}

HBRUSH CTransparentStatic2::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
   pDC->SetBkMode(TRANSPARENT);
   return (HBRUSH)GetStockObject(NULL_BRUSH);
}

BOOL CTransparentStatic2::OnEraseBkgnd(CDC* pDC)
{
   if (m_Bmp.GetSafeHandle() == NULL)
   {
      CRect Rect;
      GetWindowRect(&Rect);
      CWnd *pParent = GetParent();
      ASSERT(pParent);
      pParent->ScreenToClient(&Rect);    //convert our co-ordinates
                                         //to our parents

      //copy what's on the parents at this point
      CDC *pDC = pParent->GetDC();
      CDC MemDC;
      MemDC.CreateCompatibleDC(pDC);
      m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());
      CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);

      MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,
                   Rect.top,SRCCOPY);

      MemDC.SelectObject(pOldBmp);

      pParent->ReleaseDC(pDC);
   }
   else    //copy what we copied off the parent the first time
           //back onto the parent
   {
      CRect Rect;
      GetClientRect(Rect);
      CDC MemDC;
      MemDC.CreateCompatibleDC(pDC);
      CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);
      pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);
      MemDC.SelectObject(pOldBmp);
   }
   return TRUE;
}

Method 2

The other approach comes in handy when the parent window's background is dynamic. If the parent windows background is constantly changing, the above approach will not look too nice. So, instead of doing all the copying, the static control should invalidate the area of the parent where the control resides every time its text is changed. This method is much simpler than the one before, but it could flicker if the text is changed at a rapid rate.

LRESULT CTransparentStatic::OnSetText(WPARAM wParam,LPARAM lParam)

{
   LRESULT Result = Default();
   CRect Rect;
   GetWindowRect(&Rect);
   GetParent()->ScreenToClient(&Rect);
   GetParent()->InvalidateRect(&Rect);
   GetParent()->UpdateWindow();
   return Result;
}

HBRUSH CTransparentStatic::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
{
   pDC->SetBkMode(TRANSPARENT);
   return (HBRUSH)GetStockObject(NULL_BRUSH);
}

Keep an eye out for a Transparent Edit control and Transparent Listbox.



About the Author

Ali Rafiee

Ali Rafiee has been developing windows applications for the past 14 years using Visual C++, and he hasn't looked back since. Ali has been a software development consultant for must of his career, but he has finally settled down and has been working for an educational software company for the past 7 years. While he is not working, he is either learning C#, flying airplanes, playing with his daughter, or answering peoples question on newsgroups, he finds that to be a great learning tool for him (He is always trying to learn something new).

Downloads

Comments

  • thanks good

    Posted by dave on 10/22/2012 07:10am

    Method 1 is fantastic method for high speed text change

    Reply
  • Fails with WS_CLIPCHILDREN

    Posted by SteveS on 08/24/2007 01:49pm

    This is good but it fails when the parent has the WS_CLIPCHILDREN style. That's something I must have in my project due to other windows that flicker when redrawn. I think having that style would be the norm since it eliminates flicker.

    • Fails with WS_CLIPCHILDREN

      Posted by AliRafiee on 08/24/2007 02:05pm

      Hi Steve,
      I know about the WS_CLIPCHILDREN problem. Unfortunately that is one of the things that break this control.
      There is a work around.  If you are using CTransparentStatic change the OnSetText method to look like this
      
      LRESULT CTransparentStatic::OnSetText(WPARAM wParam,LPARAM lParam)
      {
         LRESULT Result = Default();
         ShowWindow(SW_HIDE);
         ShowWindow(SW_SHOW);
         return Result;
      }
      
      This should eliminate the residue problem, but you might notice a flicker. Unfortunately I haven't been able to find a cleaner solution.

      Reply
    Reply
  • A good job

    Posted by zhuht on 03/22/2007 02:20am

    This is a good job! I use your technology about this now.Thanks. And How to write a transparent ActiveX static control using ATL ?

    Reply
  • Thanks

    Posted by SeninAndrew on 10/13/2005 12:18pm

    Thank you very much Ali for this article!

    • good Article!!!

      Posted by shree510 on 02/01/2010 05:39am

      This is really important article

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

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • When it comes to desktops – physical or virtual – it's all about the applications. Cloud-hosted virtual desktops are growing fast because you get local data center-class security and 24x7 access with the complete personalization and flexibility of your own desktop. Organizations make five common mistakes when it comes to planning and implementing their application management strategy. This eBook tells you what they are and how to avoid them, and offers real-life case studies on customers who didn't …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds