Created
March 8, 2023 19:47
-
-
Save gszauer/8ad9758266c825a4a85e1f9092d00bce to your computer and use it in GitHub Desktop.
mousehandler.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////////////////////////////////////////// | |
// | |
// 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