Missing GetKeyState(0) Return

I have a panel hook that captures keystroke events looking for command-shift on Mac or control-shift on Windows. I am not getting a response that I would expect from GetKeyState(0) on Windows XP Igor 6.2.2.2. With the shift key down, it returns 4. However, I get no response with the control key down by itself, nor with both the control and shift keys down. My Windows keyboard works because control-L opens the file load dialog box. On the Mac, the combination command-shift is captured.

Am I missing something in this ??? ....

Function PanelHook(whs)
   ...

    switch(whs.eventCode)
          case 11:
              et = GetKeyState(0)
              print et
              if ((et&4) && (et&1))
                // handle command-shift Mac or control-shift Windows
                ...
              endif
              break
     endswitch
     return 0
end

This works correctly on my Macintosh and on Windows 7 running on Macintosh under VMWare:
Function Test()
    #ifdef MACINTOSH
        Print "Press shift and command to continue"
    #else
        Print "Press shift and control to continue"
    #endif
   
    do
        Variable keys = GetKeyState(0)
        if ((keys & 0x05) == 0x05)
            Print "Done"
            break
        endif
    while (1)  
End


I'm not sure that just pressing the control key sends a keyboard event to hook functions. Perhaps the problem is not with GetKeyState but rather that your hook function is not called with eventCode==11.



hrodstein wrote:
... I'm not sure that just pressing the control key sends a keyboard event to hook functions. Perhaps the problem is not with GetKeyState but rather that your hook function is not called with eventCode==11.


In reality, the behavior is a bit more involved than just inputting the modifier keys themselves.

On Macintosh ...
I input a command+shift+= and get a proper capture from the panel hook of the eventCode 11 with further notice that command and shift are held down.

On Windows
I input shift+ANYTHING and I get a keyboard input event capture with et = 4
I input control+ANYTHING and get NO keyboard input event capture
I input control+shift+ANYTHING and also get no keyboard input event capture

So, on the Mac, the panel hook responds to the keyboard event (input keystroke "=") and then recognizes the modifiers are pressed ... this is the behavior that I want. On Windows, the panel hook ONLY responds to the keyboard event (input keystroke "=") when the shift key is down. When the control key is down, the keystroke event (input of "=" key) seems to be eaten up somewhere upstream before it reaches the panel hook.

The specific code is in the LogBook package under the PanelHook() function if you would want to investigate further.

In the meantime, I'll consider restructuring the panel hook code to adjust for this discrepancy ... I was hesitant to tie up the processing otherwise by always doing a GetKeyState(0) call even during an idle of the hook. Suggestions would be appreciated.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
I have never been able to get Ctrl-special (where special is period, comma, equals, +, -, i.e., anything other than letters and numbers) to work on Windows. I'm not sure this type of event even gets to Igor.
hrodstein wrote:
I have never been able to get Ctrl-special (where special is period, comma, equals, +, -, i.e., anything other than letters and numbers) to work on Windows. I'm not sure this type of event even gets to Igor.


Oh! Indeed, based on my testing, keystrokes for any combination of control-KEY or alt-KEY keystrokes seem never to activate the eventCode = 11 hook function check either. They appear to get gobbled (to use LaTeX parsing jargon) by the OS.

Perhaps a note as such should go in the help and manual for GetKeyState(...) pertaining to this difference:

When testing for keystroke events, recognize that Windows mostly (if not exclusively) behaves as though it captures any keystroke that is pressed with control or alt key modifiers regardless of whether that keystroke is used by the OS or not, whereas the Macintosh OS passes that keystroke (and the corresponding modifiers) through when it does not otherwise use it. Therefore, a test for eventCode = 11 in a window hook event will (most certainly) never respond on Windows when the user also presses the control or alt keys regardless of what other key is pressed, whereas that same test could respond on the Macintosh as long as the total input keystrokes are not otherwise used by the OS.

(another reason you have sometimes just got to love how the Mac works)

I will have to set up my hook event correspondingly in my coding.

Thanks!

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
After reading this I was afraid that my code stopped working where I use the exact same thing of eventcode 11 and getkeystate(0) to handle ctrl+arrow keys. But after rechecking I can tell you that my code gets every event even with ctrl pressed or shift + ctrl pressed together. I'm using Windows XP + Igor 6.2.2.2 by the way.

I have my code running on two other Win XP machines and two Win 7 ones, but as far as I remember I had never any problems with this. If you want to post some test code I can test it here and at least tell you if it works on my system. Not that this would help much, but anyway.
chozo wrote:
After reading this I was afraid that my code stopped working where I use the exact same thing of eventcode 11 and getkeystate(0) to handle ctrl+arrow keys. But after rechecking I can tell you that my code gets every event even with ctrl pressed or shift + ctrl pressed together. I'm using Windows XP + Igor 6.2.2.2 by the way.


Is your test within a window hook function? What order do you do the test ... getkeystate(0) first or second?

Download and install the LogBook package that I recently posted. Open a new experiment and #include "LogBook". Create a new notebook and make a graph (make/n=100 test; display test). Open the LogBook panel from Misc:Panels menu. Type some text in the bottom note field. While you are still active in the note field, hit control+shift+=. That should act to send the contents of the LogBook panel to the notebook.

I'd appreciate if you can let me know what you find.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
Ok, I have tested this and some other stuff. Your key command doesn't work on my system either. That's because some key combinations won't work the usual way it seems. Apparently there are only some keys which can be used together with ctrl and ctrl+shift (and there seem to be even different sets of keys for each case). The positioning keys (arrow keys, home, etc.) are useable as in my case. Ctrl+shift+"=" is not.
I took a look at the eventcodes and instead of an 11 it turns out as a 9 ("enablemenu", whatever that means).

I have quick-hacked a 'case 9' with similar contents as for 'case 11' into your hook function. I check for '0' (keycode = 48), because somehow this doesn't turn out as a '='. But whatever, it works as intended (possible collateral damage due to case 9 check not considered, though).
As Howard mentioned previously, Windows (for whatever unknown reason) doesn't support Ctrl+[punctuation] as an accelerator key combination. I can't say that this is true of all punctuation, but it is at least true for many types. That's why on Windows we haven't implemented Ctrl+] and Ctrl+[ as accelerator keys to adjust indentation. On Windows we were forced to the rather unsatisfying Ctrl+R and Ctrl+L.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
That's why on Windows we haven't implemented Ctrl+] and Ctrl+[ as accelerator keys to adjust indentation. On Windows we were forced to the rather unsatisfying Ctrl+R and Ctrl+L.


John,

As unsatisfying as the latter may be, at least I can remember it; I probably wouldn't be able to say the same for the former. And almost every time I manage to remember to use Ctrl+R or L, I get a little self-congratulatory puff of dopamine wafting through my brain. Times are tough. : )
This implementation works to capture command+shift+= on Mac or control+shift+= on Windows in a panel hook ...

Function PanelHook(whs)
    STRUCT WMWinHookStruct &whs
   
        ...

    switch(whs.eventCode)
        case 0: // activate
                        ...
            break          
#ifdef Macintosh
        case 11:    // keyboard input
            et = GetKeyState(0)
            if ((et&4) && (et&1))
                switch(whs.keycode)
                    case 61:    // = key Macintosh
                        ...
                        rtnV = 1
                        break
                endswitch
            endif
            break
#endif
#ifdef Windows
        default:
            et = GetKeyState(0)
            if ((et&4) && (et&1))
                switch(whs.keycode)
                    case 187:   // = key Windows
                        ...
                        rtnV = 1
                        break
                endswitch
            endif
            break
#endif
    endswitch
   
    return rtnV
end


Ultimately, I could dispense with the eventCode=11 check all together and just do a whs.keyCode = 61 (Mac) or whs.keyCode = 187 (Windows). I'd like to think I that am keeping this a step or two faster on the Mac for all the speed typists out there :-)

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville