Skip to content

Instantly share code, notes, and snippets.

@gszauer
Created March 8, 2023 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gszauer/8ad9758266c825a4a85e1f9092d00bce to your computer and use it in GitHub Desktop.
Save gszauer/8ad9758266c825a4a85e1f9092d00bce to your computer and use it in GitHub Desktop.
mousehandler.cpp
///////////////////////////////////////////////////////////////////////////
//
// MODULE: MOUSINFO.C
//
// DESCRIPTION: SDK sample for handling the WM_MOUSEWHEEL message and
// the TrackMouseEvent() API.
//
// Applet displays MouseButton, MouseWheel, MouseMovement, and
// any mouse messages in the title bar.
//
// PLATFORMS: WinNT 4.0 and newer
//
// Copyright 1995 - 2000 Microsoft Corporation.
// All rights reserved
//
//
///////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
//#include "mousinfo.h"
///////////////////////////////////////////////////////////////////////////
//
// MODULE: MOUSINFO.H
//
// DESCRIPTION: Include file for the MousInfo.Exe Tool
//
//
// Copyright 1995 - 2000 Microsoft Corporation.
// All rights reserved
//
//
///////////////////////////////////////////////////////////////////////////
TCHAR szAppName[] = TEXT("MousInfo");
TCHAR szClassName[] = TEXT("MousInfoClass");
// Maximum # of chars in title bar
#define MAX_TITLE_LEN 44
// Index into Button Message Array
#define NO_MESSAGE 0
#define LBU 1 // Left Button Up
#define RBU 2 // Right Button Up
#define MBU 3 // Middle Button Up
#define LBD 4 // Left Button Down
#define RBD 5 // Right Button Down
#define MBD 6 // Middle Button Down
#define LB2 7 // Left Button Double Click
#define MB2 8 // Right Button Double Click
#define RB2 9 // Middle Button Double Click
#define MW 10 // Mouse Wheel
#define MH 11 // Mouse Hover
#define ML 12 // Mouse Leave
// Resource defines
#define MOUSINFO_ICON 102
#define IDM_MENU 0x0900
#define IDM_TRACK 0x1000
#define IDM_HOVER 0x1001
#define IDM_LEAVE 0x1002
#define IDM_ABOUT 0x2000
// Function Prototypes
int WINAPI WinMain(
__in HINSTANCE,
__in_opt HINSTANCE,
__in_opt LPSTR,
__in int);
LRESULT CALLBACK MainWindowProc(
HWND,
UINT,
WPARAM,
LPARAM);
// End mouseinfo.h
// Globals
HINSTANCE ghInst = NULL;
//
// Array of Mouse Message Strings
//
TCHAR garMsgStrings[][20] =
{
TEXT(" "),
TEXT("WM_LBUTTONUP "),
TEXT("WM_RBUTTONUP "),
TEXT("WM_MBUTTONUP "),
TEXT("WM_LBUTTONDOWN "),
TEXT("WM_RBUTTONDOWN "),
TEXT("WM_MBUTTONDOWN "),
TEXT("WM_LBUTTONDBLCLK "),
TEXT("WM_MBUTTONDBLCLK "),
TEXT("WM_RBUTTONDBLCLK "),
TEXT("WM_MOUSEWHEEL "),
TEXT("WM_MOUSEHOVER "),
TEXT("WM_MOUSELEAVE ")
};
//////////////////////////////////////////////////////////////////////////
//
// FUNCTION: int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int)
//
// DESCRIPTION: Your basic WinMain ()
//
/////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(
__in HINSTANCE hInstance,
__in_opt HINSTANCE hPrevInstance,
__in_opt LPSTR lpCmdLine,
__in int nCmdShow)
{
MSG msg = { 0 };
WNDCLASS wc = { 0 };
HWND hwndMain = NULL;
BOOL bRet = FALSE;
BOOL bRetZero = FALSE;
ghInst = hInstance;
//
// Register our main window
//
wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = (WNDPROC)MainWindowProc;
wc.hInstance = ghInst;
wc.hIcon = 0;// LoadIcon(hInstance, MAKEINTRESOURCE(MOUSINFO_ICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = 0;// MAKEINTRESOURCE(IDM_MENU);
wc.lpszClassName = szClassName;
if (!RegisterClass(&wc))
{
bRetZero = TRUE;
goto exit_func;
}
//
// Create the main window...
// with an initial size of 0
//
hwndMain = CreateWindow(
szClassName,
szAppName,
WS_OVERLAPPEDWINDOW ^ WS_MAXIMIZEBOX,
0, 0, 0, 0,
NULL, NULL, ghInst, NULL);
//
// Show the window
//
ShowWindow(hwndMain, SW_SHOW);
UpdateWindow(hwndMain);
//
// Message pump
//
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
bRetZero = TRUE;
goto exit_func;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
exit_func:
if (bRetZero)
{
return 0;
}
else
{
return (int)msg.wParam;
}
}
//////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: LRESULT CALLBACK MainWindowProc (HWND, UINT, WPARAM, LPARAM)
//
// DESCRIPTION: Your standard Window Procedure.
//
// MESSAGE: Handles the following Windows messages:
//
// WM_CREATE
// WM_DESTROY
// WM_SYSCOMMAND
// WM_LBUTTONUP
// WM_RBUTTONUP
// WM_MBUTTONUP
// WM_LBUTTONDOWN
// WM_RBUTTONDOWN
// WM_MBUTTONDOWN
// WM_LBUTTONDBLCLK
// WM_MBUTTONDBLCLK
// WM_RBUTTONDBLCLK
// WM_MOUSEMOVE
//
// And the new mouse message
//
// WM_MOUSEWHEEL
//
// And the new TrackMouseEvent() Messages
//
// WM_MOUSEHOVER // mouse hovered specified delay over
// // client area
// WM_MOUSELEAVE // mouse has left the client area
//
//
//////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK MainWindowProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
TEXTMETRIC tm = { 0 };
HDC hDC = NULL;
int MsgIndex = NO_MESSAGE; // Index into garMsgStrings[] array
TCHAR szBuff[128] = { 0 }; // String buffer
size_t bufferSize = ARRAYSIZE(szBuff); // Size of szBuff
static int LB = 0, RB = 0, MB = 0; // State of the mouse buttons
static int X = 0, Y = 0; // Mouse position
static TCHAR Roller = TEXT(' '); // State of the mouse wheel. '+' or '-'
static int fHasWheel = FALSE; // Mouse has a wheel?? TRUE if yes,
// FALSE if no
switch (message)
{
case WM_CREATE:
//
// See if we have a mouse with a wheel attached to the system.
// Note that SM_MOUSEWHEELPRESENT is a new flag for GetSystemMetrics
// and returns TRUE if a mouse with a wheel is present, FALSE if not.
//
fHasWheel = GetSystemMetrics(SM_MOUSEWHEELPRESENT);
//
// Size the window so that it will display all the text
//
hDC = GetDC(hwnd);
GetTextMetrics(hDC, &tm);
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0,
tm.tmMaxCharWidth * MAX_TITLE_LEN,
100, SWP_SHOWWINDOW);
ReleaseDC(hwnd, hDC);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
//
// Handle WM_MOUSE messages.
// First we setup up some variables and then let
// control fall through to the end of the switch
// construct, where we then update the title bar.
//
case WM_LBUTTONUP: LB = 0; MsgIndex = LBU; break;
case WM_RBUTTONUP: RB = 0; MsgIndex = RBU; break;
case WM_MBUTTONUP: MB = 0; MsgIndex = MBU; break;
case WM_LBUTTONDOWN: LB = 1; MsgIndex = LBD; break;
case WM_RBUTTONDOWN: RB = 1; MsgIndex = RBD; break;
case WM_MBUTTONDOWN: MB = 1; MsgIndex = MBD; break;
case WM_LBUTTONDBLCLK: LB = 0; MsgIndex = LB2; break;
case WM_MBUTTONDBLCLK: MB = 0; MsgIndex = MB2; break;
case WM_RBUTTONDBLCLK: RB = 0; MsgIndex = RB2; break;
case WM_MOUSEHOVER: MsgIndex = MH; break;
case WM_MOUSELEAVE: MsgIndex = ML; break;
case WM_MOUSEMOVE: MsgIndex = NO_MESSAGE; Roller = TEXT(' '); break;
// Handle WM_MOUSEWHEEL message.
// We handle this message a little differently since the
// roller movement info is in the HIWORD of wParam.
//
// The MouseWheel has 18 'detents'. As the wheel is rolled
// and a detent is encountered, the OS will send a WM_MOUSEWHEEL
// message with the HIWORD of wParam set to a value of +/- 120.
// '+' if the wheel is being rolled forward (away from the user),
// '-' if the wheel is being rolled backwards (towards the user).
case WM_MOUSEWHEEL:
//
// Mouse Wheel is being rolled forward
//
if ((short)HIWORD(wParam) > 0)
{
Roller = TEXT('+');
}
//
// Mouse Wheel is being rolled backward
//
if ((short)HIWORD(wParam) < 0)
{
Roller = TEXT('-');
}
MsgIndex = MW;
break;
case WM_COMMAND:
switch (wParam)
{
//
// Call the TrackMouseEvent() API, and set up a WM_MOUSEHOVER
// "one-shot" event. Exactly one and only one WM_MOUSEHOVER
// message will be sent to the window specified in the hwndTrack
// member of the TRACKMOUSEEVENT structure, when the mouse has
// 'hovered' over the client area an amount of time equal to that
// specified in the dwHoverTime member of TRACKMOUSEEVENT.
//
// NOTE that this message will be generated only once. The application
// must call the TrackMouseEvent() API again in order for the system
// to generate another WM_MOUSEHOVER message.
//
case IDM_HOVER:
{
TRACKMOUSEEVENT tme = { 0 };
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_HOVER;
tme.hwndTrack = hwnd;
tme.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&tme);
break;
}
//
// Call the TrackMouseEvent() API, and set up a WM_MOUSELEAVE
// "one-shot" event. Exactly one and only one WM_MOUSELEAVE
// message will be sent to the window specified in the hwndTrack
// member of the TRACKMOUSEEVENT structure, when the mouse has
// left the client area.
//
// NOTE that this message will be generated only once. The application
// must call the TrackMouseEvent() API again in order for the system
// to generate another WM_MOUSELEAVE message. Also note that if the
// mouse pointer is not over the application, a call to TrackMouseEvent()
// will result in the immediate posting of a WM_MOUSELEAVE
// message.
//
case IDM_LEAVE:
{
TRACKMOUSEEVENT tme = { 0 };
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
TrackMouseEvent(&tme);
break;
}
case IDM_ABOUT:
{
TCHAR buff[128] = { 0 };
size_t buffSize = sizeof(buff) / sizeof(buff[0]);
StringCchPrintf(buff, buffSize,
TEXT("MousInfo.Exe\r\n")
TEXT("Copyright 1995 - 2000 Microsoft Corp.\r\n")
TEXT("All rights reserved\r\n\r\n"));
MessageBox(hwnd, buff, szAppName, MB_OK);
break;
}
}
break;
default:
goto exit_func;
break;
} // end switch (message)
//
// If the mouse has a wheel, display the state of the mouse buttons,
// wheel and position in the title bar.
// Else if mouse does not have a wheel, do not display the state
// of the wheel (but do display everything else!)
//
if (fHasWheel)
{
StringCchPrintf(szBuff, bufferSize,
TEXT("L:%d M:%d R:%d W:%c x:%04d y:%04d %s"),
LB, MB, RB, Roller,
LOWORD(lParam), HIWORD(lParam),
garMsgStrings[MsgIndex]);
}
else
{
StringCchPrintf(szBuff, bufferSize,
TEXT("L:%d M:%d R:%d x:%04d y:%04d %s"),
LB, MB, RB, LOWORD(lParam), HIWORD(lParam),
garMsgStrings[MsgIndex]);
}
SetWindowText(hwnd, szBuff);
exit_func:
return DefWindowProc(hwnd, message, wParam, lParam);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment