Click here to Skip to main content
15,890,579 members
Articles / Desktop Programming / MFC
Article

Tracking The Mouse In A View

Rate me:
Please Sign up or sign in to vote.
3.30/5 (22 votes)
7 May 2001CPOL 105.2K   2.1K   37   9
Track a mouse click, even in a scrolled view

Introduction

Recently, I had a project that required the user to be able to click on the screen (in the client window) and get info about the item he clicked on. This also had to work if the client window had been scrolled. While not a tough programming problem, I had to spend a couple of hours on the MSDN CD trying to get things sorted out in my already full brain. To help others who don't have the MSDN CDs (or the time to spend weeding through the MSDN CDs), I'm publishing some sample code here.

The sample program is a SDI application created in VC6 using AppWizard. No functionality was added to the program other than the drawing and mouse tracking that I wish to demonstrate.

Demonstrated techniques:

  • Tracking the mouse cursor in a view
  • Updating main status bar from a view
  • Changing the current cursor
  • Converting a point to values relative to various points on the screen
  • Clickable regions in a scrolled window

How It Works

The actual drawing of the items on the screen is pretty much a trivial issue, so I won't go over actual mechanics of the drawing itself. The sample draws six groups of six items which include a group header, and a label and a horizontal bar for each group sub-item. These bars represent a fictional percentage value used solely for the purpose of making the output resemble something slightly useful.

As each item is drawn, I save the label and the bounding rectangle coordinates for that item into a CTypedPtrArray. Once the screen is drawn, the real fun starts.

Tracking The Mouse

The program tracks and displays the mouse's current position in the status bar. Three values are displayed - the actual client window position (as calculated form the top/left corner of the client window), the desktop position (relative to the top/left corner of the windows desktop), and finally, the logical client window position (relative to the scrolled top/left corner of the client window). This last position is the one we use for the rest of the program.

When the user left-clicks in the client window, the program cycles through all of the saved regions in the CTypedPtrArray, and if the point is contained within the previously saved rectangle coordinates, the program displays a message box, telling the user which area he clicked on.

As an added bonus, the cursor changes to a cross whenever it is positioned within a "clickable" area,

License

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


Written By
Software Developer (Senior) Paddedwall Software
United States United States
I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Comments and Discussions

 
Praisethis is a great post Pin
Southmountain6-Jan-21 6:58
Southmountain6-Jan-21 6:58 
QuestionHow to detect mouse-click event? Pin
1-Feb-02 9:18
suss1-Feb-02 9:18 
Generalflicker Pin
30-Aug-01 6:10
suss30-Aug-01 6:10 
GeneralRe: flicker Pin
Darren Schroeder12-Oct-01 8:39
Darren Schroeder12-Oct-01 8:39 
GeneralRe: flicker Pin
#realJSOP20-Oct-01 5:08
mve#realJSOP20-Oct-01 5:08 
GeneralRe: flicker, caused by not handling WM_SETCURSOR Pin
Roger Allen5-Nov-01 5:34
Roger Allen5-Nov-01 5:34 
GeneralRe: flicker, caused by not handling WM_SETCURSOR Pin
Anonymous19-Nov-04 0:36
Anonymous19-Nov-04 0:36 
I've also noticed a flicker when changing from the default cursor (which I left as whatever the default is), to a custom cursor IDC_CURSOR_1 which has is 32x32 in 16 colours.
However, if I replace the default cursor with another custom built cursor of the same type, changing from that new default to IDC_CURSOR_1 doesn't flicker anymore.
Does this indicate that changing cursor type/device flickers?

To change the default cursor, in your own CScrollView::Oncreate, add this:

SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)m_Cursor_1);

I declared m_Cursor_1 as a static HCURSOR private member of the view, and load it with something like this when I initialise my resources:
m_Cursor_1= ::LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSOR_1));

(IDC_CURSOR_1 is the id in the resource editor).

Then I don't call SetCursor from OnMouseMove, I only set a member variable there (m_bTest in my example below). I handle the cursors in OnSetCursor (WM_SETCURSOR Message) as described elsewhere in this thread.

BOOL CMyView::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
HCURSOR hCursor;
if(m_bTest)
{
::SetCursor(m_Cursor_1);
return TRUE;
}
else
return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}

Forgot to say that is you're doing drag&drop, you're probably doing a SetCapture() and when you finish you call StopCapture. Using SetCapture() means that WM_SETCURSOR is not sent anymore.

TYS.
GeneralWarning Pin
#realJSOP24-Jan-01 5:18
mve#realJSOP24-Jan-01 5:18 
GeneralRe: Warning Pin
pist1-Nov-04 2:48
pist1-Nov-04 2:48 

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.