L’accentuation
L’association
Technique
Dernière mise à jour : 9 mars, 2024
Claviers : Le clavier français élargi (Galéron) Clavier azerty normalisé Clavier bépo Clavier québécois
         
Création de claviers : Sous Windows (via MSKLC) Version portable sous Windows (PKL)    

Création d’un clavier Windows personnalisé

Pour utiliser la méthode qui est développée ici, et pour créer son propre clavier sous Windows XP, Vista, Windows 7 et suivants, sous les diverses versions 32 bits ou 64 bits (amd64, ia64, i386, wow64). On s’aidera de l’utilitaire Microsoft Keyboard Layout Creator 1.4 (MSKLC) disponible gratuitement chez Microsoft.

Il s’avère cependant qu’avec MSKLC les touches mortes sont en général inutilisables, et que les touches modifiables ne concernent qu’une partie du clavier. La procédure permet de corriger ces défauts par le biais de quelques connaissances en informatique et en particulier de programmation C/C++. Le paquetage contient les sources du clavier multilingue :

Sources.bat Un script pour obtenir les sources C et H
Compile.bat Un script pour compiler les sources C et H
KbFrVmu.klc La source klc
KbFrVmu.DEF La source de définition de la librairie
KbFrVmu.H La source H
KbFrVmu.RC Le fichier ressources
KbFrVmu.RC Le fichier ressources

Installation

En regardant le contenu des répertoires où est installé MSKLC, on trouve les fichiers cl.exe, c1.dll, c2.dll, link.exe, rc.exe, qui correspondent à un compilateur C complet avec éditeur de liens et compilateur de ressources. Donc, quelque part MSKLC doit créer un programme C, le compiler puis effacer les sources C après usage. En fait kbdutool.exe utilisé directement à partir de la ligne de commande permet d’obtenir ces sources. Le script Sources.bat facilite l’obtention de ces sources et le script Compile.bat permet de compiler les sources et d’obtenir un nouveau pilote. La procédure est la suivante :

  • Installer MSKLC directement sous la racine, avec un nom de répertoire minimal C:\MSKLC et non sous le répertoire par défaut C:\Program Files\Microsoft Keyboard Layout Creator 1.4 (pour la simplicité et parce que l’indication de la version 1.4 avec le point dans le nom contrarie le fonctionnement de Compile.bat et Sources.bat).
  • L’obtention des sources n’est pas obligatoire. Il suffit de reprendre les sources fournies (KbdFrVmu.C ou Kbdfr.C). Mais on peut les obtenir de la façon suivante :
    • Lancer MSKLC pour créer un nouveau clavier, puis aller dans Project>Properties… en le nommant Layout01 par exemple (Name) et adapter les autres champs (Description, Company, Copyright), et l’enregistrer dans un répertoire de travail Test, par exemple (Current working directory).
      • Avec File>Save Source File As…, le fichier Layout01.klc est enregistré sous Test\Layout01,
      • Avec Project>Build DLL and Setup Package les fichiers Layout01_amd64.msi, Layout01_i386.msi, Layout01_ia64.msi, setup.exe sont enregistrés sous le répertoire Test\Layout01. Les pilotes Layout01.dll se trouvent dans les répertoires respectifs : amd64, i386, ia64 et wow64.
    • Copier Compile.bat et Sources.bat dans le répertoire Test\Layout01.

      Note : Si on passe par la ligne de commande par Démarrer/Exécuter/cmd et qu’on lance C:\MSKLC\bin\i386\kbdutool.exe, on obtient une aide succincte pour les différents attributs associés à cette commande. Le script Sources.bat permet d’obtenir directement les sources C dans le répertoire de travail.

      kbdutool.exe -u -s Layout01.klc fournit les sources C et H,
      kbdutool.exe -u -x Layout01.klc compile les sources C et H et crée le pilote 32 bits pour x86 dans le répertoire en cours : Layout01.dll.

      Pour les autres pilotes les commandes sont :
      [-x]   
      pour x86 (par défaut),
      [-i]    pour IA64,
      [-m]    pour AMD64,
      [-o]    pour WOW64.

      Le script de Sources.bat est le suivant :

      rem Sources
      C:\MSKLC\bin\i386\kbdutool.exe -u -s Layout01.klc

      Le script de Compile.bat est le suivant :

      rem Compilateur
      attrib +R Layout01.C
      attrib +R Layout01.H
      attrib +R Layout01.DEF
      attrib +R Layout01.RC

      C:\MSKLC\bin\i386\kbdutool.exe -u -v -w -x Layout01.klc
      move /y Layout04.dll i386
      C:\MSKLC\bin\i386\kbdutool.exe -u -v -w -i Layout01.klc
      move /y Layout04.dll iad64
      C:\MSKLC\bin\i386\kbdutool.exe -u -v -w -m Layout01.klc
      move /y Layout04.dll amd64
      C:\MSKLC\bin\i386\kbdutool.exe -u -v -w -o Layout01.klc
      move /y Layout04.dll wow64

      attrib -R Layout01.C
      attrib -R Layout01.H
      attrib -R Layout01.DEF
      attrib -R Layout01.RC

      Étant donné que MSKLC efface les sources C après usage, la commande attrib +R met le fichier en lecture seule. En fin de compilation, la commande attrib -R enlève la lecture seule pour permettre la modification des fichiers. La commande move /y déplace le fichier Layout01.dll dans le répertoire correspondant.

    • Modifier Sources.bat à l’aide du Bloc-Notes et adapter selon le nom du pilote de clavier choisi Layout01.klc
    • Lancer Sources.bat  quatre fichiers sont obtenus dans le répertoire en cours Test/Layout qui sont  Layout01.C, Layout01.DEF, Layout01.H, Layout01.RC
  • Les fichiers Layout01.C et Layout01.H sont modifiables grâce au Bloc-notes et il n’est plus nécessaire de relancer MSKLC et de rechercher les sources dans les fichiers temporaires. C’est le fichier Compile.bat qui permettra de compiler ces sources, et de créer les nouveaux pilotes de clavier du même nom Layout01.dll.
  • Modifier Compile.bat à l’aide du Bloc-Notes, et remplacer toutes les occurences dépendant du nom de clavier Layout01.
  • Lancer Compile.bat. Les nouveaux pilotes Layout01.dll se trouvent dans chacun des quatre répertoires respectifs : Test\Layout01\amd64, Test\Layout01\ia64, Test\Layout01\i386, et Test\Layout01\wow64.
  • Lancer setup.exe pour installer le pilote de clavier.

Cette méthode a l’avantage que l’on peut tester à volonté le même pilote de clavier et comprendre l’usage de chaque structure.

Images de la disposition du clavier KbFrVmu.

Autres exemples de pilotes de clavier Grec classique polytonique à partir du clavier français, Clavier français élargi.


Autre méthode par le WDK

On peut également créer des pilotes de clavier à partir du Windows Driver Kit (WDK) sans utiliser MSKLC.
Décompacter le fichier GRMWDK_EN_7600.ISO à l’aide de l’utilitaire 7-Zip par exemple, puis lancer KitSetup.exe pour l’installation.
Les sources du clavier français se trouvent en C:\WinDDK\7600.16385.0\src\input\layout\all_kbds\kbdfr. Les quatre fichiers kbdfr.c, kbdfr.def, kbdfr.h et kbdfr.rc sont modifiables également par le Bloc-notes.
Par exemple, la compilation des sources pour Windows XP, se fait de la façon suivante : Démarrer>Programmes>Windows Driver Kits>WDK 7600.16385.0>Build Environments>Windows XP> x86 Checked Build Environment. Une fois en mode console, se replacer dans le répertoire C:\WinDDK\7600.16385.0\src\input\layout\all_kbds\kbdfr et taper build pour lancer la compilation. Huit fichiers sont créés dans le répertoire C:\WinDDK\7600.16385.0\src\input\layout\all_kbds\kbdfr\objchk_wxp_x86\i386, dont le nouveau pilote kbdfr.dll. La procédure est la même pour les autres systèmes d’exploitation Windows 7, Windows Server 2003, Windows Vista and Windows Server 2008, pour chacun trois versions sont proposées (ia64, x64, x86).
Pour l’installation, substituer le pilote installé situé dans le répertoire d’origine par le nouveau pilote personnalisé du même nom, puis redémarrer Windows pour activer le pilote.

La procédure doit être adaptée pour les pilotes 64 bits en fonction de l’architecture de la machine (système d’exploitation et processeurs).

Les spécifications des claviers sont données dans le fichier C:\WinDDK\7600.16385.0\inc\api\kbd.h, et dans la documentation du WDK.


Description du fonctionnement d’un clavier

Chaque touche du clavier est considérée comme un interrupteur, lorsqu’on appuie sur une touche, le clavier renvoie un numéro que l’on appelle le scan code. Lorsqu’on relâche la touche, le clavier envoie à nouveau un scan code à l’ordinateur. Mais certaines touches ne renvoient pas un scan code, mais deux ou trois : le premier octet envoyé est toujours 224 (0xE0 en hexadécimal), ou 225 (0xE1). 0xE0 signale qu’un autre octet suit, et 0xE1 que deux octets suivent. Seules quelques touches renvoient deux octets, et la seule touche renvoyant trois octets est la touche Pause. En fait, seules les touches qui font double emploi renvoient plusieurs octets, ce qui permet de les distinguer. Par exemple une des touches Origine renvoie 0x47, l’autre renvoie 0xE0 0x47. Quand on relâche ces touches, elles renvoient les mêmes octets. La touche Pause, elle, renvoie en rafale les six codes 0xE1 0x1D 0x45 0xE1 0x9D 0xC5.

Scan codes des touches sur le clavier américain.
Liste des codes des touches virtuelles.


Description des structures de données utilisées

I – Fichier H

Modifier KbFrVmu.H avec le Bloc-notes.

Le clavier Anglais (États-Unis) – kbdus.dll – est à l’origine de tous les claviers. La disposition AZERTY du clavier français en diffère selon la redéfinition des touches suivante :

OEM_4, 'A', 'Z', OEM_6, OEM_1, 'Q', 'M', OEM_3, OEM_7, 'W', OEM_COMMA, OEM_PERIOD, OEM_2, OEM_8.

Certaines touches ont un scan code étendu extended key (KBDEXT) et sont précédées de la lettre X (touche Control droite  X1D). Les autres touches sont précédées de la lettre T (touche Entrée  T1C).

Pour KbFrVmu.H, on a en particulier :
La touche Kana fonctionne ici comme la touche Alt-Gr et non comme la touche CapsLock. Elle est occupe la touche Ctrl droite du clavier (X1D) et devient OEM_8 )
La touche [§ !] du clavier français (T35) initialement définie OEM_8, devient OEM_ATTN.

La redéfinition est alors :

#undef  T35
 #define T35 _EQ( OEM_ATTN )

#undef  X1D
 #define X1D _EQ( OEM_8    )

Conséquence dans KbFrmuVmu.C, dans la structure aVkToWch<n> la touche virtuelle VK_OEM_8 (normalement associée à la touche [§ !] du clavier français) est remplacée en VK_OEM_ATTN (voir plus bas dans la table aVkToWch7).

II – Fichier C

Modifier KbFrVmu.C avec le Bloc-notes.

ausVK

La première table ausVK contient la table de conversion des codes clavier (scan code) vers les touches virtuelles Windows (Virtual keys). Les macros T01 à T7F sont définies dans kbd.h se trouvant quelque part dans le répertoire d’installation de MSKLC et également dans le DDK. (N.B. le KBD_TYPE est 4 pour la plupart des claviers actuels non asiatiques). Certaines de ces macros peuvent être redéfinies dans le .H spécifique du clavier (ex : KbFrVmu.H). La table est adressable directement par le scan code.

aE0VscToVk

La table aE0VscToVk contient la table de conversion des scan codes doubles (0xE0 0x??) vers les touches virtuelles Windows correspondantes.

aE1VscToVk

La table aE1VscToVk contient la table de conversion des scan codes triples (0xE1 0x?? 0x??) vers les touches virtuelles Windows correspondantes.

Inutile de modifier ces tables.

aVkToBits

La table aVkToBits définit les touches bascule (Shift, Ctrl, Alt) et associe un bit à chacune d’elles (KBDSHIFT = 0x01, KBDCTRL = 0x02, KBDALT= 0x04).

Comme il y a trois bits apparemment, le clavier peut donc être dans huit états. (VK_MENU est la touche Alt de gauche). Windows gère de façon particulière la touche Alt-Gr, théoriquement VK_RMENU, en combinant les deux touches VK_CONTROL et VK_MENU. En fait on peut utiliser d’autres bits supplémentaires et les associer à d’autres touches, ce qui peut fournir beaucoup plus d’états possibles, notamment pour les claviers asiatiques (KBDKANA = 0x08).

static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = {
{ VK_SHIFT   , KBDSHIFT },
{ VK_CONTROL , KBDCTRL  },
{ VK_MENU    , KBDALT   },

{ VK_OEM_8   , KBDKANA  },
{ 0          , 0        }
};


CharModifiers

La table CharModifiers transforme les différentes valeurs précédentes en index dans les tables qui suivent.

La première entrée de cette table contient l’adresse de la table précédente, l’entrée suivante indique le nombre d’états - 1 du clavier (ici 9), les entrées suivantes donnent les index correspondants. SHFT_INVALID indique que la combinaison est interdite (ou utilisée par Windows). Ici dans le clavier multilingue, les combinaisons Shift + Ctrl, Alt, Shift + Alt sont interdites.

Modification# Keys pressed
0, Normal
1, Shift
2, Control
SHFT_INVALID, Shift + Control
SHFT_INVALID, Alt
SHFT_INVALID, Shift + Alt
3, Ctrl + Alt (ou Alt-Gr)
4, Ctrl + Alt + Shift (ou Alt-Gr + Shift)
5, Kana
6 Kana + Shift

Les tables suivantes sont réellement les plus utiles. Ce sont elles qui assignent des valeurs Unicode à chaque touche.

aVkToWch<n>

Les premières tables utiles sont aVkToWch<n> (<n> allant de 1 à 7, et même de 8 à 10 pour les claviers asiatiques). Ces tables associent n valeurs Unicode à chaque touche virtuelle Windows.

Ces tables ont toutes la même structure, chaque entrée contient :

La valeur de la touche virtuelle Windows,
Un attribut,
<n> valeurs Unicode ou spéciales. Chaque code est indexé avec les valeurs venant de la table CharModifiers.

L’attribut peut être une combinaison de ces différentes valeurs :

CAPLOK indique que la touche blocage CapsLock agit comme la touche Shift sur cette touche.
CAPLOKALTGR idem CAPLOK quand la touche Alt-Gr est enfoncée.
SGCAPS permet d’associer quatre états majuscule à cette touche :

- Normal
- Shift
- CapsLock
- CapsLock + Shift

KANALOK indique que la touche blocage katakana agit comme la touche katakana. (clavier asiatique/japonais).     
GRPSELTAP aucune information.

Les valeurs spéciales peuvent être :

WCH_NONE Cette touche ne produit rien.
WCH_DEAD Cette touche est une touche morte ou diacritique.
WCH_LGTR Cette touche est une touche ligature.

Il y a donc une table aVkToWch7 car on a sept états possibles, et chaque entrée contient neuf valeurs : la touche virtuelle, un attribut, et sept valeurs Unicode qui correspondent aux sept états ci-dessus.

Exemple :

  {'A' ,CAPLOK | CAPLOKALTGR,'a' ,'A' ,WCH_NONE ,0x00e6 ,0x00c6 ,0xfb00 ,WCH_NONE },

La touche virtuelle A, renvoie les valeurs suivantes en fonction de l’état des touches bascule :

0 Normal a
1 Shift A
2 Control touche inactive
3 Alt-Gr 0x00e6 (æ - ligature linguistique a/e minuscule)
4 Shift + Alt-Gr 0x00c6 (Æ - ligature linguistique A/E majuscule)
5 Kana 0xfb00 (ff - ligature esthétique de 2 f)
6 Kana + Shift touche inactive

Comme la touche T35 a été redéfinie dans le fichier H pour les besoins de la touche Kana (VK_OEM_ATTN à la place de VK_OEM_8) , on a alors :

  {VK_OEM_ATTN  ,0 ,'!'      ,0x00a7   ,WCH_NONE ,0x00a1   ,WCH_NONE ,WCH_NONE ,WCH_DEAD },
  {0xff         ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,0xa705   },

La valeur WCH_DEAD indique que l’entrée sera directement suivie par une entrée spéciale pour définir la valeur de cette touche morte. La touche virtuelle associée à cette entrée supplémentaire est 0xff.

Exemple :

  {'S'  ,CAPLOK ,'s'      ,'S'      ,WCH_NONE ,0x00df   ,0x017f   ,WCH_NONE ,WCH_DEAD },
  {0xff ,0      ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,0xa709   },

La touche virtuelle S renvoie les valeurs suivantes en fonction de l’état des touches bascule :

0 Normal s
1 Shift S
2 Control touche inactive
3 Alt-Gr 0x00df (ß - eszett)
4 Shift + Alt-Gr 0x017f (ſ - s long)
5 Kana touche inactive
6 Kana + Shift touche morte correspondant aux signes diacritiques brève et accent aigu

N.B. : Le comportement de chaque touche morte est défini dans la table aDeadKey.

Si l’attribut contient SGCAPS, cette entrée sera directement suivie par une entrée spéciale (de type aVkToWch2) pour définir les codes à renvoyer lorsque le clavier est en mode CapsLock. La touche virtuelle associée à cette entrée supplémentaire est la même que l’entrée principale.

Exemple :

  {'N'  ,SGCAPS ,'n' , 'N'  ,WCH_NONE ,'£', WCH_NONE },
  {'N'  ,0      ,'ñ' , 'Ñ' },

La touche virtuelle N a quatre états Shift, et renvoie les valeurs :

Normal n
Shift N
CapsLock ñ (n tilde)
CapsLock + Shift Ñ (n tilde majuscule)
Alt-Gr £ (livre sterling)

Il est possible de combiner l’attribut SGCAPS et un signe diacritique sur la même touche. Cela devient un peu compliqué pour Windows, mais c’est le comportement habituel des claviers Macintosh ou Linux.

Exemple :

  {'7'   ,SGCAPS ,0x00e8 , '7'   ,WCH_NONE ,WCH_DEAD ,WCH_NONE ,0x201e   , WCH_NONE },
  {0xff  ,0      ,0x00c8 , '7'   ,WCH_NONE ,'`'      ,WCH_NONE ,WCH_NONE , WCH_NONE },

La touche virtuelle 7 renvoie les valeurs suivantes en fonction de l’état des touches bascule :


Normal 0x00e8 (è)
Shift 7
Control touche inactive
CapsLock 0x00c8 (È)
Alt-Gr touche morte accent grave
Shift + Alt-Gr touche inactive
CapsLock + Shift 0x00e8 (è)
Kana 0x201e („ Guillemet-virgule double inférieur)
Kana + Shift touche inactive

La valeur WCH_LGTR indique une touche ligature, ou plus exactement une touche pouvant renvoyer plusieurs unités de code. Le nom de ligature vient du fait que ces touches sont normalement utilisées pour produire une suite de valeurs Unicode devant se combiner avec le dernier caractère introduit pour ne former qu’un seul glyphe. Les touches ligature sont définies dans la table aLigature.

aVkToWcharTable

Cette table contient la liste de toutes les tables aVkToWch<n> à utiliser.

Chaque entrée contient :

Un pointeur sur la table aVkToWch<n>,
La valeur de <n>,
La taille en octets d’une entrée de la table aVkToWch<n>.

N.B. : Il semble que la table aVkToWch1 doit être citée en dernier.

aKeyNames, aKeyNamesExt, aKeyNamesDead

Ces tables servent uniquement à nommer les touches qui ne correspondent pas à un caractère ascii.

Chaque entrée des tables aKeyNames (touches envoyant un seul scan code), aKeyNamesExt (touches envoyant deux ou trois scan codes) contient deux valeurs :

Le scan code de la touche,
Le nom donné à cette touche.

Chaque entrée de la table aKeyNamesDead contient aussi deux valeurs :

La valeur Unicode de la touche morte,
Le nom donné à cette touche morte.

aDeadKey

C’est une des tables les plus utiles. Elle contient toutes les combinaisons possibles des touches diacritiques avec les autres touches.

Chaque entrée doit contenir un appel à la macro DEADTRANS dont les quatre paramètres sont :

La valeur Unicode du caractère,
La valeur Unicode du signe diacritique,
La valeur Unicode du caractère avec le signe diacritique,
Un drapeau qui vaut 0 ou 1 (DKF_DEAD).

Le quatrième paramètre par défaut doit être à 0. Mais s’il est à DKF_DEAD c’est que cette combinaison crée un nouveau signe diacritique, correspondant à la combinaison de plusieurs touches diacritiques.

aLigature

Cette table facultative contient la définition de toutes les touches ligature. Celles-ci ont la valeur WCH_LGTR dans les tables aVkToWch<n>.

La touche ligature qui renvoie le plus d’unités de code détermine la taille de la table.

Par exemple si on a deux touches ligature en dévanâgarî.

VK_OEM_4 qui renvoie les deux valeurs Unicode 0x0930 et 0x0941 (रु).
et Shift + VK_OEM_4 qui renvoie les trois valeurs Unicode 0x0930, 0x094d, 0x0935 (र्व).

La plus longue séquence renvoyant trois valeurs, il faut donc créer la table comme suit :

static ALLOC_SECTION_LDATA LIGATURE3 aLigature[] = {
  {VK_OEM_4, 0 ,0x0930 ,0x0941 ,WCH_NONE },
  {VK_OEM_4, 1 ,0x0930 ,0x094d ,0x0935   },
  {0 ,0 ,0 ,0 ,0 }
};

La première valeur du tableau est la valeur de la touche virtuelle Windows, la deuxième est l’index venant de la table CharModifiers. Les plus courtes séquences sont complétées par des WCH_NONE.

Le fichier kbd.h ne contient que 4 types LIGATURE2, LIGATURE3, LIGATURE4, LIGATURE5. Mais en réalité on n’est pas limité à cinq unités de code : si on a une touche Alt-Gr + espace qui renvoie dix unités de code, par exemple *LIGATURE*, on peut déclarer la table précédente comme suit :

TYPEDEF_LIGATURE(10) // LIGATURE10, *PLIGATURE10;
static ALLOC_SECTION_LDATA LIGATURE10 aLigature[] = {
  {VK_OEM_4 ,0 ,0x0930 ,0x0941 ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE , WCH_NONE ,WCH_NONE ,WCH_NONE },
  {VK_OEM_4 ,1 ,0x0930 ,0x094d ,0x0935   ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE , WCH_NONE ,WCH_NONE ,WCH_NONE },
  {VK_SPACE, 3 , '*'   ,    'L',      'I',      'G',      'A',      'T',      'U',       'R',      'E',     '*' },
  {0 ,0 ,0 ,0 ,0 }
};

On peut donc créer des touches renvoyant des mots, voire des phrases. On est toutefois limité à seize unités de code  TYPEDEF_LIGATURE(16).

KbdTables

Cette table est celle qui référence toutes les autres et dont l’adresse est renvoyée par l’API KbdLayerDescriptor défini juste après cette table et qui termine la source.

static ALLOC_SECTION_LDATA KBDTABLES KbdTables = {
  /*
  * Modifier keys
  */
  &CharModifiers,           
Adresse de la table CharModifiers

  /*
  * Characters tables
  */
  aVkToWcharTable,          
Adresse de la table aVkToWcharTable

  /*
  * Diacritics
  */
  aDeadKey,                 
Adresse de la table aDeadKey, mettre NULL s’il n’y a pas de touche morte

   /*
  * Names of Keys           
Adresses des tables des noms des touches
  */
  aKeyNames,
  aKeyNamesExt,
  aKeyNamesDead,

  /*
  * Scan codes to Virtual Keys     
Adresses des tables de conversion des scan codes
  */
  ausVK,
  sizeof(ausVK) / sizeof(ausVK[0]), 
Nombre d’entrées de la table ausVK
  aE0VscToVk,
  aE1VscToVk,

  /*
  * Locale-specific special processing

KBD_VERSION vaut 1 et ne doit pas être changé.
KLLF_ALTGR  signifie que Alt-Gr est traité comme la pression simultanée des touches Ctrl et Alt. Et si le clavier a une touche Alt-Gr, on doit utiliser KLLF_ALTGR.
KLLF_SHIFTLOCK signifie qu’on peut désactiver CapsLock en appuyant sur une des touches Shift. Par défaut pour désactiver CapsLock il faut repousser dessus.
        N.B. : Une fois le clavier installé, cette option peut être redéfinie via les Options régionales et linguistiques du Panneau de configuration.
        N.B. : Si on a des touches ayant quatre états Shift, il est déconseillé d’utiliser ce flag.
KLLF_LRM_RLM Left-To-Right-Marker, Right-To-Left-Marker, est utile si on a défini un clavier pour une langue qui s’écrit de droite à gauche (hébreu, arabe, etc.) et si l’on veut l’utiliser en mode bidirectionnel. Dans ce cas Left-Shift + Backspace renvoie la valeur Unicode (U+200E - Left-To-Right-Mark) et Right-Shift + Backspace renvoie la valeur Unicode (U+200F - Right-To-Left-Mark).

  */
  MAKELONG(KLLF_ALTGR, KBD_VERSION),

  /*
  * Ligatures,              
S’il n’y a pas de ligatures, mettre les valeurs 0, 0, NULL
  */
  10,                       
Longueur de la plus longue séquence
  sizeof(aLigature[0]),      Taille d’une entrée de la table aLigature
  (PLIGATURE1)aLigature      Adresse de la table aLigature
};