No mouse pointer wanted if no mouse is connected.
-
Tuesday, July 03, 2012 9:20 PM
The device I am using has a touchscreen display but can also accept a USB mouse. Wether a mouse is plugged in or not, there is always a pointer in the display.
Basically what I want is to not have a pointer on the display if there is no USB mouse plugged in. When one is plugged in then yes, have a pointer.
Right now the pointer follows where ever you last pressed on the screen. Not really a problem, but sometimes blocks out some of what is being displayed or just looks goofy just sitting there in the middle of the display.
How can I disable the pointer on the screen when no USB mouse is connected and only have it appear if a USB mouse is detected. Where are the routines in the WindowsCE 6.0 source code that controls this?
Thanks.
All Replies
-
Wednesday, July 04, 2012 3:14 AMI usually adjust the display driver to wait for events from the USB mouse driver to turn on/off the mouse cursor. That way you can have touch, but also mouse when you plug in a USB mouse. This of course requires cloning the USB HID mouse driver and adding some code to fire events at Attach and Detach and adding code to the display driver to act on these events.
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services. -
Wednesday, July 04, 2012 10:36 AM
Another option which might be a bit dirtier but I think easier to implement, is to make an application that polls for USB attachment event and if no attachment was done, just make the application move the mouse pointer outside the visible display.
It is quite close to what Michel offered but I find it easier to implement.
Shahal
-
Tuesday, July 10, 2012 6:03 PMThanks. Initally I think I will go with the recommendation offered by Michel Verhagen, but only because I don't know exactly what I am doing yet. Your mention of "make the application move the mouse pointer outside the visible display" seems right but I'm thinking that this is a OS type requirement. When the unit first boots, you get the desktop screen with some Icons for example 'My device", etc, and right in the middle of the screen there is the pointer even though I have no USB mouse connected. Anyplace on the screen I tap, the pointer follows. So what I need is for that pointer to just not be there, unless of course a USB mouse is detected. But what you suggest is a great idea...thanks.
-
Tuesday, July 10, 2012 6:22 PM
Thanks Michel: Sounds like this is what I need to try, but it requires me do do what I have not yet got a good handle on which is cloning. You mention adding code to create and trigger on events in the display driver and USB HID mouse driver. That makes perfect sense. You mention cloning the USB HID mouse driver, but I'm guessing the I also need to close the display driver also? Is that correct?
To expose my inexperience even more...where is the source code for the USB HID mouse driver, and the display driver and more importantly, how do I go about cloning them? Is the cloning process similiar to what you describe in your blog at http://guruce.com/blog concerning "Customizing a UI Component" which describes how to clone the Oomui, Startui, and Calibrui components?
Thanks;
-
Tuesday, July 10, 2012 6:41 PM
I suspect that the problem is caused by your touch driver actually presenting itself as a mouse. If it were a true touch driver GWES would automatically remove the cursor when you touch the screen.
This is not necessary a bad thing, or even unusual, but becuase if it I don't think that Shahal's solution will work. Michel's solution is the way to go if you don't have time to rewrite you touch driver to be a true touch driver.
I did just have a thought, if you have source code for your touch driver, you could remove the cursor when the panel is touched, but you will also need to modify the USB mouse driver to show the cursor when the mouse is moved. With this, the cursor will not be in the way when the user is using the touch panel even if a mouse is attached.
Bruce Eitman (eMVP)
Senior Engineer
Bruce.Eitman AT Eurotech DOT com
My BLOG http://geekswithblogs.net/bruceeitman
Eurotech Inc.
www.Eurotech.com -
Thursday, July 12, 2012 1:04 AM
The blog items that will help you are:
http://guruce.com/blogpost/manualcloneofpubliccode
http://guruce.com/blogpost/cloningpubliccodeanexample
The mouse HID code is in \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USB\CLASS\HID
The display driver is already in your BSP, so no need to clone. If it's in the SOC folder you should clone the code to your BSP (so that other BSP's using the same SOC code do not get the change if you don't want it to).
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services.
- Edited by Michel VerhagenMVP Thursday, July 12, 2012 1:08 AM
-
Monday, July 23, 2012 9:56 PM
Thanks Micheal: Your words are encouraging but I still need a lot of clarifications: and I appreciate your help and insights. Unlike myself, you obviously know what you are doing.
I've checked out many cloning method Web-sites including the one's you mention:
http://geekswithblogs.net/BruceEitman/archive/2008/07/02/platform-builder-clone-public-code.aspx
http://guruce.com/blogpost/cloningpubliccodeanexample
http://msdn.microsoft.com/en-us/library/aa459163.aspx
http://guruce.com/blogpost/cloning-calibrui-in-windows-ce-60
http://guruce.com/blogpost/manualcloneofpubliccode
http://msdn.microsoft.com/en-us/library/ms941304.aspx
http://guruce.com/blogAll 7 site have great information but still don't get me thru my quest.
You stated: The mouse HID code is in \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USB\CLASS\HID
That is true but there are some 10 more folders under the HID folder. From what I have gathered, the actual file that I need to modify is the file called mouhid.cpp in the \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USB\CLASS\HID\CLASS\CLIENTS\MOUHID\BASE folder.
So do need to clone just the BASE folder or the whole HID folder? (My guess is just the contents of the BASE folder.
The next challange is where to place these files..I get all different kinds of recommendations.
Each Web-site recommends copying desired folder to clone near the same way:
1. Create a new folder in my platform
2. Copy the entire
\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\NETUIfolder to your OSDesign, for instance\WINCE600\OSDesigns\MyOS\MyOS3.Create two subdirectories for the driver within your platform directory.4. Copy the TELNETD folder to your OS Design (
\WINCE500\PBWorkspaces\<MyOSDesign>\TELNETDor\WINCE600\OSDesigns\<MyOSDesign>\<MyOSDesign>\TELNETD)5. For example, to customize Com16550.dll, create a subdirectory named %_TARGETPLATROOT%\Drivers\Com16550\Src for the library and %_TARGETPLATROOT%\Drivers\Com16550\DLL for the binary file.
6. Copy \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\STARTUI to \WINCE600\OSDesigns\YourOSDesign\YourOSDesign\STARTUI
So where do I actually copy these files? This is CE 6.0 with VS2005 and Platformbuilder CE 6.0. I would like to copy them to a folder I create called
\WINCE600\OSDesigns\<MyOSDesign>\Subproject\MOUHID. Do you see anything wrong with that? Or perhaps in a folder called \WINCE600\3rdParty? (3rd party is described as aDirectory for own components, such as those that were cloned from Public or Private. It is independently created by a developer and, similar to Public, it is automatically scanned for catalog files.).Thanks;
-
Monday, July 23, 2012 10:10 PM
Since this is a driver I would clone the mouse HID stuff to your BSP folder.
- Copy the \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USB\CLASS\HID\CLIENTS\MOUHID\BASE folder to your BSP\SRC\DRIVERS\MOUHID
- Modify the sources file like this:
TARGETNAME=mouhid
TARGETTYPE=DYNLINK
RELEASETYPE=PLATFORM
DLLENTRY=_DllEntryCRTStartup
DEFFILE=$(TARGETNAME).defSOURCELIBS=
TARGETLIBS=\
$(_SYSGENOAKROOT)\lib\$(_CPUINDPATH)\hidparse.lib \
$(_PUBLICROOT)\common\oak\lib\$(_CPUINDPATH)\MouHidStd.lib \
$(_SYSGENSDKROOT)\lib\$(_CPUINDPATH)\coredll.libSOURCES= \
mouhid.cpp \Then set a named event at attach and detach and add code in your display driver to respond to those events.
You could contact us through our website (contact) if you want us to make this change for you. It'll be no more than a couple of hours and will show you how to do it in the future, plus spare a bit of frustration I guess... All our BSPs have this feature included by default.
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services. -
Tuesday, July 24, 2012 10:11 PM
Thanks...but I have a dozen more modifications like this and I need to understand this all myself or you'll end up doing all my work...and like everything its all in the details and I fear that cloing MOIHID is really just the easy part.
I proceeded with your suggestions and noted the following:
Solutions Explorer shows MOUHID(excluded from build), so I presume I need to include it in the build...is that correct? (including in the build adds this folder name into the dirs file located in \WINCE600\BSP\SRC\DRIVERS).
After including it in the build, I right click on MOUHID and do a rebuild, I get a failure because it cannot fie a file called mouhidlib.h so I copied that file from \WINCE600\PUBLIC\COMMON\OAK\DRIVERS\USB\CLASS\HID\CLIENTS\MOUHID\INC into the BSP\SRC\DRIVERS\MOUHID folder...sound correct?
I do another rebuild and it does compile sucessfully. So that is good. Testing opened the door to another set of problems, but before that I wanted to make sure I could still do a full compile(clean sysgen), just as I could right before I made these changes/additions.
BUT now when I perform a 'clean sysgen' I get a faulure. In the last entires in the build.log file I see:
Microsoft (R) COFF/PE Editor Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.nmake /NOLOGO C:\WINCE600\OSDesigns\LP8_CM_X300\Wince600\CM_X300_BSP_ARMV4I\cesysgen\oak\target\ARMV4I\retail\mouhid.dll
makefile.def: Invoked with predefined settings:
TARGETNAME: mouhid
TARGETTYPE: DYNLINK
RELEASETYPE: OAK
TARGETLIBS: C:\WINCE600\public\common\oak\lib\ARMV4I\retail\mouhidbase.lib C:\WINCE600\OSDesigns\LP8_CM_X300\Wince600\CM_X300_BSP_ARMV4I\cesysgen\oak\lib\ARMV4I\retail\hidparse.lib C:\WINCE600\public\common\oak\lib\ARMV4I\retail\MouHidStd.lib C:\WINCE600\OSDesigns\LP8_CM_X300\Wince600\CM_X300_BSP_ARMV4I\cesysgen\sdk\lib\ARMV4I\retail\coredll.lib
SOURCELIBS:
DEFFILE: C:\WINCE600\public\common\oak\lib\ARMV4I\retail\mouhid.def
EXEENTRY: WinMainCRTStartup
DLLENTRY: _DllEntryCRTStartup
makefile.def: Including C:\WINCE600\public\common\oak\misc\Sources.default
makefile.def: BUILDROOT is C:\WINCE600\public\common\cesysgen
makefile.def: Including C:\WINCE600\PUBLIC\COMMON\CESYSGEN\sources
makefile.def: Including C:\WINCE600\public\common\oak\misc\Sources.CE
Directory: C:\WINCE600\PUBLIC\COMMON\CESYSGEN
TARGETNAME: mouhid
makefile.def: Including C:\WINCE600\public\common\oak\misc\sources.ReleaseType_OAK
NMAKE : fatal error U1073: don't know how to make 'C:\WINCE600\public\common\oak\lib\ARMV4I\retail\mouhid.def'
Stop.
NMAKE : fatal error U1077: 'C:\WINCE600\sdk\bin\i386\nmake.exe' : return code '0x2'
Stop.Even after I 'exclude' MOUHID from the build I now get this same error. How do I get things back the same...like before adding the new MOUHID folder? I performed a 'clean sysgen' before making any of these changes and the 'clean sysgen' worked fine. How does it think it now needs to make 'C:\WINCE600\public\common\oak\lib\ARMV4I\retail\mouhid.def' but can't find it?
Even when I delete all that I think I added(just the MOUHID folder), I still fail the 'clean sysgen'. Fortunately I also made a backup copy of the WINCE600 folder, so I'm going back to that and try again.
Appriciate any suggestions/comments...thanks.
-
Tuesday, July 24, 2012 10:46 PM
From the above it looks like you didn't modify the sources as per my instructions. The build is still trying to get the def file from the public common folder.
Make sure the sources file is EXACTLY like I showed you (so NO PREPROCESSDEFFILE, NO WINCETARGETFILE0, etc).
Copying the mouhidlib.h file was correct, and adding to the dirs file is logical.
If you've followed my instructions to the letter you should be able to do a clean sysgen (blddemo clean -q) without any problems.
Also note that a clean sysgen is overkill and a time waster. Read and understand everything in http://guruce.com/blogpost/what-to-build-when so you can build more intelligently...
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services.
- Edited by Michel VerhagenMVP Tuesday, July 24, 2012 10:46 PM
- Edited by Michel VerhagenMVP Tuesday, July 24, 2012 10:48 PM
-
Tuesday, July 24, 2012 11:21 PM
Thanks...I'll start again and be more careful. I sometimes do a 'clean sysgen' just to make sure I have't screwed something up somewhere in my array of modifications. I start it at the end if the day so everything is completed in the morning.
Oddly when I 'excluded from build' the MOUHID folder, then deleted the MOUHID folder I created, I still get the same error on a 'clean sysgen'. I did exit out of VS2005 before deleteing the MOUHID folder.
I guess I am wondering how does one correctly undo's these changes. My guess would be to just make the MOUHID folder 'excluded from build'.
Thanks.
-
Tuesday, July 24, 2012 11:32 PMYou sure you did not do a "build and sysgen"? (that's EVIL, so don't ever do that, see this http://guruce.com/blogpost/how-to-remove-the-demonic-build-and-sysgen-commands-from-platform-builder-for-windows-embed)
The changes you made should not cause any of the problems you are reporting...Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services. -
Tuesday, July 24, 2012 11:56 PMNO...I deleted those two commands(build and sysgen) and (Rebuild and Clean SYSGEN) first thing out of the build selection many many months ago when I first installed VS2005 and Platform Builder.
-
Wednesday, July 25, 2012 12:30 AMAnd you are sure you did not change the sources file in the PUBLIC tree by accident?
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services. -
Wednesday, July 25, 2012 7:09 PM
The honest answer is I don't know. Obviously I did something wrong. I had made a full backup of everything before the change so I have restored to that previous version so whatever changes I did no longer exists.
I made the changes again and it all compiled and passed even when doing a 'clean sysgen'.
I realize that I am still in quite a steep learning curve mode so I really appricate your help and patience.
With this cloning sucess I'll try to get back to topic.
Lets look at the mouhid.cpp source code itself.
The first dumb question I have is: How do I determine if this thing is compiled in DEBUG, and how do I enable the code to be in DEBUG....My guess is that I just need to enter a line:
#define DEBUG 1
at the beginning of the code...is that correct? Or is DEBUG defined/enabled if I build the Solutions Configuration as Debug instead of Release?
What in the world is the command PREFAST_DEBUGCHK() vs just DEBUGCHK() and why is it being used instead of just DEBUGCHK?
I see in the code:
#ifdef DEBUG
static
void
ValidateHidMouse(
PHID_MOUSE pHidMouse
);
#else
#define ValidateHidMouse(ptr)
#endif // DEBUGand
#ifdef DEBUG
// Validate a PHID_KBD structure
static
void
ValidateHidMouse(
PHID_MOUSE pHidMouse
)
{
.
.
.
}
#endif // DEBUGSince I am not in DEBUG(I guess) then the ValidateHidMouse() routine in the mouhid.cpp file is not generated, so where/what is the ValidateHidMouse routine? What does it do?
-
Thursday, July 26, 2012 1:30 AM
is DEBUG defined/enabled if I build the Solutions Configuration as Debug instead of Release?
Correct.
As for your other questions; start new "question" (not "discussion") threads per question you have. You'll have more chance to get an answer and it allows people to easier find your questions and answers if they encounter the same.
To answer your questions you must simply browse the code and understand it. I can't do your job for you, sorry!
I am (and many others are) more then happy to answer any specific questions you may have, but you have to put in some research yourself as well.
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services. -
Thursday, July 26, 2012 3:48 PMUnderstood. All the information provided by you and others is truely extremely valuable.
-
Friday, August 03, 2012 6:53 PM
Greetings: Well I did acomplish my goal. Just wanted to show everyone what I did.
I cloned the MOUHID.CPP file per Michel's instructions from above.(I still don't quite understand all the why's of what is being done but it did work.)
In the mouhid.cpp file I added the following:
I added the header file:// CMC via PGT: Get the GUID for the mouse device class that we will
// advertise when the mouse is detected.
#include "devclassmouse.h" (Contents shown below)In the routine called HIDDeviceAttach() which executes when I plug in a USB mouse, I added the following right after the DetermineWheelUsage(pHidMouse) routine.
errloop = 0;
{
GUID devclass = DEVCLASS_MOUSE_GUID;
if ( AdvertiseInterface( &devclass, _T( "USBMouse" ), TRUE ) )
{
RETAILMSG( 1, ( TEXT( "USBMouse::HidDeviceAttach - Successfully advertised interface %s.\r\n" ), DEVCLASS_MOUSE_GUID_STRING ) );
RETAILMSG(1,(TEXT("=================================================\r\n")));
}
else
{
// Sometimes when I first plug in a USB mouse the command would fail and this is how I fix it. while (errloop < 10)
{
Sleep(1000);
if ( AdvertiseInterface( &devclass, _T( "USBMouse" ), FALSE ) )
{
}
else
{
Sleep(1000);
if ( AdvertiseInterface( &devclass, _T( "USBMouse" ), TRUE ) )
{
errloop = 11; // I know, not the right way to break out of a loop.
}
else
{
errloop++;
}
}
}
}In the routine called HIDDeviceNotifications(), which executes whenever I unplug the USB mouse, I added the following:(Between the MouseEvent(dwFlags, 0, 0, 0); and FreeHidMouse(pHidMouse); in HID_CLOSE_DEVICE)
GUID devclass = DEVCLASS_MOUSE_GUID;
if ( AdvertiseInterface( &devclass, _T( "USBMouse" ), FALSE ) )
{
RETAILMSG( 1, ( TEXT( "USBMouse::HID_CLOSE_DEVICE...HIDDeviceNotifications - Successfully deadvertised interface %s.\r\n" ), DEVCLASS_MOUSE_GUID_STRING ) );
}
else
{
RETAILMSG( 1, ( TEXT( "USBMouse::HID_CLOSE_DEVICE...HIDDeviceNotifications - AdvertiseInterface failed %s. Err = 0x%x.\r\n" ), DEVCLASS_MOUSE_GUID_STRING, GetLastError() ) );
}=====================================
In the display driver for our device(which I am told is differet between CPU modules used) I did the following to
turn on or off the mouse curser(pointer?)////////////////////////////////////////////////////////////////////////////////////////////
// CMC
//#define CMC_DEBUG 1
#include <pnp.h>
int SetCursorOn = -1;
DWORD CursorCheckMousePresent( LPVOID lpParameter );
( Where the following goes would depend on your display driver code I suppose)
// CMC: Start a thread to monitor for mouse device arrivals and departures.
HANDLE thH;
if ( ( thH = CreateThread( NULL, 0,
CursorCheckMousePresent, NULL,
0, NULL ) ) != NULL )
{
#ifdef CMC_DEBUG
RETAILMSG( 1, ( TEXT( "SA2Video() - CursorCheckMousePresent Thread creation successful.\r\n" ) ) );
#endif
CloseHandle( thH ); // CMC: We don't need to keep this.
}
else
{
RETAILMSG( 1, ( TEXT( "SA2Video() - CursorCheckMousePresent Thread creation error!!! Error = 0x%x\n" ), GetLastError() ) );
}=============================================================================
(And here is the thread I added at the end of the dislay driver source code file.)
// CMC...Thread to monitor if USB mouse is connected or not.
/*
When a mouse gets plugged in, the HIDDeviceAttach routine executes
and advertises that there was an attachment.This advertisement will be received by this routine.
The keyboard chip we are using triggers the HIDDeviceAttach routine about
a USB mouse being attached when the unit first boots, even if there is
USB mouse attached. The keyboard chip an accept a PS/2 mouse and I
suspect that by default the keyboard chip always indicates that a USB mouse
is connected.When a real USB mouse is actually plugged in or is already plugged in another HIDDeviceAttach executes.
BUT the first time a real USB mouse is plugged in, the AdvertiseInterface
routine always fails!To solve this I perform find I must perform a AdvertiseInterface(FALSE)
message, then perform another AdvertiseInterface(TRUE) message which
always then works.(See code in cloned mouhid.cpp)An Advertiseinterface(FALSE) is seen as a USB mouse being removed, so the
trick is to figure out a way to know if there is really a USB mouse
plugged in when the unit first boots or when a USB mouse is first
plugged in.I found I was unable to execute the actual routine that turns the mouse cursaor on or off difrect from this thread
so I had to do this with a global variable called SetCursorOn. In the routine called CursorOn() I found I could see the SetCursorOn variable in the CursorOn() routine, so if SetCursorOn is set to 1(one), the CursorOn() does whatever it does to turn on the cursor, otherwise I have it call the CursorOff() routine.With no real USB mouse attached at power up:
Initally, SetCursorOn is set to -1.
When the unit first boots and there is no USB mouse attached, SetCursorON
will get incremented from the phantom USB mouse generate by the our goofy keyboard
chip to a value of 0(zero). With SetCursorOn set to 0(zero) the mouse
cursor will not be displayed.When a USB mouse is plugged in, the AdvertiseInterface(TRUE) message always
fails(don't know why), and I have to perform a AdvertiseInterface(FALSE) and then another
AdvertiseInterface(TRUE). The AdvertiseInterface(FALSE) is seen as a command
that the USB mouse has been removed, but ONLY decrements the SetCursorOn
value if it is greater than 0(zero). The AdvertiseInterface(TRUE), which will
now work, then increments the SetCursorOn value to a 1(one). From then
on the SetCursorValue will increment or decrement with a USB mouse is
inserted or removed. With no USB mouse attached, SetCursorOn will alway be 0(zero) or a value equal to the number of USB mice attached(I guess you could plug in more than one).With a real USB mouse attached at power up:
Initally, SetCursorOn is set to -1.
When the unit first boots, SetCursorON will get incremented from the
phantom USB mouse generated by the keyboard chip to a value of 0(zero).With the real USB mouse attached the first AdvertiseInterface(TRUE) message
always fails, and I have to perform a AdvertiseInterface(FALSE). Since
an AdvertiseInterface(FALSE) is an indication of the mouse removed BUT
the SetCursorOn value is at 0(zero), the SetCursorOn value
will not get decremented and when the AdvertiseInterface(TRUE)is
then executed, the SetCursorOn value will get incremented to 1(one).From then on, the SetCursorOn Value will increment or decrement when a
USB mouse is inserted or removed.*/
DWORD CursorCheckMousePresent( LPVOID lpParameter )
{// Create a message queue to get the notifications when devices
// appear or disappear.
MSGQUEUEOPTIONS opts;
DWORD who = 0;
int loopcnt = 0;opts.dwSize = sizeof( opts );
opts.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opts.dwMaxMessages = 0; // No limit.
opts.cbMaxMessage = MAX_DEVCLASS_NAMELEN; // Should work for anything.
opts.bReadAccess = TRUE;
HANDLE msgQ = CreateMsgQueue( _T( "CursorCheckMousePresent" ), &opts );
if ( msgQ )
{
#ifdef CMC_DEBUG
RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: created message queue...loopcnt=%d\r\n" ), loopcnt ) );
#endif
// Ask for device notifications to be sent. Note that we set the
// last parameter to true to indicate that we want notifications
// for devices already connected.
HANDLE notH = RequestDeviceNotifications( NULL, msgQ, TRUE );
if ( notH )
{
// RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: requested device notifications.\r\n" ) ) );
// while ((( who = WaitForSingleObject( msgQ, 5000 )) != WAIT_FAILED ) && (loopcnt < 100))
while (( who = WaitForSingleObject( msgQ, INFINITE )) != WAIT_FAILED )
{
// RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: WaitForSingleObject loop....%d\r\n" ), ++loopcnt));
if ( who == WAIT_OBJECT_0 )
{
// Get the DEVDETAIL structure from the queue.
BYTE detail[ MAX_DEVCLASS_NAMELEN ];
DWORD flags = 0;
DWORD xcount;
if ( ReadMsgQueue( msgQ, &detail, sizeof( detail ), &xcount,
0, &flags ) )
{
DEVDETAIL *devdetail = (DEVDETAIL*)&detail;
// RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: Got a notification message for...%s...%d...%s...\r\n" ),
// devdetail->szName,
// devdetail->fAttached,
// ( devdetail->fAttached ? _T( "Attached" ) : _T( "Removed" ) ) ) );
if (wcscmp(devdetail->szName,TEXT("USBMouse")) == 0)
{
RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: Notification for...%s...%d...%s...\r\n" ),
devdetail->szName,
devdetail->fAttached,
( devdetail->fAttached ? _T( "Attached" ) : _T( "Removed" ) ) ) );
if (devdetail->fAttached == 1)
{
SetCursorOn++;
RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: SetCursorOn=%d\r\n" ), SetCursorOn));
}
else
{
if (SetCursorOn > 0)
SetCursorOn--;
RETAILMSG( 1, ( TEXT( "CursorCheckMousePresent: SetCursorOn=%d\r\n" ), SetCursorOn));
}
}
// LPOLESTR guidString;
// StringFromCLSID( devdetail->guidDevClass, &guidString );
// RETAILMSG( 1, ( TEXT( "MouseCursorTest: GUID = %s.\r\n" ),
// guidString ) );
// CoTaskMemFree( guidString );
}
else
{
RETAILMSG( 1, ( TEXT( "MouseCursorTest: ReadMsgQueue got no message. Exiting...\r\n" ) ) );
// break;
}
}
}
}
}
return 0;
}The devclassmouse.h contains:
#pragma once
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */#define DEVCLASS_MOUSE_GUID_STRING TEXT("{FFBE5A05-87B4-4591-B067-CEBA6FAFD298}")
#define DEVCLASS_MOUSE_GUID { 0xFFBE5A05, 0x87B4, 0x4591, { 0xB0, 0x67, 0xCE, 0xBA, 0x6F, 0xAF, 0xD2, 0x98 } }#ifdef __cplusplus
}
#endif /* __cplusplus */ -
Friday, August 03, 2012 9:36 PM
Chulk,
Instead of using AdvertiseInterface for this you could also just use 2 named events; one for attach and onve for detach. This will always work and makes your code a lot easier.
Good luck,
Michel Verhagen, eMVP
Check out my blog: http://guruce.com/blog
GuruCE
Microsoft Embedded Partner
http://guruce.com
Consultancy, training and development services. -
Friday, October 12, 2012 5:58 AM
Thanks for the thread guys, this was exactly what I was looking for!
I followed Michel's advice and used named events:
Just after DetermineWheelUsage(pHidMouse) :
// set event for mouse attach to enable the cursor pHidMouse->hAttachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseAttached"); if (pHidMouse->hAttachEvent != NULL) SetEvent(pHidMouse->hAttachEvent);
and Between the MouseEvent(dwFlags, 0, 0, 0); and FreeHidMouse(pHidMouse);
// set event for mouse attach to disable the cursor pHidMouse->hDetachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseDetached"); if (pHidMouse->hDetachEvent != NULL) SetEvent(pHidMouse->hDetachEvent);
Then in the display driver in the init function:
m_hAttachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseAttached"); m_hDetachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseDetached"); m_MouseDisabled = true; m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThread, NULL, 0, NULL);
The thread:DWORD MouseEventThread(void) { DWORD rc = TRUE; HANDLE handles[2]; handles[0] = m_hAttachEvent; handles[1] = m_hDetachEvent; for(;;) { switch (WaitForMultipleObjects(2, handles, FALSE, INFINITE)) { // m_hAttachEvent case WAIT_OBJECT_0 + 0: m_MouseDisabled = false; CursorOn(); break; // m_hDetachEvent case WAIT_OBJECT_0 + 1: m_MouseDisabled = true; CursorOff(); break; default: rc = FALSE; return rc; } } }Cheers!!
- Edited by Barak14 Friday, October 12, 2012 6:00 AM typo

