Hi, I am creating an application in win32 that will display the x, y position (in screen coordinates) of the mouse if the mouse (inside my application / NC area and outside).
I am at the stage when I want to detect when the mouse completely leaves the application. I wrote a simple win32 application that should detect and notify itself when the mouse leaves my application, BUT it does not work, I never receive WM_MOUSELEAVE and WM_NCMOUSELEAVE messages.
What do you think is wrong? Am I using the wrong win32 functions?
#include "stdafx.h"
#include <windows.h>
#include <vector>
#include <string>
#include <cstdlib>
static HINSTANCE gInstance;
enum MouseStatus { DEFAULT = 50001, LEFT_CLIENT, LEFT_NCLIENT };
static MouseStatus mouseState = DEFAULT;
static COLORREF bkCol = RGB(0,255,255);
BOOL TrackMouse( HWND hwnd )
{
TRACKMOUSEEVENT mouseEvt;
ZeroMemory( &mouseEvt, sizeof(TRACKMOUSEEVENT) );
mouseEvt.cbSize = sizeof(TRACKMOUSEEVENT);
mouseEvt.dwFlags = TME_LEAVE | TME_NONCLIENT;
mouseEvt.hwndTrack = hwnd;
return TrackMouseEvent( &mouseEvt );
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
BOOL trackSuccess = TrackMouse( hwnd );
if ( trackSuccess == 0 )
{
MessageBoxW( hwnd, L"Failed to track mouse", L"Error", MB_OK|MB_ICONEXCLAMATION );
}
else MessageBoxW( hwnd, L"Tracking mouse", L"Success", MB_OK|MB_ICONEXCLAMATION );
}
break;
case WM_MOUSELEAVE:
{
mouseState = LEFT_CLIENT;
bkCol = RGB(50,50,50);
InvalidateRect( hwnd, NULL, true );
}
break;
case WM_NCMOUSELEAVE :
{
if ( mouseState == LEFT_CLIENT )
{
mouseState = LEFT_NCLIENT;
BOOL trackSuccess = TrackMouse( hwnd );
if ( trackSuccess == 0 )
{
bkCol = RGB(255,255,0);
MessageBoxW( hwnd, L"On WM_NCMOUSELEAVE: Failed to track mouse", L"Error", MB_OK|MB_ICONEXCLAMATION );
}
else MessageBoxW( hwnd, L"On WM_NCMOUSELEAVE: Tracking mouse", L"Success", MB_OK|MB_ICONEXCLAMATION );
InvalidateRect( hwnd, NULL, true );
}
}
break;
case WM_ACTIVATE:
case WM_MOUSEHOVER:
{
mouseState = DEFAULT;
bkCol = RGB(0,255,255);
InvalidateRect( hwnd, NULL, true );
}
break;
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint( hwnd, &ps );
SetBkColor( hdc, bkCol );
Rectangle( hdc, 10, 10, 200, 200 );
EndPaint( hwnd, &ps );
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE gInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = gInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(DKGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"Custom Class";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBoxW(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
L"Custom Class",
L"App Name",
WS_CAPTION|WS_MINIMIZEBOX|WS_VISIBLE|WS_OVERLAPPED|WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 600, 500,
NULL, NULL, gInstance, NULL);
if(hwnd == NULL)
{
MessageBoxW(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}