Applying Visual Effects to the Desktop'�Shoot

Environment: VC6 SP4

Introduction

This article discusses how an application can apply visual effects to the Desktop, by copying Desktop contents, applying effects on it using GDI functions, and then re-displaying it. Additionally, this application also demonstrates how to play WAV files using Win32 API.

Shoot comes in handy when you are frustrated with your computer and would like to literally shoot the brains out of it. This application, when run, converts your mouse pointer to a gun's target finder and wherever you click, it makes a gun shot sound and burns a hole through the Desktop. To close the application, just press the Escape key.

Background

Like all other windows, the Desktop window also has a device context associated with it. The Win32 API GetDCEx(...) can be used to get a handle to this Desktop device context. By using this handle, you can copy the Desktop window contents to some device context of your application. Then, by using any combination of GDI operations, various visual effects can be applied to it.

Using the Code

We start copying the Desktop window in the constructor of the dialog class because we need to do this before the window for this application comes up. We first get a handle to the Desktop device context and then convert it to a pointer to a CDC object. We also get the screen resolution.

CDC *pDesktopDC = CDC::FromHandle (::GetDCEx(NULL, NULL, 0));
int screenMaxX = GetSystemMetrics(SM_CXSCREEN);
int screenMaxY = GetSystemMetrics(SM_CYSCREEN);

Then, we create a device context in memory that is compatible with the Desktop device context.

m_pProcDC = new CDC;
m_pProcDC->CreateCompatibleDC (pDesktopDC);

When a memory device context is created, a 1x1 pixel-sized bitmap is selected to it and hence GDI operations on it do not produce the required effect. We circumvent this by creating a bitmap of the same dimension as the Desktop and selecting it to the memory device context.

m_pBMP = new CBitmap;
m_pBMP->CreateCompatibleBitmap (pDesktopDC, screenMaxX,
                                screenMaxY);
m_pProcDC->SelectObject (m_pBMP);

The memory device context is now ready for use and we can copy the contents of the Desktop device context to it.

m_pProcDC->BitBlt(0, 0, screenMaxX, screenMaxY, pDesktopDC,
                  0, 0, SRCCOPY);

Once this is done, you can apply any visual effect to the memory device context and then redisplay it.

However, in this application we will not apply the visual effect right now. We need to create a bullet mark on the screen when the user clicks. For that, we use a bitmap resource named IDB_SHOTMARK, which is like a gunshot mark. To use this bitmap, we load it and select it to another device context created in memory.

m_pShotDC = new CDC;
m_pShotDC->CreateCompatibleDC(pDesktopDC);

m_pShotBmp = new CBitmap;
m_pShotBmp->LoadBitmap ( IDB_SHOTMARK );

m_pShotDC->SelectObject ( m_pShotBmp );

When we are done with copying the Desktop contents and loading bitmaps, we are ready to display them.

In the OnInitDialog, we make the dialog cover the whole Desktop, by giving it the size of the Desktop and making it stay always on top by using a call to SetWindowPos.

::SetWindowPos( this->GetSafeHwnd(), HWND_TOPMOST, 0, 0,
                 GetSystemMetrics(SM_CXSCREEN),
                 GetSystemMetrics(SM_CYSCREEN),
                 SWP_SHOWWINDOW);

We also keep the gun's view finder cursor, which is another resource, ready, by loading it.

HINSTANCE hInstResource = AfxFindResourceHandle
                          (MAKEINTRESOURCE(IDC_TF),
                           RT_GROUP_CURSOR);
m_hCursor = ::LoadCursor(hInstResource, MAKEINTRESOURCE(IDC_TF));

In the OnPaint handler, we display the Desktop window by copying it from the device context in memory where we had stored it previously to the dialog's device context.

CDC *pDC = GetDC();
pDC->BitBlt (0, 0, screenMaxX, screenMaxY, m_pProcDC,
             0, 0, SRCCOPY );
ReleaseDC(pDC);

The only thing that is left is to show the gunshot mark and make the sound when the user clicks. For this, we handle the message WM_LBUTTONDOWN where we copy the contents of the gunshot bitmap loaded in the m_pShotDC device context to the point where the user clicked. We also play the WAV file by using the PlaySound function. To use this function, you need to link the VC98\Lib\WINMM.LIB with your application and include the mmsystem.h header file in your application.

void CShootDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
  ...
  //  Show gunshot mark
  CDC *pDC = GetDC();
  pDC->BitBlt (point.x - 10, point.y - 10, 48, 48, m_pShotDC,
               0, 0, SRCAND);
  ReleaseDC(pDC);
  ...

  //  Play gunshot sound
  ::PlaySound((LPCTSTR)soundFile, NULL,
              SND_FILENAME | SND_ASYNC | SND_NODEFAULT |
              SND_PURGE);
  ...

}

Points of Interest

The project assumes that the winmm.lib is available as ..\..\VC98\Lib\WINMM.LIB. So, you need to extract the shoot sources in the MyProjects folder or change the relative path before building the application.

The application assumes that the gunshot.wav file is present in the same folder as the executable. If it does not find the WAV file, the gunshot sound will not be made.

Downloads

Download demo executable - 71 Kb
Download source - 77 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

  • Клиника Илая - инновационный медицинский центр

    Posted by HeepsyMed on 04/22/2013 12:42am

    http://www.kava-time.com.ua/kiev/klinika-ilaya-innovatsionniy-meditsinskiy-tsentr.html Новейшие методики лечения ilaya - упрощение и удешевление сложных операций Ультрасовременный эндоскоп PENTAX (Япония) экспертного класса имеет уникальную возможность ранней диагностики новообразований желудочно-кишечного тракта с помощью программы «i-scan» (виртуальная хромоэндоскопии) без введения контрастного вещества (1-й обстановка в СНГ). Трескать возможность одновременного с диагностикой выполнения эндоскопических операций. Диагностика и лечение почечно-каменной болезни биполярным резектоскопом Richard Wolf (Германия) и лазерной установкой Lumenis (США) позволяет фрагментировать гранит с всякий локализации (почка, мочеточник, мочевой пузырь и мочеиспускательный канал) и восстановить уродинамику после нераздельно визит. В ilaya возможно действие эндоскопических операций сообразно лечению доброкачественной гиперплазии предстательной железы (аденома), включая ТУРП (Трансуретральная резекция простаты) и лазерную энуклеацию простаты с помощью Lumenis (США). Мы перевели тяжелые хирургические операции в величина «Хирургии одного дня».

    Reply
  • just what i needed

    Posted by garyofcourse on 06/24/2008 09:47am

    Abhinaba, thanks a ton for writing this article. Im new to windows programming and I spent the whole day asking people on the msdn, codeproject, and codeguru forums on how to draw stuff on the desktop till someone gave me a link to this article. Been a great help, gonna go try your code. Thanks again.

    Reply
  • Fabulous job Mr.Abhinaba Basu

    Posted by vemireddy587 on 03/18/2007 05:57am

    i am very glad to see programmers like you people
    just bringing simple things in real life to experimenting on system

    Reply
  • Applying visual effects to the desktop - shoot

    Posted by Legacy on 02/04/2004 12:00am

    Originally posted by: Michael

    Thanks for the article. In your article regarding the PlaySound API, you mentioned to include mmsystem.h in the project and "To use this function, you need to link the VC98\Lib\WINMM.LIB with your application". Please tell me how to do this in VC++ 6.0? Thanks.

    Michael

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

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • QA teams don't have time to test everything yet they can't afford to ship buggy code. Learn how Coverity can help organizations shrink their testing cycles and reduce regression risk by focusing their manual and automated testing based on the impact of change.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds