Bonjour à tous,
J'ai besoin de capturer le code d'une carte RFID, grâce à un lecteur qui dispose d'une fonction clavier "virtuel" si je peux l'appeler ainsi.
Le logiciel, installer sur des bornes, utilise déjà un système qui communique en PORT COM. Les lectures qui servent d'identification, devra être parfaitement identique entre les 2 système, les utilisateurs pouvant utiliser alternativement les anciens lecteur ou ce nouveau.
Je ne connaissais pas ce système de clavier "virtuel", et l'ancien développeur du projet à uniquement codé l'acquisition des touches, mais cela ne fonctionne pas bien.
Sur la vue principal:
Sur l'évènement Loaded:
Dans STATIC_FUNCTION j'avais uniquement cela:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 using RawInputProcessor; using System.Windows.Input; using System.Windows.Navigation; private void NavigationWindow_Loaded(object sender, RoutedEventArgs e) { _rawInput = new RawPresentationInput(this, RawInputCaptureMode.Foreground); _rawInput.KeyPressed += STATIC_FUNCTION.OnKeyPressed; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public static void OnKeyPressed(object sender, RawInputEventArgs e) { if (e.Device.Name.Contains("HID#VID_076B&PID_5428")) { if (e.Key.String() != "LeftShift") { inData += e.Key.String(); LastRecpBadge2 = DateTime.Now; } } }
Et ensuite il regardait uniquement si InData contenait quelque chose.
Bon ce n'est qu'une ébauche.
Le lecteur semble assez complet, il est possible, entre autre, d'ajouter des caractères de début et de fin où, comme je pense utiliser, un caractère envoyé lorsque la carte n'est plus sur le lecteur.
Le code de ma carte de test est A39D2BBD, ainsi j'ai ajouté "&" en début et "#" lorsque la carte est retiré du lecteur, et avec le bloc note j'ai parfaitement &A39D2BBD#. Mais cela se complique dans le logiciel.
1) Déjà il regarde le nom du périphérique. (e.Device.Name.Contains("HID#VID_076B&PID_5428")) c'est bien le mien, je suppose que chaque périphérique aura peut être un nom diffèrent, ou une partie commune permettant d'identifier que c'est bien le lecteur de carte, et pas un simple clavier.
2) La simple conversion de e.Key.ToString(), ne donne pas la bonne valeur non plus.
Le & est représenté par D1
Le # par D3.
J'ai trouvé une fonction qui permet de me donner la bonne valeur:
Avec cela j'ai bien mes caractères & et #, mais pour le reste ce n'est pas top non plus.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public enum MapType : uint { MAPVK_VK_TO_VSC = 0x0, MAPVK_VSC_TO_VK = 0x1, MAPVK_VK_TO_CHAR = 0x2, MAPVK_VSC_TO_VK_EX = 0x3, } [DllImport("user32.dll")] public static extern int ToUnicode( uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)] StringBuilder pwszBuff, int cchBuff, uint wFlags); [DllImport("user32.dll")] public static extern bool GetKeyboardState(byte[] lpKeyState); [DllImport("user32.dll")] public static extern uint MapVirtualKey(uint uCode, MapType uMapType); public static char GetCharFromKey(Key key) { char ch = ' '; int virtualKey = KeyInterop.VirtualKeyFromKey(key); byte[] keyboardState = new byte[256]; GetKeyboardState(keyboardState); uint scanCode = MapVirtualKey((uint)virtualKey, MapType.MAPVK_VK_TO_VSC); StringBuilder stringBuilder = new StringBuilder(2); int result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0); switch (result) { case -1: break; case 0: break; case 1: { ch = stringBuilder[0]; break; } default: { ch = stringBuilder[0]; break; } } return ch; }
Voila du coup ce que je me suit fait:
J'ai 2 buffers histoire de voir la différence entre le retour de GetCharFromKey et e.Key.ToString();
Au point d'arrêt j'ai sa:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 static string BufferBadgeString = ""; static string BufChar = ""; static bool EnterCard = false; public static void OnKeyPressed(object sender, RawInputEventArgs e) { if (e.Device.Name.Contains("HID#VID_076B&PID_5428")) { System.Windows.Input.Key mKey = e.Key; char mK = GetCharFromKey(mKey); if (mK == '#') { //Fin de trame trouvé //point d'arrêt ici EnterCard = false; inData = BufChar ; } else if (mK == '&') { //Début de trame EnterCard = true; } else if (EnterCard) { BufChar += mK; if (mKey.ToString() != "LeftShift") BufferBadgeString += mKey.ToString(); } } }
BufChar = " A a 3 \" 9 ç D d 2 é B b B b D d "
BufferBadgeString ="AAD3D3D9D9DDD2D2BBBBDDLeftCtrlLeftAlt"
L'un comme l'autre ce n'est pas terrible.
Filtrer LeftShift semble convenir car sinon il se retrouve entre chaque caractère de BufferBadgeString.
Si je filtre LeftShift avant, BuffChar = "Aa3\"9çDd2éBbBbDd "
La capture ne semble pas bonne. Mettre des point d'arrêt pendant la boucle est compliqué, car du coup cela écrit dans Visual Studio directement.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 if (mKey.ToString() == "LeftShift") { return; }
Concernant le lecteur ont défini aussi qu'il est en clavier Français, sur un environnement Windows. C'est un lecteur HID OMNIKEY 5427.
Avez vous une solution qui me permettrait d'avoir ce que le Bloc note reçois parfaitement.
Merci
Partager