As expected, the two extra buttons on all mice send XBUTTON1 and XBUTTON2 messages. However with a Sculpt ergonomic mouse, the Windows button does not send this. Apparently it sends the right Windows key. I need to fix it so that it sends XBUTTON2.

I was able to disable the Windows button from doing anything by following this: Rebind Microsoft Sculpt Mobile Mouse (Windows Key) - but this disables the Windows button on the mouse completely and doesn't make it function as normally as on all other five button mice. It should send XBUTTON2.

However I need it to function as XBUTTON2.

Here is a detailed explanation:

I am a software developer. I bought the Sculpt ergonomic mouse because it has five buttons (and horizontal scroll), so it can allow me to test all the button messages. It especially helps with keeping me comfortable while I type/mouse away.

The button messages are seen here for mouse hook: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644986.aspx

The mouseData field is set according to the mouse button:

  • Pressing the left mouse button sends message: WM_LBUTTONDOWN
  • Right mouse button: WM_RBUTTONDOWN
  • Middle mouse button: WM_MBUTTONDOWN
  • Side mouse button: WM_XBUTTONDOWN and we see in the MSLLHOOKSTRUCT structure: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644970.aspx?f=255&MSPPError=-2147217396 - that mouseData field is XBUTTON1
  • Now the issue - Windows mouse button is sending nothing - I am expecting it to send message WM_XBUTTONDOWN with mouseData of XBUTTON2 (notice the 2)

Here is a graphic to explain the bullet points:

enter image description here

The green arrow and text cloud shows thats how it is, and thats what I expect. The red arrow and text cloud is what I expect the windows mouse button to do, but it doesn't. Anyone can help me make this windows mouse button work as expected from a winapi standpoint?

  • 1
    Since this is probably happening at the hardware level, your best bet (short of writing a custom driver) would be using one of the standard key remapping methods to remap the right windows key to the desired mouse button press. You can do the remapping via the registry (tools available) or a user-mode program like AHK - look for one of the existing questions. – Bob Nov 13 '15 at 6:22
  • Thanks @Bob, is the current driver out there open source? Maybe I could modify it? (Because I have another issue, in tilting the scroll wheel right/left, instead of sending ONE scroll event to the left/right, it keeps sending while tilted - unlike when you scroll up/down, it sends one event in up or down dir) – Noitidart Nov 13 '15 at 6:31
  • Also @Bob do you know if AutoHotkey remaps via registry? I don't want to use something like X-Mouse Button Control (XMBC) because that just installs a mouse hook, intercepts it and sends it out, and it actually is not a remap, it actually doesnt even realize Im hitting the 5th button. – Noitidart Nov 13 '15 at 6:44
  • 1
    If the mouse hardware is sending out the repeating signals, there really isn't much you can do about it. Perhaps with AHK you could do something that simulates a button down on the first press and a button up only if there's been X seconds since the last press, but that's hacky at best. As for XMBC - there's nothing wrong with a mouse hook, but the "5th button" wouldn't work there because the mouse is probably pretending to be a keyboard - as far as the computer is concerned you have separate mouse and keyboard devices connected to the same USB port. – Bob Nov 13 '15 at 7:04
  • 1
    Assuming the repeats are implemented on the hardware side (and not a special driver from MS themselves). For the most part, it would not be any different from using a userspace program like AHK, since the actual method you use to detect the repeats would be similar. Only in special circumstances - where the program you're interacting with is on a lower level than what AHK hooks - would you see a difference. So most of the time it's a lot of work for little gain. – Bob Nov 14 '15 at 2:56

Listening to the “WIN” key

As far as I understand, the only reason why you may not see the any events coming from the “WIN” mouse key is that you’re only looking on mouse-related events, while there “WIN” key produce keyboard-related “Right-Win” keystroke. Effectively, this part was already discussed in comments – the “Right-Win” remapping perfectly works.

Repeatedly sent RWin events

I can confirm that it sends events repeatedly. AFAIK, every keyboard key works like this – e.g. “F2”. At least the following AHK trick shows effectively the same for both "F2" and "RWin", as far as I can tell.


The good thing abouht the “WIN” key is that it's mechanically able to produce single keystrokes. In contrast to wheel tilts – it’s quite hard to get a “single click” from them – even my shortest click is typically treated as 3-5 separate keystrokes.

Listening to the wheel tilt keys

The “Microsoft Mouse and Keyboard center” (version seem to change the behavior of the mouse - the AHK is no longer able to hear WheelRight/WheelLeft events. The easiest way to fix this is to uninstall the Microsoft's tool. Though, according to my experiments, it does not affect the "WIN" key.

However, it should still be possible to remap the wheel tilts even without uninstalling it. By using the AHKHID examples 1 and 2 I was able to catch 1FFDFF and 1F0300 "data" from right and left wheel tilts, using UsagePage 12, Usage 1 with “Microsoft Mouse and Keyboard center” installed, and nothing after I've uninstalled it.

Repeatedly sent wheel tilt events

Personally, I ended up simply introducing a delay, as suggested by Bob. It looks like the most simple code, based on the code in this question works OK in this case (though it might be not optimal - I'm not an expert in AHK). The following AHK script allows me to remap Wheel-tilt-Left to "Ctrl+Alt+leftArrow" and Wheel-tilt-Right to "Ctrl+Alt+rightArrow". I use these hotkeys in VirtuaWin to switch to previous/next virtual desktop (a task, where "one response per click" is quite important), and it works perfect. (Still, If I press-and-hold the "tilt button", I get ~5 events per second).

    if(  not GetKeyState("WheelRight")  )
        sleep 200    

    Send, {LControl down}
    Send, {LAlt down}
    Send, {right}
    Send, {LControl up}
    Send, {LAlt up} 

    if(  not GetKeyState("WheelLeft")  )
        sleep 200

    Send, {LControl down}
    Send, {LAlt down}
    Send, {left}
    Send, {LControl up}
    Send, {LAlt up}

    Send, {Browser_Forward}

RWin works OK even without this trick.

  • Thanks so much for this reply, I have still been stuck on it :( It's not the perfect solution but its all we can get so I have accepted it. Thanks for it! – Noitidart May 12 '16 at 21:01

Timers are ideal to reduce repeating events to a single action. Every time we receive a repeated key/click, we reset the timer interval, so the action won't happen until we finally release the key/button.

I use this script with the wheel tilt:

; Prevent warning if we hold a button too long
#MaxHotkeysPerInterval 200

~MButton & WheelRight::
    SetTimer ArrangeWindowRight, -50

~MButton & WheelLeft::
    SetTimer ArrangeWindowLeft, -50

    Send #{Right}

    Send #{Left}

So ArrangeWindowRight and ArrangeWindowLeft are only called 50ms after I release the tilt (note the negative sign in the timer interval, to have it run only once; without it, the function would be called again and again).

As for i3v's code, at first sight it seems to me all it does is slow down the last repeated event (sleep 200 if wheel is not pressed anymore), so I'm left wondering what was the improvement there. Also, you can reduce the five sends to Send ^!{Right}.


  • Thank you very much Chema for sharing this! I still haven't got a solution till today. I will try out this AHK script! :) – Noitidart Mar 18 '17 at 1:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.