How to inject win32 keys : source code

Forum for general chit-chat or off-topic discussion.

Moderators: CEGUI MVP, CEGUI Team

User avatar
Pacome
Just popping in
Just popping in
Posts: 14
Joined: Fri Dec 02, 2005 11:54
Contact:

How to inject win32 keys : source code

Postby Pacome » Fri Dec 09, 2005 21:33

Hi all,

here is some code which could be useful for people who want to inject win32 keys to CeGUI. I saw that some people need it on the forum, then I share..

Code: Select all

LRESULT CALLBACK WndProc(HWND wnd, UINT msgType, WPARAM wParam, LPARAM lParam)
{
  switch( msgType )
  {
    case WM_KEYUP:
      CEGUI::System::getSingleton().injectKeyUp( virtualkey2scancode(wParam, lParam) );
      break;

    case WM_KEYDOWN:
      CEGUI::System::getSingleton().injectKeyDown( virtualkey2scancode(wParam, lParam) );
      break;

    case WM_CHAR:
      CEGUI::System::getSingleton().injectChar( static_cast<CEGUI::utf32>(wParam) );
      break;
  }
}


and the function you need for the conversion:

Code: Select all

UINT virtualkey2scancode(WPARAM wParam, LPARAM lParam)
{
  if(HIWORD(lParam) & 0x0F00)
  {
    UINT scancode = MapVirtualKey(wParam, 0);
    return scancode | 0x80;
  }
  else
  {
    return HIWORD(lParam) & 0x00FF;
  }
}


It works well for all common and special keys.

Just an advice: it would be great to document a little bit more the way you can inject CeGUI inputs.
This lib is great, and it could disappoint some people to find this kind of documentation (the link to "The Beginner Guide to Injecting Inputs" is broken or doesn't exist on the tutorial website).

Best regards,

Pacôme

User avatar
stephb7
Just popping in
Just popping in
Posts: 14
Joined: Wed Nov 02, 2005 13:56

Re: How to inject win32 keys : source code

Postby stephb7 » Wed Dec 14, 2005 17:45

I have not implemented my keyboard code yet but it will use the following functions to handle multilingual input:

HKL hklKeyboardLayout = GetKeyboardLayout(0); // 0 means current thread
// This seemingly cannot fail
// If this value is cached then the application must respond to WM_INPUTLANGCHANGE


BYTE diks[256];
HRESULT hr = mlpDIKeyboard->GetDeviceState( sizeof(diks), diks);
// char mKeyboardBuffer[256];
// hr = mlpDIKeyboard->GetDeviceState( sizeof(mKeyboardBuffer), (LPVOID)&mKeyboardBuffer);


UINT uiScanCode = MapVirtualKeyEx( diks[DIK_A],
0, // Convert DIK_ code to scan code
hklKeyboardLayout);
if(!uiScanCode)
// Error converting to a scancode


BYTE buffer[2];
int iAscii = ToAsciiEx( DIK_A,
uiScanCode,
diks,
buffer,
0, // 1 means a menu is active, 0 means no menu
hklKeyboardLayout);
if(iAscii > 0)
{
// We have 1 or 2 characters in our buffer
// If we have 2 characters then a dead key could not be combined
// with the virtual key to form a single character. But is the
// first digit the virtual key or the dead key?
}
else if(iAscii == 0)
{
// Virtual key could not be translated
}
else if(iAscii == -1)
{
// The virtual key corresponds to a dead key (accent or diacritic)
// Dead keys require an additional input to be resolved into a value
}

User avatar
stephb7
Just popping in
Just popping in
Posts: 14
Joined: Wed Nov 02, 2005 13:56

Re: How to inject win32 keys : source code

Postby stephb7 » Thu Jan 12, 2006 20:10

Here's my code to convert a DirectInput key into a CEGUI utf value. It sort of works.

CEGUI::utf32 keycodeToUTF32( UINT keyCode)
{
CEGUI::utf32 utf = 0;

// Retrieve the keyboard layout in order to perform the necessary convertions
HKL hklKeyboardLayout = GetKeyboardLayout(0); // 0 means current thread
if(hklKeyboardLayout == 0)
return utf;

// Retrieve the keyboard state
BYTE keyboardState[256];
if (GetKeyboardState(keyboardState) == FALSE)
return utf;

/* 0. Convert virtual-key code into a scan code
1. Convert scan code into a virtual-key code
Does not distinguish between left- and right-hand keys.
2. Convert virtual-key code into an unshifted character value
in the low order word of the return value. Dead keys (diacritics)
are indicated by setting the top bit of the return value.
3. Windows NT/2000/XP: Convert scan code into a virtual-key
Distinguishes between left- and right-hand keys.*/
UINT virtualKey = MapVirtualKeyEx(keyCode, 3, hklKeyboardLayout);
if (virtualKey == 0) // No translation possible
return utf;

/* 0 means that there is no menu active
Return values:
0. No translation available
1. A translation exists
2. Dead-key in buffer[1] could not be combined with character
The value in buffer[0] is invalid */
unsigned char buffer[2];
if (ToAsciiEx(virtualKey, keyCode, keyboardState, (LPWORD) buffer, 0, hklKeyboardLayout) == 1)
utf = buffer[0];
return utf;
}


When I place my keyboard in French Canada mode the / key now generates a é. My function correctly converts the DirectInput scancode into the utf32 value of 233, which corresponds to E9 in hexadecimal, the "Latin Small Letter E with Acute" according to Character Map (charmap.exe) which comes with Windows, with the Arial font.

The problem is that I'm unable to view this letter. I'm setting the font to Arial with the following:

mGUISystem = new CEGUI::System(mGUIRenderer, (const CEGUI::utf8*) "Player_Data/Logs/CEGUI_Interface.log");
CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative); // Standard, Errors, Informative, Insane
CEGUI::Font* guiFont = CEGUI::FontManager::getSingletonPtr()->createFont("Arial", "c:/windows/fonts/arial.ttf", 12, CEGUI::FontFlag::Default);
mGUISystem->setDefaultFont(guiFont);


And creating the text box as:


CEGUI::Editbox* editBox = (CEGUI::Editbox*) CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/Editbox", (CEGUI::utf8*)"Editor");
mEditorGuiSheet->addChildWindow(editBox);
editBox->setPosition(CEGUI::Point(0.35f, 0.55f));
editBox->setSize(CEGUI::Size(0.3f, 0.1f));
editBox->setFont("Arial");


And injecting the characters with:

CEGUI::utf32 utf = keycodeToUTF32(arg.key);
CEGUI::System::getSingleton().injectChar(utf);


arg.key contains the value of 0x35, DIK_SLASH. Is there something else I'm supposed to do?

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: How to inject win32 keys : source code

Postby lindquist » Thu Jan 12, 2006 20:19

Remember to add the glyphs to the font. by default a font only loads the ascii glyphs. and as you load the font entirely in code I assume you'll want to set the glyphs from code as well.

So either do it by passing the glyphs utf32 codepoints numerically, or use a string and save your code in utf8

User avatar
stephb7
Just popping in
Just popping in
Posts: 14
Joined: Wed Nov 02, 2005 13:56

Re: How to inject win32 keys : source code

Postby stephb7 » Thu Jan 12, 2006 21:13

Thanks, specifying

guiFont->defineFontGlyphs(230, 250);

displayed my é but made me lose every other character. I'll look into creating a multi-lingual file to enable acceptable characters.

User avatar
stephb7
Just popping in
Just popping in
Posts: 14
Joined: Wed Nov 02, 2005 13:56

Re: How to inject win32 keys : source code

Postby stephb7 » Thu Jan 12, 2006 21:32

I forgot to mention that my keycodeToUTF32() function is only able to convert single key characters. The letter é is obtained by pressing / on a french canadian keyboard, the letter É is obtained by pressing both the SHIFT and the / keys. The SHIFT, CONTROL, and CAPS-LOCK are not considered keys in this case.

However generating the è or È keys require first pressing the right-ALT and the [ keys, releasing both, and then pressing the e or the SHIFT-e keys. These letters are considered as requiring two keys (a dead key and a real key). My function cannot convert this combination into a corresponding character.

User avatar
jacmoe
Just can't stay away
Just can't stay away
Posts: 136
Joined: Sun Apr 03, 2005 14:18
Location: Holbaek, Denmark
Contact:

Re: How to inject win32 keys : source code

Postby jacmoe » Sat Jan 14, 2006 19:28

Code snippets like this are bound to vanish quickly, being buried in a CEGUI Forum...

Consider logging in to the CEGUI Wiki and add it there.

User avatar
stephb7
Just popping in
Just popping in
Posts: 14
Joined: Wed Nov 02, 2005 13:56

Re: How to inject win32 keys : source code

Postby stephb7 » Mon Jan 16, 2006 13:22

I finally figured out how to handle dead keys. Wikied here:
http://www.cegui.org.uk/wiki/index.php/ ... EGUI_utf32

Hope this helps.

User avatar
pjcast
Quite a regular
Quite a regular
Posts: 47
Joined: Wed Jan 12, 2005 12:06

Postby pjcast » Sat Feb 18, 2006 07:46

I just want to thank you for this code snippet (and Rackle helped to).. This helped me integrate Lanugage Nuetral charcter translations into my Input Lib (OIS http://www.sourceforge.net/projects/wgois)... which now uses this on Win32 (and X API on Linux) for translating keys to text.

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Sat Feb 18, 2006 14:36

stephb7 and Rackle are the same person; I switched to this same name on various message boards.

User avatar
pjcast
Quite a regular
Quite a regular
Posts: 47
Joined: Wed Jan 12, 2005 12:06

Postby pjcast » Sat Feb 18, 2006 17:32

:D

Mystique7
Just popping in
Just popping in
Posts: 5
Joined: Thu Mar 30, 2006 15:18
Location: Hull, UK

Postby Mystique7 » Fri Mar 31, 2006 17:26

Cheers Pacome.. the code really helped!

Bump!


Return to “Offtopic Discussion”

Who is online

Users browsing this forum: No registered users and 1 guest