?
Solved

Mouse notification when leaving the client area

Posted on 1997-07-21
10
Medium Priority
?
232 Views
Last Modified: 2013-11-20
How can I be notified when the mouse leaves a child view in an MDI App when no mouse buttons are down?  Is there a way that doesn't involvethe CWnd::SetCapture() method?  I am implementing a customized cursor and need to do some GDI cleanup when the mouse leaves the client window.
0
Comment
Question by:derrickh
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
10 Comments
 
LVL 8

Expert Comment

by:gelbert
ID: 1302712
Use OnMouseMove, it gives you coordinates of cursor. Based on them you can figure out where you are.
0
 

Author Comment

by:derrickh
ID: 1302713
I AM using the OnMouseMove() notification for processing inside  of the client area.  My view does not receive notification of mouse messages when it is outside of the client area. I am trying to determine when the mouse leaves the client area.  There is a nice function (I forget the name) that does notify the view when the mouse leaves IF the left mouse button is down, but I need it when the mouse button is up. Is there a straightforward way to do this?
0
 
LVL 10

Accepted Solution

by:
RONSLOW earned 200 total points
ID: 1302714
There is an article in Windows Developers Journal Sept 1996 which describes how to implement a WM_MOUSEMOVEIN and WM_MOUSEMOVEOUT message.  It discusses a couple of different ways to implement this, and implements a "best" method.  You can download the code from the WDJ site or I can send you the source code if you like.

e-Mail me at Roger_Onslow@compsys.com.au

0
Get proactive database performance tuning online

At Percona’s web store you can order full Percona Database Performance Audit in minutes. Find out the health of your database, and how to improve it. Pay online with a credit card. Improve your database performance now!

 

Author Comment

by:derrickh
ID: 1302715
This code is an SDK solution. I was looking for a MFC way to do this.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1302716
You simply override PumpMessage for your CMyApp to do normal pump message then call the special dispatch code using m_msgCur

(Please refer to my e-Mail reply for details).

I'll see if I can get it working in my own app and will post some code here for reference.  If you get it working first, let me know.

Roger

0
 

Expert Comment

by:asker
ID: 1302717
If you are working under NT, check TrackMouseEvent routine in Win32 API.
0
 

Author Comment

by:derrickh
ID: 1302718
Nope.  I found that already, and to my dismay it only works for NT (as you said).  We're writing the software for Windows 95 AND NT.  It must be compatible with both. :-(
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1302719
I've got it working - will post solution here shortly (when I get a break from my real work :-)

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1302720
Here is my code (seems to work OK).

in my WinApp.h
====================
extern const UINT WM_MOUSEMOVEIN;
extern const UINT WM_MOUSEMOVEOUT;

class QWinApp : public CWinApp {
      ...
      bool m_bMouseIn;
      bool m_bMouseInOutUnknown;
      bool m_bGenerateMouseInOutMessages;
      ...
      //{{AFX_VIRTUAL(QWinApp)
      ...
      virtual BOOL PumpMessage();
      ...
      //}}AFX_VIRTUAL
      ...
};

in my WinApp.cpp
====================

const UINT WM_MOUSEMOVEIN = ::RegisterWindowMessage("WM_MOUSEMOVEIN");
const UINT WM_MOUSEMOVEOUT = ::RegisterWindowMessage("WM_MOUSEMOVEOUT");

QWinApp::QWinApp() :
      ...
      , m_bMouseIn(FALSE)      // doesn't matter because don't know yet
      , m_bMouseInOutUnknown(TRUE)      // don't know whether in or out yet
      , m_bGenerateMouseInOutMessages(FALSE)      // TRUE if you want mouse move in/out message generated
{
      ...
}

BOOL QWinApp::PumpMessage() {
      BOOL ok = CWinApp::PumpMessage();
      if (ok && m_bGenerateMouseInOutMessages) {
            //If mouse is in then check if it has gone out. If
            //mouse is not in then check if it has come in.
            if (m_bMouseIn || m_bMouseInOutUnknown) {
                  //As long as there is no message for this application
                  //track the mouse cursor position.
                  while(!PeekMessage(&m_msgCur, 0, 0, 0, PM_NOREMOVE)) {
                        CWnd* pMainWnd = ::AfxGetMainWnd();
                        if (pMainWnd) {
                              CPoint pt; GetCursorPos(&pt);
                              CWnd* pMsgWnd = CWnd::WindowFromPoint(pt);
                              //If window at mouse cursor position is not this
                              //app's window and not any of its child windows
                              //then it means mouse has left the app area.
                              if (pMsgWnd != pMainWnd && !pMainWnd->IsChild(pMsgWnd)) {
                                    m_bMouseIn = FALSE;
                                    m_bMouseInOutUnknown = FALSE;
                                    pMainWnd->PostMessage(WM_MOUSEMOVEOUT, 0, 0L);
                                    break;
                              }
                        }
                  }
            }
            if (! m_bMouseIn || m_bMouseInOutUnknown) {
                  //If the mouse is not in and the app has received
                  //mouse move message the it means mouse has entered.
                  if (
                        m_msgCur.message == WM_MOUSEMOVE ||
                        m_msgCur.message == WM_NCMOUSEMOVE
                  ) {
                        CWnd* pMainWnd = ::AfxGetMainWnd();
                        if (pMainWnd) {
                              m_bMouseIn = TRUE;
                              m_bMouseInOutUnknown = FALSE;
                              pMainWnd->PostMessage(WM_MOUSEMOVEIN, 0, 0L);
                        }
                  }
            }
      }
      return ok;
}

example of how to handle a message in MainFrame.h/cpp
============================================================

BEGIN_MESSAGE_MAP(QMainFrame, CFrameWnd)
...
ON_REGISTERED_MESSAGE(WM_MOUSEMOVEIN, OnMouseMoveIn)
ON_REGISTERED_MESSAGE(WM_MOUSEMOVEOUT, OnMouseMoveOut)
...
END_MESSAGE_MAP()

LRESULT QMainFrame::OnMouseMoveIn(WPARAM /*wparam*/, LPARAM /*lparam*/) {
      TRACE("OnMouseMoveIn\n");
      return 0;
}

LRESULT QMainFrame::OnMouseMoveOut(WPARAM /*wparam*/, LPARAM /*lparam*/) {
      TRACE("OnMouseMoveOut\n");
      return 0;
}

Hope this helps.

Roger

0
 

Author Comment

by:derrickh
ID: 1302721
This I can work with. Thank for the time you put in!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question