• You are not logged in.

'hacked' MSKLC to enable remapping CAPSLOCK

  • Started by screaminglemon
  • 31 Replies:
  • Reputation: 2
  • Registered: 15-Feb-2010
  • Posts: 14

Well not exactly hacked per se, but I found you can manually edit one of the MSKLC source files to remap CAPSLOCK, and I assume any key for that matter.  And please forgive me if this is old news for I searched and could not find this info anywhere.

Mandatory stupid warning:  I assume no responsibility if this FUBARs your computer.  I have tested it on mine (Win7 32 and 64 bit) and it seems to work fine but use at your own risk.


Instructions:

(1) Download and install Microsoft keyboard Layout Creator 1.4 (MSKLC) from Microsofts website.

(2) Copy a backup of the file C:\Program Files\Microsoft Keyboard Layout Creator 1.4\inc\kbd.h
      In 64bit windows its: C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\inc\kbd.h

     Keep this backup in a safe place so you can easily restore the file if need be.

(3) Open (EDIT) kbd.h in notepad.  Scroll down till you see the keyboard type 4 definitions.
     Should look like this:

#if (KBD_TYPE <= 6)
/***************************************************************************\
* T** - Values for ausVK[] (Virtual Scan Code to Virtual Key conversion)
*
* These values are for Scancode Set 3 and the USA.
* Other languages substitute their own values where required (files kbd**.h)
*
* Six sets of keyboards are supported, according to KBD_TYPE:
*
* KBD_TYPE   Keyboard (examples)
* ========   =======================================================
*    1       AT&T '301' & '302'; Olivetti 83-key; PC-XT 84-key; etc.
*    2       Olivetti M24 102-key
*    3       HP Vectra (DIN); Olivetti 86-key; etc.
*    4 *     Enhanced 101/102-key; Olivetti A; etc.
*    5       Nokia (Ericsson) type 5 (1050, etc.)
*    6       Nokia (Ericsson) type 6 (9140)
*
* * If KBD_TYPE is not defined, the default is type 4.
*
* KB3270 comments refers to KB 3270 keyboards in native emulation mode (DIP
* switches all OFF), and the Scancode Map used to convert its scancodes to
* standard scancode set 1.
*    KB3270 <= 57      - this entry is reached by mapping from scancode 0x57
*                        to an arbitrary scancode: the VK is what counts
*    KB3270 => HOME    - this scancode is mapped to the scancode for VK_HOME
*    KB3270            - no mapping involved, a scancode for KB3270 only
*
* _EQ() : all keyboard types have the same virtual key for this scancode
* _NE() : different virtual keys for this scancode, depending on kbd type
*
*     +------+ +--------+--------+--------+--------+--------+--------+
*     | Scan | |  kbd   |  kbd   |  kbd   |  kbd   |  kbd   |  kbd   |
*     | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 |
\****+-------+-+--------+--------+--------+--------+--------+--------+******/
#define T00 _EQ(                           _none_                    )
#define T01 _EQ(                           ESCAPE                    )
#define T02 _EQ(                           '1'                       )
#define T03 _EQ(                           '2'                       )
#define T04 _EQ(                           '3'                       )
#define T05 _EQ(                           '4'                       )
#define T06 _EQ(                           '5'                       )
#define T07 _EQ(                           '6'                       )
#define T08 _EQ(                           '7'                       )
#define T09 _EQ(                           '8'                       )
#define T0A _EQ(                           '9'                       )
#define T0B _EQ(                           '0'                       )
#define T0C _EQ(                           OEM_MINUS                 )
#define T0D _NE(OEM_PLUS,OEM_4,   OEM_PLUS,OEM_PLUS,OEM_PLUS,OEM_PLUS)
#define T0E _EQ(                           BACK                      )
#define T0F _EQ(                           TAB                       )
#define T10 _EQ(                           'Q'                       )
#define T11 _EQ(                           'W'                       )
#define T12 _EQ(                           'E'                       )
#define T13 _EQ(                           'R'                       )
#define T14 _EQ(                           'T'                       )
#define T15 _EQ(                           'Y'                       )
#define T16 _EQ(                           'U'                       )
#define T17 _EQ(                           'I'                       )
#define T18 _EQ(                           'O'                       )
#define T19 _EQ(                           'P'                       )
#define T1A _NE(OEM_4,   OEM_6,   OEM_4,   OEM_4,   OEM_4,   OEM_4   )
#define T1B _NE(OEM_6,   OEM_1,   OEM_6,   OEM_6,   OEM_6,   OEM_6   )
#define T1C _EQ(                           RETURN                    )
#define T1D _EQ(                           LCONTROL                  )
#define T1E _EQ(                           'A'                       )
#define T1F _EQ(                           'S'                       )
#define T20 _EQ(                           'D'                       )
#define T21 _EQ(                           'F'                       )
#define T22 _EQ(                           'G'                       )
#define T23 _EQ(                           'H'                       )
#define T24 _EQ(                           'J'                       )
#define T25 _EQ(                           'K'                       )
#define T26 _EQ(                           'L'                       )
#define T27 _NE(OEM_1,   OEM_PLUS,OEM_1,   OEM_1,   OEM_1,   OEM_1   )
#define T28 _NE(OEM_7,   OEM_3,   OEM_7,   OEM_7,   OEM_3,   OEM_3   )
#define T29 _NE(OEM_3,   OEM_7,   OEM_3,   OEM_3,   OEM_7,   OEM_7   )
#define T2A _EQ(                           LSHIFT                    )
#define T2B _EQ(                           OEM_5                     )
#define T2C _EQ(                           'Z'                       )
#define T2D _EQ(                           'X'                       )
#define T2E _EQ(                           'C'                       )
#define T2F _EQ(                           'V'                       )
#define T30 _EQ(                           'B'                       )
#define T31 _EQ(                           'N'                       )
#define T32 _EQ(                           'M'                       )
#define T33 _EQ(                           OEM_COMMA                 )
#define T34 _EQ(                           OEM_PERIOD                )
#define T35 _EQ(                           OEM_2                     )
#define T36 _EQ(                           RSHIFT                    )
#define T37 _EQ(                           MULTIPLY                  )
#define T38 _EQ(                           LMENU                     )
#define T39 _EQ(                           ' '                       )
#define T3A _EQ(                           CAPITAL                   )
#define T3B _EQ(                           F1                        )
#define T3C _EQ(                           F2                        )
#define T3D _EQ(                           F3                        )
#define T3E _EQ(                           F4                        )
#define T3F _EQ(                           F5                        )

Now replace where it says "CAPTITAL" with "BACK".

Save the file.  And now 'copy and replace' it back into the %MSKLC%\inc directory so MSKLC will now use the new definition when it runs.

(4) Run MSKLC as you normally would.  Create or import a layout and then "build DLL and Setup Package".

Viola!  The resulting *.DLL files will have the remapped CAPSLOCK.  No need to mess with registry, and you don't need to reboot to get the original QWERTY + CAPSLOCK behavior back.  Just change to a normal layout with the language bar.

You can also put CAPSLOCK on the BACKSPACE key and swap LSHIFT/RSHIFT with letter keys.  That is all I have tested so far and it all seems to work fine.

Offline
  • 2
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189

Remapping modifier keys without editing the registry? Screaminglemon, you are our hero!

Now, who does remember these famous last words:

For what its worth, what you want does not actually appear to be possible within the definitions in kbd.h that MSKLC depends on. Only a key remapper (which is essentially a hardware solution) can work around this issue; it is not something that can be done by simply changing VK mappings. (https://blogs.msdn.com/michkap/archive/ … 70048.aspx)

Last edited by spremino (23-Apr-2010 16:13:30)

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 2
  • Registered: 15-Feb-2010
  • Posts: 14

Funny.  That was the exact post that led me to this discovery.  So thanks to everyone that pestered Micheal Kaplan on his blog for so long that he finally let that hint slip out.

I thought I should mention that the testing function internal to MSKLC will not represent any changes you make to the modifier keys but the layouts will validate fine and the .DLL files do definitely work.

Last edited by screaminglemon (23-Apr-2010 20:51:20)
Offline
  • 0
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189

Has anyone a clue about remapping Alt? Its key and related key code are missing.

Thanks.

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 1
  • From: New York, New York
  • Registered: 22-Nov-2008
  • Posts: 130

I have to say remapping CapsLock to Backspace works perfectly with this. This should be linked on the website or stickied. I've been looking for this for a while.

Colemak typist

Offline
  • 0
  • Reputation: 2
  • Registered: 15-Feb-2010
  • Posts: 14
spremino said:

Has anyone a clue about remapping Alt? Its key and related key code are missing.

Thanks.

The ALT key is named MENU.  So LALT is

#define T38 _EQ(                           LMENU  )

However, RALT is what is called an escaped scancode. They basically share the same scancode.  It seems that all the escaped scancodes start with #define X...  I'm not sure what would happen if you change one but not the other.  I'm not even sure you can change them at all.  It's worthy of some experimentation.

Offline
  • 0
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189

I've tried switching LCONTROL with LMENU and RCONTROL with RMENU and

IT WOOOOOOOOOOORKS! ^_^

Thank you very much, Screaminglemon.

My final goal is to get rid of RMENU and to have LALT on both sides (I have a customized layout without AltGr), but I've not been able to. I've tried using either LMENU or MENU in place of RMENU, but that doesn't accomplish anything. I'll investigate further.

EDIT: Tested on Windows XP Professional SP3. Well, I don't know whether AltGr has been swapped properly with RControl, since I can't check graphics. I'll check later.

Last edited by spremino (03-May-2010 15:41:04)

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 0
  • Registered: 25-Nov-2008
  • Posts: 10

This really ought to be built into the official Windows installer. Shai?

Offline
  • 0
  • Reputation: 214
  • From: Viken, Norway
  • Registered: 13-Dec-2006
  • Posts: 5,361

From what I remember, no key can be defined twice. That's like defining a C variable twice: You'll redefine it the second time. So the duplicated modifier keys have separate scan codes (some of them are escaped codes).

*** Learn Colemak in 2–5 steps with Tarmak! ***
*** Check out my Big Bag of Keyboard Tricks for Win/Linux/TMK... ***

Offline
  • 0
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189

No luck. I resorted to remapping RAlt to LAlt with AutoHotKey.

Still, having a one line script I can stop and restart is way better than having a registry hack which requires logging out.

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 0
  • Registered: 12-Jul-2010
  • Posts: 18

I tried this, while it does work... when you use the Caps Lock key repeatedly it only registers the backspace every second time.

Offline
  • 0
  • Reputation: 0
  • Registered: 14-Aug-2010
  • Posts: 6

Works like a charm (WinXP SP3).

Thank you so much! I'm going to tell (read:bore) everyone I know about this as it's great for all key layouts. (Here I am still on Dvorak-by-day...)

Offline
  • 0
  • Reputation: 0
  • Registered: 28-Aug-2010
  • Posts: 2

Maybe I absolutely did not understand what this discussion is about. If it really is about getting 'normal' CAPSLOCK behaviour after having remapped your keyboard, then there is no problem. MSKLC allows to regulate the CAPSLOCK behaviour for every key separately. Click a key in MSKLC, e.g. VK_OEM_7 (which in the QUERTY keyboard contains quotation marks). A small screen appears that allows to assign a character of your choice to that key, but not only that. Click the button "All…" ('Shows all shift states for this key') in the small screen that appears and check or uncheck 'caps = shift' according to what is needed. That's all.

Offline
  • 0
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189

Hi czytacz, this discussion is about using the Caps Lock key for some other function (Backspace, etc.), not about just disabling it. Thank you for your tip, however ^_^

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 0
  • Registered: 28-Aug-2010
  • Posts: 2

Hello, Spremino. Now I wonder why the use of the CapsLock key for some other function like Backspace could not be arranged more easily by a program like KeyTweak. At least that is what I used for mapping the CapsLock function onto the RightCtrl key and using the CapsLock key for some other function (not Backspace in my case). Of course this may well be just another irrelevant suggestion, for changes brought about by KeyTweak (or any similar program) are not limited to only one specific keyboard but to all keyboard. I just wanted to get rid of the effect of inadvertantly touching the CapsLock key while typing an A, so I was happy to have something less obnoxious next to the A key.

Last edited by czytacz (30-Aug-2010 11:13:32)
Offline
  • 0
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189
czytacz said:

Hello, Spremino. Now I wonder why the use of the CapsLock key for some other function like Backspace could not be arranged more easily by a program like KeyTweak.

Therefore to install Colemak you'd need both a layout setup and KeyTweak. Moreover, whenever you would like to switch back to standard Qwerty (Caps Lock included), you would have to use both the Control Panel applet and KeyTweak. OTOH, a tweaked MSKLC layout will not require any other software and you'll just need the Control Panel applet to switch. To me, this is the most convenient way.

Last edited by spremino (30-Aug-2010 12:41:20)

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 0
  • Registered: 07-Oct-2010
  • Posts: 28

Lol what the?

"Access denied"

- when I try and overwrite the existing file :(

edit: no worries.

-- for those on windows 7 and I suppose vista you need to make and save changes outside the program files IF you have UAC turned on.

Last edited by Culinia (21-Nov-2010 00:24:32)
Offline
  • 0
  • Reputation: 0
  • Registered: 10-Apr-2011
  • Posts: 1

FYI, my thoughts on this (and info on both some of the reported problems and some of the inherent issues in the approach) can be found here:

http://www.siao2.com/2011/04/09/10151666.aspx

Cheers,
Michael

Offline
  • 0
  • Reputation: 0
  • Registered: 21-Dec-2012
  • Posts: 1

Hello
I surprised to find this post because I engage of a very teasing proplem in MSKLC. that is simple: I want to add virtual space in Shift + Space combination. but validation error occur and log it:
"ERROR: 'VK_SPACE' in Shift State 'Shift' must be made up of white space character(s), but is defined as '' (U+200c) instead."
this is in the case which I imported even a ready installed keyboard in MSKLC and even without any change, right after importing the keyboard, and run Make DLL, the above mentioned Error occur. PLEASE help me if you know how can I ignore the error and create my own keyboard. when others could do it and embed (U+200c) in their keyboards, this should be possible for me.... how can I hack the error for such code for Shift + space? I really need your help
All the Best
Datis

Offline
  • 0
  • Reputation: 0
  • Registered: 03-Jul-2009
  • Posts: 189

Does anybody know whether this hack still works on Windows 8.1?

Dvorak typist here.  Please take my comments with a grain of salt.

Offline
  • 0
  • Reputation: 0
  • Registered: 28-May-2015
  • Posts: 1

Hello
How should MSKLC be hacked or changed to allow assigning U+200c to Shift+Space?

Offline
  • 0
  • tmn
  • New member
  • Reputation: 1
  • Registered: 17-Apr-2017
  • Posts: 4

Keep in mind that MSKLC layouts might break shortcuts in some applications. It happens with Ctrl-Shift-letter and some other combinations, as described here.

For example, Civilization 3 was affected by this, and, I think, Firefox had the same problem.

Layouts created with KbdEdit work fine, but that program isn't free.

Offline
  • 0
  • Reputation: 214
  • From: Viken, Norway
  • Registered: 13-Dec-2006
  • Posts: 5,361

Interesting, tmn. And a bit complex. Have you got any experience with UI:KeyboardLayout tool from the page you linked to?

Last edited by DreymaR (19-Apr-2017 12:36:14)

*** Learn Colemak in 2–5 steps with Tarmak! ***
*** Check out my Big Bag of Keyboard Tricks for Win/Linux/TMK... ***

Offline
  • 0
  • tmn
  • New member
  • Reputation: 1
  • Registered: 17-Apr-2017
  • Posts: 4

No, I haven't used the module itself. But its documentation was of great help. That module is designed to produce the izKeys crazy layouts.

I've just tried to import US layout into MSKLC, save it into .klc file and then compare "kbdutool -s" output to a publicly available US layout source (kbdutool comes with MSKLC). And the reason for the mentioned bug becomes clear.

Edited:
On import MSKLC loses three Ctrl+Shift combinations. From the original US layout:

static ALLOC_SECTION_LDATA VK_TO_WCHARS4 aVkToWch4[] = {
//                      |         |  Shift  |  Ctrl   |S+Ctrl   |
//                      |=========|=========|=========|=========|
  {'2'          ,0      ,'2'      ,'@'      ,WCH_NONE ,0x0000   },
  {'6'          ,0      ,'6'      ,'^'      ,WCH_NONE ,0x001e   },
  {VK_OEM_MINUS ,0      ,'-'      ,'_'      ,WCH_NONE ,0x001f   },

Adding them back produces a warning:

WARNING: The <Shift+Control> shift state for VK_2 contains a control character. This is redundant and should be removed.

I don't know what's the story behind it, but other characters bound to Ctrl+Shift in other layouts import fine.

However, with no Ctrl+Shift combinations left MSKLC does not add Ctrl+Shift as a handled state into SHIFTSTATE section of .klc file. Which, in turn, causes different behavior after compilation.

I've found two ways to fix this:
- add any Ctrl+Shift+... combination in MSKLC and rebuild from the menu;
- or change the relevant section inside the .klc file

SHIFTSTATE

0	//Column 4
1	//Column 5 : Shft
2	//Column 6 :       Ctrl
3	//Column 7 : Shft  Ctrl

and recompile with kbdutool.

Another difference from kbdus.c was that kbdutool put all the keys into the widest array.
kbdus.c:

static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = {
//                      |         |  Shift  |
//                      |=========|=========|
  {VK_OEM_3     ,0      ,'`'      ,'~'      },

kbdutool:

static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = {
//                      |         |  Shift  |  Ctrl   |
//                      |=========|=========|=========|
  {VK_OEM_3     ,0      ,'`'      ,'~'      ,WCH_NONE },

I don't think it affects anything. But the same structure can be achieved with kbdutool, if the trailing "-1"s are removed from the .klc file.

Is there any other tool to convert a .dll layout back into C source? Or anything else that can produce standalone layouts like MSKLC and KbdEdit?

Last edited by tmn (20-Apr-2017 22:21:50)
Offline
  • 0
  • Reputation: 214
  • From: Viken, Norway
  • Registered: 13-Dec-2006
  • Posts: 5,361

I know of no such tools. I've never even used kbdutool directly, although I've wanted to on some occasions.

Surely, the extra Ctrl column shouldn't matter as long as there's WCH_NONE in it. Looks like it's just accounting for the extra Ctrl state but not adding anything to it.

*** Learn Colemak in 2–5 steps with Tarmak! ***
*** Check out my Big Bag of Keyboard Tricks for Win/Linux/TMK... ***

Offline
  • 0