derrickh
asked on
Mouse notification when leaving the client area
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.
Use OnMouseMove, it gives you coordinates of cursor. Based on them you can figure out where you are.
ASKER
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?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This code is an SDK solution. I was looking for a MFC way to do this.
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
(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
If you are working under NT, check TrackMouseEvent routine in Win32 API.
ASKER
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. :-(
I've got it working - will post solution here shortly (when I get a break from my real work :-)
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_bGenerateMouseInOutMessa ges;
...
//{{AFX_VIRTUAL(QWinApp)
...
virtual BOOL PumpMessage();
...
//}}AFX_VIRTUAL
...
};
in my WinApp.cpp
====================
const UINT WM_MOUSEMOVEIN = ::RegisterWindowMessage("W M_MOUSEMOV EIN");
const UINT WM_MOUSEMOVEOUT = ::RegisterWindowMessage("W M_MOUSEMOV EOUT");
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_bGenerateMouseInOutMessa ges(FALSE) // TRUE if you want mouse move in/out message generated
{
...
}
BOOL QWinApp::PumpMessage() {
BOOL ok = CWinApp::PumpMessage();
if (ok && m_bGenerateMouseInOutMessa ges) {
//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_msgC ur, 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_M OUSEMOVEOU T, 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_M OUSEMOVEIN , 0, 0L);
}
}
}
}
return ok;
}
example of how to handle a message in MainFrame.h/cpp
========================== ========== ========== ========== ====
BEGIN_MESSAGE_MAP(QMainFra me, CFrameWnd)
...
ON_REGISTERED_MESSAGE(WM_M OUSEMOVEIN , OnMouseMoveIn)
ON_REGISTERED_MESSAGE(WM_M OUSEMOVEOU T, 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
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_bGenerateMouseInOutMessa
...
//{{AFX_VIRTUAL(QWinApp)
...
virtual BOOL PumpMessage();
...
//}}AFX_VIRTUAL
...
};
in my WinApp.cpp
====================
const UINT WM_MOUSEMOVEIN = ::RegisterWindowMessage("W
const UINT WM_MOUSEMOVEOUT = ::RegisterWindowMessage("W
QWinApp::QWinApp() :
...
, m_bMouseIn(FALSE) // doesn't matter because don't know yet
, m_bMouseInOutUnknown(TRUE)
, m_bGenerateMouseInOutMessa
{
...
}
BOOL QWinApp::PumpMessage() {
BOOL ok = CWinApp::PumpMessage();
if (ok && m_bGenerateMouseInOutMessa
//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_msgC
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_M
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_M
}
}
}
}
return ok;
}
example of how to handle a message in MainFrame.h/cpp
==========================
BEGIN_MESSAGE_MAP(QMainFra
...
ON_REGISTERED_MESSAGE(WM_M
ON_REGISTERED_MESSAGE(WM_M
...
END_MESSAGE_MAP()
LRESULT QMainFrame::OnMouseMoveIn(
TRACE("OnMouseMoveIn\n");
return 0;
}
LRESULT QMainFrame::OnMouseMoveOut
TRACE("OnMouseMoveOut\n");
return 0;
}
Hope this helps.
Roger
ASKER
This I can work with. Thank for the time you put in!