Click here to Skip to main content
15,868,141 members
Articles / Desktop Programming / MFC
Article

Applying visual effects to the desktop - Shoot

Rate me:
Please Sign up or sign in to vote.
4.46/5 (16 votes)
31 Jul 20033 min read 125.8K   2.9K   39   18
This article discusses how an application can apply visual effects to the desktop, by copying desktop contents, applying effects on it and then re-displaying it.

Sample Image

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 hit 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. Using this handle, you can copy the desktop window contents to some device context of your application. Then 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, since 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 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 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 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.

History

  • v1.0 - This is the initial version.

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
United States United States
I just love coding. I started programming in 1995 with BASIC and then moved through Cobol, Pascal, Prolog, C, C++, VB, VC++ and now C#/.NET.

I received a Bachelor of Technology degree in Computer Science from University of Calcutta in 2001.

I worked for some time in Texas Instruments, Adobe Systems and now in Microsoft India Development Center in the Visual Studio Team Systems.

I am from the City of Joy, Kolkata in India, but now live and code Hyderabad.

Comments and Discussions

 
Generalcapturing the mouse cursor Pin
stealth kid31-Oct-04 23:54
stealth kid31-Oct-04 23:54 
Generalerror MFC42D.DLL Pin
elmic30-Aug-03 11:29
elmic30-Aug-03 11:29 
GeneralRe: error MFC42D.DLL Pin
abhinaba31-Aug-03 8:51
abhinaba31-Aug-03 8:51 
GeneralRe: error MFC42D.DLL Pin
elmic1-Sep-03 4:38
elmic1-Sep-03 4:38 
GeneralBombs out when I run it Pin
tufwheels6-Aug-03 10:12
tufwheels6-Aug-03 10:12 
When I run either the downloaded exe or the compiled src, they both bomb. I can see using debug that it's happening on the call to CreateCompatibleBitmap in CaptureDesktop(). Looks like the call above to ::GetDCEx () is failing for some reason so the handle passed to CreateCompatibleBitmap is NULL, causing an Exception. Any ideas?
GeneralRe: Bombs out when I run it Pin
abhinaba7-Aug-03 20:11
abhinaba7-Aug-03 20:11 
GeneralRe: Bombs out when I run it Pin
tufwheels23-Aug-03 9:45
tufwheels23-Aug-03 9:45 
GeneralRe: Bombs out when I run it Pin
Philippe Lhoste8-Jun-04 0:29
Philippe Lhoste8-Jun-04 0:29 
GeneralAnother Way Pin
SuperEric4-Aug-03 8:45
SuperEric4-Aug-03 8:45 
GeneralRe: Another Way Pin
abhinaba4-Aug-03 17:51
abhinaba4-Aug-03 17:51 
GeneralLinkage error. Pin
WREY2-Aug-03 21:50
WREY2-Aug-03 21:50 
GeneralRe: Linkage error. Pin
abhinaba3-Aug-03 17:09
abhinaba3-Aug-03 17:09 
GeneralIt's working now!! Thanks!! Pin
WREY3-Aug-03 20:29
WREY3-Aug-03 20:29 
QuestionHow 2 Close IT?!! Pin
SuperEric2-Aug-03 10:40
SuperEric2-Aug-03 10:40 
AnswerRe: How 2 Close IT?!! Pin
Johann Gerell2-Aug-03 10:50
Johann Gerell2-Aug-03 10:50 
GeneralRe: How 2 Close IT?!! Pin
SuperEric2-Aug-03 19:41
SuperEric2-Aug-03 19:41 
AnswerRe: How 2 Close IT?!! Pin
abhinaba3-Aug-03 16:58
abhinaba3-Aug-03 16:58 
GeneralRe: How 2 Close IT?!! Pin
SuperEric4-Aug-03 8:32
SuperEric4-Aug-03 8:32 

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.