Click here to Skip to main content
12,355,505 members (71,666 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

26.8K views
1.1K downloads
25 bookmarked
Posted

MouseLight - Utility to Make Spot Light Based on Mouse Moving

, 15 Aug 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
MouseLight support for your presentation
MouseLight Sample - Click to enlarge image

Introduction

Sometimes it's difficult to tell an audience to look at a particular area of the screen. Whether it's for a product demo, presentation, screencast or a lecture. MouseLight tries to eliminate this problem.

This utility puts a "spotlight" and dims the surrounding area which enables your audience to effortlessly follow your path of movement on the screen.

Background

Our goal solves the problem that we need to know the 2 concepts given below:

  • LayeredWindow - Windows APIs support a layered window made transparent for a dialog. We will create a dialog with size equal to desktop and use this technique to blur the surrounding area.
  • Region - We can change the shape of the dialog based on Region. With this technique, we can make a spotlight with different shapes such as Round, etc.

How To Make SpotLight

First, we will create a dialog with a size equal to desktop window. We must go to the resource mode of that dialog, set properties of dialog - border = none, so this dialog will be removed in the title bar. And we will blur this dialog by making transparent with specified percent rate. So we still see different windows although our dialog is topmost, as you see the code below (also see my 2 WndShadow h/cpp files):

// We get address of function from WindowAPI
HMODULE hSysDll = LoadLibrary(_T("USER32.DLL"));
s_UpdateLayeredWindow =
    (pfnUpdateLayeredWindow)GetProcAddress(hSysDll,
    "UpdateLayeredWindow");

// If the import did not succeed, probably layered window is
// not supported by current OS
if (NULL == s_UpdateLayeredWindow)
    return false;

s_SetLayeredWindowAttributes =
    (pfnSetLayeredWindowAttributes)GetProcAddress(hSysDll,
    "SetLayeredWindowAttributes");

// After that, we call this function to make transparent to that dialog
/* Windows need to be layered to be made transparent. This is done
* by modifying the extended style bits to contain WS_EX_LAYARED. */
SetLastError(0);

SetWindowLong(hWnd,
             GWL_EXSTYLE ,
             GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);

if (GetLastError())
    return FALSE;

/* Now, we need to set the 'layered window attributes'. This
* is where the alpha values get set. */
return s_SetLayeredWindowAttributes (hWnd,
                                   RGB(255, 0, 255),
                                   factor,
                                   LWA_COLORKEY|LWA_ALPHA);

To make spotlight, we use the Region technique. Create a memory DC/Bitmap with a size equal to desktop window and draw Round, etc. at some position and then convert BitmapToRegion (you can see my 2 Region cpp/hpp files) and set Region to our dialog as below:

// Draw mem dc to make region
//m_cVideoMemDC.Rectangle(m_rcVideoWindow);
m_cVideoMemDC.FillSolidRect(m_rcVideoWindow, COLOR_WHITE);
// Draw round
m_cRoundVideoMemDC.SelectObject(&m_cBrushFocusWhite);
m_cRoundVideoMemDC.SelectObject(&m_cPenFocusWhite);
CRect cRectRound(0, 0, m_cCurrentFocusSize.cx, m_cCurrentFocusSize.cy);
//m_cRoundVideoMemDC.Rectangle(cRectRound);
m_cRoundVideoMemDC.FillSolidRect(cRectRound, COLOR_WHITE);
m_cRoundVideoMemDC.SelectObject(&m_cBrushFocusBlack);
cRectRound.DeflateRect(m_cCurrentFocusSize.cx/4, m_cCurrentFocusSize.cy/4);
m_cRoundVideoMemDC.RoundRect(cRectRound, cRectRound.CenterPoint());
m_cVideoMemDC.BitBlt(m_cCurrentFocus.left, m_cCurrentFocus.top,
                        m_cCurrentFocusSize.cx, m_cCurrentFocusSize.cy,
                        &m_cRoundVideoMemDC, 0, 0, SRCCOPY);

// Draw mem dc to update on dialog background
m_cBgMemDC.SelectObject(&m_cBrushBgWhite);
m_cBgMemDC.SelectObject(&m_cPenBgWhite);
m_cBgMemDC.Rectangle(m_rcVideoWindow);
// Draw round
m_cRoundBgMemDC.SelectObject(&m_cBrushBgWhite);
m_cRoundBgMemDC.SelectObject(&m_cPenBgWhite);
CRect cRectRound2(0, 0, m_cCurrentFocusSize.cx+SIZE_BORDER,
            m_cCurrentFocusSize.cy+SIZE_BORDER);
m_cRoundBgMemDC.Rectangle(cRectRound2);
m_cRoundBgMemDC.SelectObject(&m_cBrushBgBlack);
cRectRound2.DeflateRect(cRectRound2.Width()/4, cRectRound2.Height()/4);
m_cRoundBgMemDC.RoundRect(cRectRound2, cRectRound2.CenterPoint());
m_cBgMemDC.BitBlt(m_cCurrentFocus.left-SIZE_BORDER/2,
        m_cCurrentFocus.top-SIZE_BORDER/2,
                        m_cCurrentFocusSize.cx+SIZE_BORDER,
        m_cCurrentFocusSize.cy+SIZE_BORDER,
                        &m_cRoundBgMemDC, 0, 0, SRCCOPY);

// Make region
HRGN hRgn = BitmapToRegion(m_cVideoMemDC.m_hDC, 0, 0,
                            m_rcVideoWindow.Width(), m_rcVideoWindow.Height(),
                            RGB(0,0,0), RGB(20,20,20));
int iRes = this->SetWindowRgn(hRgn, FALSE);
DeleteObject(hRgn);

// Notify to draw
UpdateWindow();
Invalidate();

SpotLight will move to follow the mouse position changes. In my old version, I used Mouse event as left clickup/down and mousemove on Dialog to move SpotLight. Now, I wrote a DLL to monitor MouseMove action (also see SetWindowHook in MSDN).

// Install hook
InstallHook(this->m_hWnd, WM_MOUSEMOVE);

// Wait to receive msg from mouse
LRESULT CMouseLightDlg::OnMouseHook(WPARAM wParam, LPARAM lParam)
{
    if (wParam == WM_MOUSEMOVE)
    {        
        if (g_bSaved == FALSE)
        {
            GetCursorPos(&g_cSavedPoint);
            g_bSaved = TRUE;
        }
        CPoint Point;
        GetCursorPos(&Point);
        if (Point != g_cSavedPoint)
        {
            if (this->IsWindowVisible())
            {
                _tprintf(_T("MouseProc\n"));
                g_pMouseLight->UpdateSpotLight(Point);
            }
            g_cSavedPoint = Point;
        }
    }

    return S_OK;
}

We can also draw an image background on that dialog and an image around SpotLight. So it is easy for an audience to look at a particular area of the screen. (Also see another article here.)

Points of Interest

Windows APIs support SetLayeredWindowAttributes function to make a dialog transparent. So we can use this function to make our application "beautifully".

History

  • Version 1.0.0.2 
    • Use the MouseHook technique to monitor MouseMove action
  • Version 1.0.0.3
    • Allow to zoom in/out by Ctrl + MouseMove 
    • Look better

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

James Duy Trinh (VietDoor)
Software Developer (Senior)
Vietnam Vietnam
Bachelor of Natural Science University, HCMC VietNam

You may also be interested in...

Comments and Discussions

 
GeneralNeat concept! Pin
wtwhite19-Aug-08 5:06
memberwtwhite19-Aug-08 5:06 
GeneralRe: Neat concept! [modified] Pin
James Duy Trinh (VietDoor)19-Aug-08 12:51
memberJames Duy Trinh (VietDoor)19-Aug-08 12:51 
RantThe demo project contains a virus Pin
David B. Taylor18-Aug-08 3:55
memberDavid B. Taylor18-Aug-08 3:55 
GeneralRe: The demo project contains a virus Pin
James Duy Trinh18-Aug-08 5:39
memberJames Duy Trinh18-Aug-08 5:39 
GeneralRe: The demo project contains a virus Pin
.dan.g.18-Aug-08 13:55
member.dan.g.18-Aug-08 13:55 
GeneralRe: The demo project contains a virus Pin
James Duy Trinh18-Aug-08 15:49
memberJames Duy Trinh18-Aug-08 15:49 
GeneralRe: The demo project contains a virus Pin
David B. Taylor18-Aug-08 18:21
memberDavid B. Taylor18-Aug-08 18:21 
GeneralRe: The demo project contains a virus Pin
coslpumo19-Aug-08 14:10
membercoslpumo19-Aug-08 14:10 
GeneralRe: The demo project contains a virus Pin
James Duy Trinh (VietDoor)3-Jan-09 16:11
memberJames Duy Trinh (VietDoor)3-Jan-09 16:11 

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.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160621.1 | Last Updated 15 Aug 2008
Article Copyright 2008 by James Duy Trinh (VietDoor)
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid