Turn off mouse pointer when no mouse is plugged in

S

Smedly Tonker

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);



// 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;

}
 
S

Schockal

Hi There,

I am looking for help with my touch screen driver. I am trying to use the
touchscreen driver from Gunze, the zip files include inf, sys and exe files.
I followed the method described by Microsoft on how to create a custom
component. The component is getting built by target designer. The ufd.inf and
ufd.sys are included in the C:/windows directory. FBA runs fine, setupai.log
tells that the driver had been installed properly and the device did not
start for some unknown reason.

My question is should I see the Gunze driver on the Add/Remove programs list
? . If I install it manually, I see the application on the Add/Remove program
list. How come my application is not on the list ?.

Whats the normal procedure to add a third party component to XPE ?.

Thanks in advance,

SC






Smedly Tonker said:
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);



// 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)
 
J

JS

Another way to determine how many mice are plugged in is to call
GetRawInputDeviceList()
and count how many RIM_TYPEMOUSE devices are listed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top