none
GetKeyState recently fails for VK_SHIFT

    Question

  • I have a Windoes Forms application that uses toolbar buttons with click handlers. For some of these buttons, there's an alternate meaning if the Shift key is pressed while clicking the button. This has always worked. The last time I know it did was on 16 November. Today it doesn't work anymore. I suspect some Windows update has broken that functionality.

    Here's some of my code:

    private void AddToolbutton_Click(object sender, EventArgs e)
    {
    	if (WinApi.GetKeyState(WinApi.VK.SHIFT) < 0)
    	{
    		...
    	}
    }
    
    [DllImport("user32.dll")]
    public static extern short GetKeyState(VK nVirtKey);
    
    public enum VK: short
    {
    	SHIFT = 0x10
    }


    The function now always returns 0, no matter how the key is pressed.

    Can somebody explain me what's going wrong here?

    Wednesday, December 25, 2013 8:23 PM

All replies

  • Use one of the key events that includes the control keys.
    Wednesday, December 25, 2013 11:07 PM
  • Is there a Click event that tells me about keys pressed? On a ToolButton? Anyway, why does that function fail now? It has always worked fine. Somebody must have broken it, I didn't touch that code in years.
    Thursday, December 26, 2013 11:28 AM
  • Is there a Click event that tells me about keys pressed? On a ToolButton? Anyway, why does that function fail now? It has always worked fine. Somebody must have broken it, I didn't touch that code in years.
    No Click event.  Use a key event that includes the control keys.
    Thursday, December 26, 2013 1:14 PM
  • What should I do with a key event? I need to react on the click event, and do one thing if no key is pressed simultaneously, and another thing if the Shift key is pressed. And I need to do it in the moment the button is clicked. What are you suggesting me? Examples please.
    Thursday, December 26, 2013 3:46 PM
  •  It has always worked fine. Somebody must have broken it, I didn't touch that code in years.

    I thought you might be interested in getting your program to function again.  To determine why your code fails, I'd investigate the timing of the code.  I wouldn't expect a winAPI method to be precisely timed to a .NET Click event.

    "On a ToolButton?"

    What's a "ToolButton"?  Searching Help returns nothing.


    • Edited by JohnWein Thursday, December 26, 2013 3:58 PM
    Thursday, December 26, 2013 3:55 PM
  • Does it work in case of new projects, or on other computers?

    Check this, instead of GetKeysState:

    if( ( ModifierKeys & Keys.Shift ) != 0 )
    {
        . . . .
    }
    

    • Proposed as answer by JohnWein Thursday, December 26, 2013 10:08 PM
    Thursday, December 26, 2013 9:40 PM
  • The Control.ModifierKeys Property help entry has an example for a button click event.
    Thursday, December 26, 2013 10:10 PM
  • Its full name is ToolStripButton.

    The ModifierKeys thing works. But what does GetKeyState then do, if it doesn't get me the key state in the moment I'm calling it?

    My use case is this:

    1. Press Shift key

    2. Click that button

    3. Something happens

    4. Release Shift key

    Step 3 opens one or another dialog window. So the action is executed while the Shift key is pressed. My only valid conclusion is then that GetKeyState doesn't consider the Shift key pressed while it is. This is normally a precise description of a failing Windows API function. Any other ideas? GetKeyState's documentation doesn't describe any exceptions.

    Friday, December 27, 2013 9:40 AM
  • Time the Click event and the release of a key.  A key can easily be released long before the logic can indicate that a Click event occurred and not a DoubleClick event.
    Friday, December 27, 2013 11:26 AM
  • What are you talking about? I don't understand you.

    DoubleClick is entirely unrelated here, I only click once. And still I cannot follow your idea of timing. Following my steps above, timing cannot be an issue here at all.

    Anybody else got some ideas?

    Friday, December 27, 2013 11:43 AM
  • "DoubleClick is entirely unrelated here, I only click once."

    You should study the Windows messaging system.  How does the .NET logic know that you only clicked once, if it doesn't wait long enough to eliminate the possibility that you clicked twice?  Are 2 clicks, 2 clicks or a doubleclick?

    Friday, December 27, 2013 11:53 AM
  • You should, after having studied it, try it out. The Click event is raised immediately after releasing the mouse button. The DoubleClick event is only raised then after the second click.

    And if you had read my description above, you wouldn't post such nonsense (sorry). The Click action is executed, I can see it because the dialog window opens. The same method that opens the dialog first checks the Shift key to decide on WHICH dialog actually should be opened. So how can you say that timing could be wrong here?

    Why does everybody assume the most possible complex and unknown code, if the simplest and easiest would be more obvious, and easier to answer to? When I don't mention something, it's most likely because it's too simple and common to mention it. If it would be complex and unusual, I'd tell about it. Probably forums are not a helpful place anymore these days.

    Friday, December 27, 2013 12:26 PM
  • According to documentation, GetKeyState seems to be applicable when you process a keyboard-input message. It does not necessarily work in case of mouse events, or in case of Click events specific to .NET. You can try GetAsyncKeyState instead.

    Friday, December 27, 2013 4:57 PM
  • No, GetAsyncKeyState does not work either.

    Can anyone please unmark the answer again, this forum is still a bunch of disfunctional crap! Sorry, but it's true. It has never worked reliably since it's been published.


    • Edited by LonelyPixel Saturday, January 11, 2014 2:15 PM
    Saturday, January 11, 2014 2:15 PM
  • If you are still interested in a solution, then maybe you prepare a short project that easily reveals the problem, so that it will be possible to test it in different environments and identify the issue.

    Saturday, January 11, 2014 8:29 PM
  • I can't provide a testcase because all three methods work as expected in a simple application. Must be random Windows quirks that you just have to face every now and then, and nobody can fix it. At least one method still works reliably (Control.ModifierKeys).

    Sunday, January 12, 2014 8:17 PM
  • Then, if you want to contribute, you can provide your whole or truncated project instead of a testcase that is difficult to make.

    Sunday, January 12, 2014 9:02 PM