Solved

Mouse notification when leaving the client area

Posted on 1997-07-21
10
225 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
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 50 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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

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

U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

Question has a verified solution.

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

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
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.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

778 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