Prev Previous Post   Next Post Next

Turn off mouse pointer when no mouse is plugged in

Posted: 01-30-2008, 03:16 PM
Background:

My company builds an XPE product with a touch screen for pointer input & so
we usually don't want a mouse pointer displayed. Even though our product is
not fielded with a mouse I still wanted the capability to plug in a mouse
for testing, development, etc. So I searched the internet for a registry
setting or a utility that would hide the mouse pointer when no mouse was
plugged in and cause it to reappear once a mouse is plugged in.
Unfortunately I didn't find a utility that did this. So I built my own.



How my program works:

My program compiles to 6Kb (as long as you link to DLL runtime library and
you use the following linker option: /OPT:NOWIN98). My program also relies
on a free third party application that I found on the internet called
'nomousy.exe' (13Kb) which allows you to hide the mouse cursor. My program
determines when a USB mouse is plugged in or not and then calls 'nomousy.exe'
to hide or show the mouse cursor. Note that my program only recognizes when
a USB mouse is plugged in (although you could easily fix this). This is
because we don't have PS/2 connector on our device.



So if anyone now or in the future has a need for such a utility I have
provided the source code to my program below:



#include "stdafx.h"



BOOL bMousedPluggedIn = FALSE;



BOOL FindProcess(TCHAR* _szName)

{

try

{

char szName[MAX_PATH], szToTermUpper[MAX_PATH];

int iLen, iLenP, indx;

BOOL bResult;

DWORD aiPID[1000], iCb = 1000, iNumProc, iV2000 = 0;

DWORD iCbneeded, i;

HANDLE hProc;

HINSTANCE hInstLib;

HMODULE hMod;



if((_szName == NULL))

return FALSE;



if((*_szName == NULL))

return FALSE;



// Transfer Process name into "szToTermUpper" and

// convert it to upper case

iLenP = strlen(_szName);

if((iLenP < 1) || (iLenP > MAX_PATH))

return FALSE;



for(indx=0; indx < iLenP; indx++)

szToTermUpper[indx] = toupper(_szName[indx]);



szToTermUpper[iLenP] = 0;



// PSAPI Function Pointers.

BOOL (WINAPI *lpfEnumProcesses)( DWORD*, DWORD cb, DWORD*);

BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE*, DWORD,
LPDWORD );

DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE, LPTSTR,
DWORD );



if((hInstLib = LoadLibraryA("PSAPI.DLL")) == NULL)

return FALSE;



// Get procedure addresses.

lpfEnumProcesses = (BOOL (WINAPI*)(DWORD*, DWORD, DWORD*))
GetProcAddress(hInstLib, "EnumProcesses");

lpfEnumProcessModules = (BOOL (WINAPI*)(HANDLE, HMODULE*, DWORD,
LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules");

lpfGetModuleBaseName = (DWORD (WINAPI*)(HANDLE, HMODULE, LPTSTR,
DWORD )) GetProcAddress(hInstLib, "GetModuleBaseNameA");



if((lpfEnumProcesses == NULL) || (lpfEnumProcessModules == NULL) ||
(lpfGetModuleBaseName == NULL))

{

FreeLibrary(hInstLib);

return FALSE;

}



bResult = lpfEnumProcesses(aiPID, iCb, &iCbneeded);

if(!bResult)

{

// Unable to get process list, EnumProcesses failed

FreeLibrary(hInstLib);

return FALSE;

}



// How many processes are there?

iNumProc = iCbneeded / sizeof(DWORD);



// Get and match the name of each process

for(i = 0; i < iNumProc; i++)

{

// Get the (module) name for this process

strcpy(szName, "Unknown");



// First, get a handle to the process

hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, aiPID[i]);



// Now, get the process name

if(hProc)

if(lpfEnumProcessModules(hProc, &hMod, sizeof(hMod),
&iCbneeded))

iLen = lpfGetModuleBaseName(hProc, hMod, szName, MAX_PATH);



CloseHandle(hProc);



// We will match regardless of lower or upper case

if(stricmp(szName, szToTermUpper) == 0)

{

FreeLibrary(hInstLib);

return TRUE;

}

}



FreeLibrary(hInstLib);

}

catch(...)

{

#ifdef _DEBUG

OutputDebugString("Uncaught exception!! - FindProcess");

#endif

}




return FALSE;

}



void Execute(LPCTSTR lpszApp, LPCTSTR lpszArgs)

{

SHELLEXECUTEINFO sei;

TCHAR szPath[MAX_PATH];

TCHAR* pStrPos;



lstrcpy(szPath, lpszApp);

if((pStrPos = _tcsrchr(szPath, '\\')))

*pStrPos = NULL;

else

*szPath = NULL;



memset(&sei, 0, sizeof(sei));

sei.cbSize = sizeof(sei);

sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;

sei.hwnd = NULL;

sei.lpFile = lpszApp;

sei.lpParameters = lpszArgs;

sei.lpDirectory = szPath;

sei.nShow = SW_HIDE;



ShellExecuteEx(&sei);

}



void MousePointer()

{

static TCHAR szNoMousyExe[] = "nomousy.exe";

static BOOL bFirst = TRUE;

static BOOL bNoMousy = FALSE;



if(bFirst)

{

TCHAR szFilename[MAX_PATH] = {0};

TCHAR szPath[MAX_PATH] = {0};

TCHAR* pStrPos;



if(GetModuleFileName(NULL, szPath, MAX_PATH))

if((pStrPos = _tcsrchr(szPath, '\\')))

*pStrPos = NULL;



wsprintf(szFilename, TEXT("%s\\%s"), szPath, szNoMousyExe);

if((GetFileAttributes(szFilename) != 0xFFFFFFFF))

bNoMousy = TRUE;



bFirst = FALSE;

}



if(bNoMousy)

{

static BOOL bSync = FALSE;

static BOOL bHidden = FALSE;



if(!bSync)

{

if(FindProcess(szNoMousyExe))

bHidden = TRUE;



bSync = TRUE;

}



if(bMousedPluggedIn)

{

// mouse present

if(bHidden)

{

Execute(szNoMousyExe, NULL);

bHidden = FALSE;

}

}

else

{

// mouse not present

if(!bHidden)

{

Execute(szNoMousyExe, TEXT("/hide"));

bHidden = TRUE;

}

}

}

}



char FirstDriveFromMask (ULONG unitmask)

{

char i;



for (i = 0; i < 26; ++i)

{

if(unitmask & 0x1)

break;



unitmask = unitmask >> 1;

}



return (i + 'A');

}



void Main_OnDeviceChange(HWND hwnd, WPARAM wParam, LPARAM lParam)

{

char szMsg[128] = {0};

PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam;



switch(wParam)

{

case DBT_DEVICEARRIVAL:

switch(lpdb->dbch_devicetype)

{

case DBT_DEVTYP_DEVICEINTERFACE:

{

bMousedPluggedIn = TRUE;

MousePointer();

}

break;

}

break;



case DBT_DEVICEREMOVECOMPLETE:

switch(lpdb->dbch_devicetype)

{

case DBT_DEVTYP_DEVICEINTERFACE:

{

bMousedPluggedIn = FALSE;

MousePointer();

}

break;

}

break;



default:

break;

}

}



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)

{

switch (message)

{

case WM_DESTROY:

PostQuitMessage(0);

break;



case WM_DEVICECHANGE:

Main_OnDeviceChange(hWnd, wParam, lParam);

break;



default:

return DefWindowProc(hWnd, message, wParam, lParam);

}



return 0;

}



BOOL RegisterForUSBDeviceNotify(HWND hWnd)

{

GUID InterfaceClassGuid = {0x378de44c, 0x56ef,
0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd};
//GUID_DEVINTERFACE_MOUSE

HDEVNOTIFY hDevNotify = {0};

DEV_BROADCAST_DEVICEINTERFACE NotificationFilter = {0};



NotificationFilter.dbcc_size =
sizeof(DEV_BROADCAST_DEVICEINTERFACE);

NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;

memcpy(&NotificationFilter.dbcc_classguid, &InterfaceClassGuid,
sizeof(GUID));



hDevNotify = RegisterDeviceNotification(hWnd, &NotificationFilter,
DEVICE_NOTIFY_WINDOW_HANDLE);



if(!hDevNotify)

return FALSE;



return TRUE; // return TRUE unless you set the focus to a control

}



BOOL FigureOutIfMouseIsConnected()

{

GUID InterfaceClassGuid = {0x378de44c, 0x56ef, 0x11d1, 0xbc, 0x8c,
0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}; //GUID_DEVINTERFACE_MOUSE

HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;

BOOL ret = FALSE;



// Create a HDEVINFO with all present devices.

if(((hDevInfo = SetupDiGetClassDevs(&InterfaceClassGuid, 0, 0,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) != INVALID_HANDLE_VALUE))

{

DWORD i;

SP_DEVINFO_DATA DeviceInfoData = {0};



// Enumerate through all devices in Set.

DeviceInfoData.cbSize = sizeof(DeviceInfoData);



for(i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)

{

DWORD buffersize;

DWORD DataT = 0;



/* char szData[1024] = {0};

buffersize = (sizeof(szData) - 1);



if(!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData,
SPDRP_DEVICEDESC, &DataT, (PBYTE) szData, buffersize, &buffersize))

break;



char szDbg[1024 + 128];

sprintf(szDbg, "Result:[%s]\r\n", szData);

OutputDebugString(szDbg);



*/

DWORD devCap = 0;

buffersize = sizeof(devCap);



if(!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData,
SPDRP_CAPABILITIES, &DataT, (PBYTE) &devCap, buffersize, &buffersize))

break;



// Eliminates terminal services mouse

if((devCap & CM_DEVCAP_SURPRISEREMOVALOK))

ret = TRUE;

}



// Cleanup

SetupDiDestroyDeviceInfoList(hDevInfo);

}



return ret;

}



ATOM MyRegisterClass(HINSTANCE hInstance, LPCTSTR szClassName)

{

WNDCLASSEX wcex = {0};



wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style = CS_HREDRAW | CS_VREDRAW;

wcex.lpfnWndProc = (WNDPROC)WndProc;

wcex.cbClsExtra = 0;

wcex.cbWndExtra = 0;

wcex.hInstance = hInstance;

wcex.hIcon = LoadIcon(hInstance, NULL);

wcex.hCursor = LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

wcex.lpszMenuName = NULL;

wcex.lpszClassName = szClassName;

wcex.hIconSm = LoadIcon(wcex.hInstance, NULL);



return RegisterClassEx(&wcex);

}



BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

HWND hWnd = NULL;

TCHAR szWindowName[] = TEXT("HidePtr");



MyRegisterClass(hInstance, szWindowName);

hWnd = CreateWindow(szWindowName, szWindowName, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);



if(!hWnd)

return FALSE;



ShowWindow(hWnd, SW_HIDE);

UpdateWindow(hWnd);

RegisterForUSBDeviceNotify(hWnd);

bMousedPluggedIn = FigureOutIfMouseIsConnected();

MousePointer();



return TRUE;

}



int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow)

{

MSG msg;



if(!InitInstance (hInstance, nCmdShow))

return FALSE;



while(GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}



return msg.wParam;

}






Reply With Quote

Responses to "Turn off mouse pointer when no mouse is plugged in"

 
LinkBack Thread Tools Display Modes
 


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can PHILIPS Wired Mouse be plugged into PS/2 slot? Guest Windows Vista 0 05-17-2008 05:02 AM
mouse pointer drifts without moving mouse Bill Tisdale Windows XP Help & Support 2 11-15-2003 08:35 PM
mouse pointer drifts without mouse Bill Tisdale Windows XP Hardware 1 11-14-2003 12:51 AM
mouse pointer drifts on screen without moving mouse Bill Tisdale Windows XP Performance & Maintenance 0 11-13-2003 10:57 PM
mouse/pointer Diane Windows XP Basics 1 09-18-2003 03:32 PM