Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Improve Zooming with Enhanced Mouse Wheels

, 19 Oct 2011
How to give your users a better zooming experience with High Resolution Mouse Wheels.
// MouseWheel.cpp :

#include "stdafx.h"

HHOOK g_hHook = 0 ;
HANDLE g_hThread = 0 ;
bool g_bSkip = false ;
LONG g_nTotalDelta = 0 ;
bool g_bExit = false;

// parameters for SetParameters (and their defaults)
int g_nDelta = WHEEL_DELTA ;
int g_nSleep = 18 ; // 18 milliseconds seems to be the minimum value that can be processed.
int g_nEvents = 1 ; // 18 milliseconds seems to be the minimum value that can be processed.

__declspec( dllexport ) void SetParameters(int x1, int x2, int x3)
{
	//SuspendThread(g_hThread) ;
	g_bSkip = true ;
	g_nDelta = x1 ;
	g_nSleep = x2 ;
	g_nEvents=x3 ;
	g_bSkip = false ;
	//ResumeThread(g_hThread) ;
}

DWORD WINAPI WorkerThread(LPVOID pParam)
{
	while (!g_bExit) {
		if (g_bSkip) {
			Sleep(3) ;
			continue ;
		}
		if (g_nTotalDelta == 0) {
			Sleep(3) ;
			continue ;
		}
		int nDirection = g_nTotalDelta/abs(g_nTotalDelta) ; 
		mouse_event( MOUSEEVENTF_WHEEL, 0, 0, nDirection*g_nDelta, 0);
		Sleep(g_nSleep) ;
	}
	return 0 ;
}

LRESULT WINAPI ProcMouseLL (int nCode, WPARAM wParam, LPARAM lParam)
{
	if (nCode < 0)
		return CallNextHookEx ( g_hHook, nCode, wParam, lParam );
	if (WM_MOUSEWHEEL == wParam) {
		if (lParam == 0)
			return CallNextHookEx ( g_hHook, nCode, wParam, lParam );
		MSLLHOOKSTRUCT *hookStruct = (MSLLHOOKSTRUCT *)lParam ;
		short delta = (short)HIWORD(hookStruct->mouseData) ;
		if (hookStruct->flags & LLMHF_INJECTED) {
			// created by mouse_event()
			// assumption is that we called it from our WorkerThread
			if ((g_nTotalDelta*delta) > 0) {
				g_nTotalDelta -= delta ;
				if ((g_nTotalDelta*delta) < 0) {
					g_nTotalDelta = 0 ;
				}
				return CallNextHookEx ( g_hHook, nCode, wParam, lParam ); // pass mouse wheel to system and application
			}
			else {
				// we've reversed directions and discard mouse_event() going in the opposite direction
				return -1 ; // eat mouse wheel
			}
		}
		else {
			// physical hardware generated event
			g_nTotalDelta = abs(delta)/delta*g_nDelta*g_nEvents ;
			return -1 ; // eat mouse wheel
		}
	}
	if ((WM_LBUTTONDOWN == wParam) ||
	    (WM_LBUTTONUP == wParam) ||
		(WM_RBUTTONDOWN == wParam) ||
		(WM_RBUTTONUP == wParam)) {
			g_nTotalDelta=0 ;
	}
	return CallNextHookEx ( g_hHook, nCode, wParam, lParam );
}

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,
    DWORD fdwReason,
    LPVOID lpvReserved)
{
    if ( fdwReason == DLL_PROCESS_ATTACH )
    {
		DisableThreadLibraryCalls( hinstDLL );
        if ( g_hHook )
            return FALSE;
        g_hHook = SetWindowsHookEx( WH_MOUSE_LL, (HOOKPROC)ProcMouseLL,hinstDLL, 0 );
		DWORD threadid;
		g_bExit = false ;
		g_bSkip = true ;
		g_hThread = CreateThread(NULL, 0,  WorkerThread, 0, 0, &threadid);
	}
    else if ( fdwReason == DLL_PROCESS_DETACH )
    {
		g_bSkip = false ;
		g_bExit = true ;
		Sleep((DWORD)(g_nSleep+5)) ;
		if (g_hHook)     
		{                                       
			UnhookWindowsHookEx(g_hHook);     
			g_hHook = 0;
		}
    }
    return TRUE;
}

extern "C" BOOL __stdcall _DllMainCRTStartup( 
    HINSTANCE hinstDLL,
    DWORD fdwReason,
    LPVOID lpvReserved)
{
    return DllMain( hinstDLL, fdwReason, lpvReserved );
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Stephen H Davis
Software Developer (Senior) Logitech Corporation
United States United States
Stephen lives in Fremont, CA with his wife and daughter and has programmed in C and C++ for a very long time.

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 19 Oct 2011
Article Copyright 2011 by Stephen H Davis
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid