Keyboard input


#1

Hi Jules,

Something that could be useful in some situations, for example for the MidiKeyboardComponent , would be providing some sort of ‘scancode’ information for the keys , an int value for each key of the keyboard that would be independent of the keyboard mapping (qwerty, azerty etc), and even cross-platform. This is the ‘virtual scan code’ on windows, and the ‘NSEvent keyCode’ on mac .


#2

Yeah, I looked into doing that once, but the tricky bit was coming up with something platform-independent that could map to all the different platforms and handle all the different types of keyboard - it seemed like it’d actually be a lot more complicated than it first appears.


#3

According to the NSEvent doc it should be hardware independent : http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/Reference/Reference.html#//apple_ref/occ/instm/NSEvent/keyCode . It seems to be also independent on windows, and probably on linux. I’m using these for now, and it seems to work fine – but I’m only concerned with the subset of keys that are available on every keyboard. The mappings are different for win, macos and linux, though.

By the way, I just noticed that I cannot input accentuated letter with the cocoa Juce - it used to work with the carbon version of juce, but it does not work anymore. You can check that by selecting a french keyboard layout in the macos “language & text preferences”. The ‘[’ key on the right of the ‘p’ letter is marked ‘^’ on french keyboards, and is supposed to

  • do nothing when pressed one time
  • insert ‘ê’ when you press ‘^’ and then ‘e’, or ‘ô’ , ‘î’, etc. Or just ‘^’ when you press it twice.

#4

Sorry to bump this thread… I got asked to add some Computer-Keyboard-to-MIDI functionality in my app today, and for that I need the virtual key scan codes. I hacked JUCE to add this feature but I’m not sure if it won’t break anything.
Here’s what I added to Win32ComponentPeer:

[code]bool handleVirtualKey(LPARAM lParam, bool keyDownOrUp)
{
const bool goOn = (keyDownOrUp && ((lParam>>30) & 1) == 0) || !keyDownOrUp;
if (goOn)
{
unsigned int scancode = (lParam>>16) & 63;
Component *c=Component::getCurrentlyFocusedComponent();

		while (c!=0)
		{
			if (c->handleVirtualKey(scancode, keyDownOrUp)) return true;
			c=c->getParentComponent();
		}

		return false;
	}
	else return true;
}[/code]

[code]//==============================================================================
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
if (doKeyDown (wParam))
return 0;

            forwardMessageToParent (message, wParam, lParam);
            break;

        case WM_KEYUP:
			if (handleVirtualKey(lParam, false)) 
				return 0;

        case WM_SYSKEYUP:
            if (doKeyUp (wParam))
                return 0;

            forwardMessageToParent (message, wParam, lParam);
            break;

        case WM_CHAR:
			if (handleVirtualKey(lParam, true)) 
				return 0;

			if (doKeyChar ((int) wParam, lParam))
                return 0;

            forwardMessageToParent (message, wParam, lParam);
            break;

        case WM_APPCOMMAND:
            if (doAppCommand (lParam))
                return TRUE;

            break;

        //==============================================================================[/code]

… and to Component.h :

// You can react to virtual key scan codes prior to keyPressed being called. // Return true if you do so, otherwise false. If you return true, keyPressed won't be called! virtual bool handleVirtualKey(int scancode, bool keyDownOrUp) {return false;}


#5

Sorry to resurrect this thread, but I think this feature would be very useful.