Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Mär 28, 2024 12:40

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Windows Keyboard Eingabe
BeitragVerfasst: Mo Mai 16, 2016 14:01 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich spiele aktuell mit imgui rum und im Rahmen desssen hab ich die Tastatureingabe in meinem Framework überarbeiten wollen.
In der Vergangenheit hab ich WM_KEYDOWN und WM_KEYUP messages verarbeitet und mir da die Zahlen und ANSI Buchstaben raus gezogen.
Ctrl, Shift, Alt und co hab ich dabei nicht beachtet und das wollte ich nun mal ausbauen und bin auf einige Wege und diverse Probleme gestoßen.
Also mein Ziel ist es Unicode als UTF-8 ins System weiter zu leiten, Tastenkombinationen richtig zu repräsentieren und die Modifier Tasten korrekt zu erkennen.

WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_CHAR und WM_UNICHAR sind die wichtigsten Messages für Tastatureingabe, es gibt noch welche für Tote Tasten und es gibt diverse Ausnahmen und sonderreglen wie Tasten/Tastenkombinationen in welcher Message verarbeitet werden und mit Unicode wurde das ganze komplizierter.
Da ich nicht wirklich das Problem neu lösen wollte hab ich mir SDL, SFML und GLFW angeguckt und alle lösen es unterschiedlich, bzw. haben auch einige Probleme Ignoriert.
Ich konnte also keine richtige Lösung bisher finden.

Hier mal mein aktueller Code.
Code:
  1. VirtualKey MapWindowsToRadonVirtualKeys(WPARAM wParam, LPARAM lParam)
  2. {
  3.     VirtualKey vk = VirtualKey::NotSet;
  4.  
  5.     // Numpad
  6.     auto hiFlags = HIWORD(lParam);
  7.     static const RF_Type::UInt16 KEYDOWNBIT = 1 << 15;
  8.     static const RF_Type::UInt16 EXTENDEDKEYBIT = 1 << 8;
  9.     static const RF_Type::UInt16 SCANCODEBITS = 255;
  10.     if((hiFlags & EXTENDEDKEYBIT) == 0)
  11.     {
  12.         switch(MapVirtualKey(hiFlags & SCANCODEBITS, MAPVK_VSC_TO_VK))
  13.         {
  14.             case VK_INSERT: vk = VirtualKey::Keypad0; break;
  15.             case VK_END: vk = VirtualKey::Keypad1; break;
  16.             case VK_DOWN: vk = VirtualKey::Keypad2; break;
  17.             case VK_NEXT: vk = VirtualKey::Keypad3; break;
  18.             case VK_LEFT: vk = VirtualKey::Keypad4; break;
  19.             case VK_CLEAR: vk = VirtualKey::Keypad5; break;
  20.             case VK_RIGHT: vk = VirtualKey::Keypad6; break;
  21.             case VK_HOME: vk = VirtualKey::Keypad7; break;
  22.             case VK_UP: vk = VirtualKey::Keypad8; break;
  23.             case VK_PRIOR: vk = VirtualKey::Keypad9; break;
  24.             case VK_DIVIDE: vk = VirtualKey::KeypadDivide; break;
  25.             case VK_MULTIPLY: vk = VirtualKey::KeypadMultiply; break;
  26.             case VK_SUBTRACT: vk = VirtualKey::KeypadSubtract; break;
  27.             case VK_ADD: vk = VirtualKey::KeypadAdd; break;
  28.             case VK_DELETE: vk = VirtualKey::KeypadDecimal; break;
  29.             default:
  30.                 break;
  31.         }
  32.     }
  33.  
  34.     switch(wParam)
  35.     {
  36.         case VK_ESCAPE:vk = VirtualKey::Escape; break;
  37.         case VK_TAB: vk = VirtualKey::Tab; break;
  38.         case VK_BACK: vk = VirtualKey::Backspace; break;
  39.         case VK_HOME: vk = VirtualKey::Home; break;
  40.         case VK_END: vk = VirtualKey::End; break;
  41.         case VK_INSERT: vk = VirtualKey::Insert; break;
  42.         case VK_DELETE: vk = VirtualKey::Delete; break;
  43.         case VK_PRIOR:vk = VirtualKey::PageUp; break;
  44.         case VK_NEXT:vk = VirtualKey::PageDown; break;
  45.         case VK_LEFT:vk = VirtualKey::Left; break;
  46.         case VK_UP:vk = VirtualKey::Up; break;
  47.         case VK_RIGHT:vk = VirtualKey::Right; break;
  48.         case VK_DOWN:vk = VirtualKey::Down; break;
  49.         case VK_SHIFT:
  50.         {
  51.             // both shift keys have the extended bit set but use different virtual keys
  52.             auto virtualKey= MapVirtualKey(VK_RSHIFT, 0);
  53.             if((hiFlags & (EXTENDEDKEYBIT | SCANCODEBITS)) == virtualKey)
  54.             {
  55.                 vk = VirtualKey::ShiftRight;
  56.             }
  57.             else
  58.             {
  59.                 vk = VirtualKey::ShiftLeft;
  60.             }
  61.             break;
  62.         }
  63.         case VK_CONTROL:
  64.         {
  65.             if(hiFlags & EXTENDEDKEYBIT)
  66.             {
  67.                 vk = VirtualKey::ControlRight;
  68.             }
  69.             else
  70.             {
  71.                 vk = VirtualKey::ControlLeft;
  72.             }
  73.             break;
  74.         }
  75.         case VK_MENU:
  76.         {
  77.             if(hiFlags & EXTENDEDKEYBIT)
  78.             {
  79.                 vk = VirtualKey::AltRight;
  80.             }
  81.             else
  82.             {
  83.                 vk = VirtualKey::AltLeft;
  84.             }
  85.             break;
  86.         }
  87.         case VK_RETURN:
  88.         {
  89.             if(hiFlags & EXTENDEDKEYBIT)
  90.             {
  91.                 vk = VirtualKey::KeypadEnter;
  92.             }
  93.             else
  94.             {
  95.                 vk = VirtualKey::Enter;
  96.             }
  97.         }
  98.     }
  99.     if (wParam >= VK_F1 && wParam <= VK_F12)
  100.         vk = (VirtualKey)((int)(VirtualKey::F1) + (wParam - VK_F1));
  101.     return vk;
  102. }
  103.  
  104. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  105. {
  106.     static const RF_Type::UInt16 EXTENDEDKEYBIT = 1 << 8;
  107.  
  108.     WindowsWindow *wnd=0;
  109.     Size2D<> size;
  110.     Point2D<> pos;
  111.     VirtualKey vk=VirtualKey::NotSet;
  112.     switch (uMsg)
  113.     {
  114. ...
  115.     case WM_CHAR:
  116.     case WM_SYSCHAR:
  117.     {
  118.         if((lParam & (1 << 30)) == 0)
  119.         {
  120.             RF_Type::UInt32 glyph = static_cast<RF_Type::UInt32>(wParam);
  121.             if((glyph >= 0xD800) && (glyph <= 0xDBFF))
  122.             {
  123.                 MSG nextMessage;
  124.                 if(PeekMessageW(&nextMessage, NULL, 0, 0, PM_NOREMOVE))
  125.                 {// check if there is an other message without removing it from the queue
  126.                     if(nextMessage.message == WM_CHAR ||
  127.                        nextMessage.message == WM_SYSCHAR)
  128.                     {
  129.                         RF_Type::UInt32 glyphPart = static_cast<RF_Type::UInt32>(nextMessage.wParam);
  130.                         if((glyphPart >= 0xDC00) && (glyphPart <= 0xDFFF))
  131.                         {
  132.                             WCHAR multybyteText[3] = {static_cast<WCHAR>(glyph), static_cast<WCHAR>(glyphPart),0};
  133.                             char languageUtf8[LOCALE_NAME_MAX_LENGTH];
  134.                             size_t writtenBytes = wcstombs(languageUtf8, multybyteText, LOCALE_NAME_MAX_LENGTH);
  135.                             if(writtenBytes > 0)
  136.                             {
  137.                                 wnd = dynamic_cast<WindowsWindow*>(WindowsWindow::GetObjectByHandle(hWnd));
  138.                                 KeyboardEvent event;
  139.                                 event.PrintableCharacter = RF_Type::String(languageUtf8, writtenBytes + 1);
  140.                                 wnd->OnKeyPress(event);
  141.                             }
  142.                         }
  143.                     }
  144.                 }
  145.             }
  146.             else
  147.             {
  148.                 WCHAR multybyteText[2] = {static_cast<WCHAR>(glyph),0};
  149.                 char languageUtf8[LOCALE_NAME_MAX_LENGTH];
  150.                 size_t writtenBytes = wcstombs(languageUtf8, multybyteText, LOCALE_NAME_MAX_LENGTH);
  151.                 if(writtenBytes > 0)
  152.                 {
  153.                     wnd = dynamic_cast<WindowsWindow*>(WindowsWindow::GetObjectByHandle(hWnd));
  154.                     KeyboardEvent event;
  155.                     event.Key = VirtualKey::NotSet;
  156.                     event.PrintableCharacter = RF_Type::String(languageUtf8, writtenBytes + 1);
  157.                     wnd->OnKeyPress(event);
  158.                 }
  159.             }
  160.         }
  161.         break;
  162.     }
  163.     case WM_SYSKEYDOWN:
  164.     case WM_KEYDOWN:
  165.     {
  166.         wnd=dynamic_cast<WindowsWindow*>(WindowsWindow::GetObjectByHandle(hWnd));
  167.         if(wParam == VK_CONTROL)
  168.         {// right alt key will throw 2 messages, first left control and then right alt key
  169.             auto hiFlags = HIWORD(lParam);
  170.             if(hiFlags & EXTENDEDKEYBIT != 0)
  171.             {// current message is a left control key
  172.                 auto messageTime = GetMessageTime();
  173.                 MSG nextMessage;
  174.                 if(PeekMessageW(&nextMessage, NULL, 0, 0, PM_NOREMOVE))
  175.                 {// check if there is an other message without removing it from the queue
  176.                     if(nextMessage.message == WM_KEYDOWN ||
  177.                        nextMessage.message == WM_SYSKEYDOWN)
  178.                     {
  179.                         if(nextMessage.wParam == VK_MENU &&
  180.                             (HIWORD(nextMessage.lParam) & EXTENDEDKEYBIT) &&
  181.                            nextMessage.time == messageTime)
  182.                         {// remove the left control key message
  183.                             return -1;
  184.                         }
  185.                     }
  186.                 }
  187.             }
  188.         }
  189.  
  190.         KeyboardEvent event;
  191.         event.Key = MapWindowsToRadonVirtualKeys(wParam, lParam);
  192.         if(event.Key != VirtualKey::NotSet)
  193.         {
  194.             wnd->OnKeyPress(event);
  195.         }
  196.         break;
  197.     }
  198.     case WM_SYSKEYUP:
  199.     case WM_KEYUP:
  200.     {
  201.         wnd=dynamic_cast<WindowsWindow*>(WindowsWindow::GetObjectByHandle(hWnd));
  202.         if(wParam == VK_CONTROL)
  203.         {// right alt key will throw 2 messages, first left control and then right alt key
  204.             auto hiFlags = HIWORD(lParam);
  205.             if(hiFlags & EXTENDEDKEYBIT != 0)
  206.             {// current message is a left control key
  207.                 auto messageTime = GetMessageTime();
  208.                 MSG nextMessage;
  209.                 if(PeekMessageW(&nextMessage, NULL, 0, 0, PM_NOREMOVE))
  210.                 {// check if there is an other message without removing it from the queue
  211.                     if(nextMessage.message == WM_KEYUP ||
  212.                        nextMessage.message == WM_SYSKEYUP)
  213.                     {
  214.                         if(nextMessage.wParam == VK_MENU &&
  215.                             (HIWORD(nextMessage.lParam) & EXTENDEDKEYBIT) &&
  216.                            nextMessage.time == messageTime)
  217.                         {// remove the left control key message
  218.                             return -1;
  219.                         }
  220.                     }
  221.                 }
  222.             }
  223.         }
  224.  
  225.         KeyboardEvent event;
  226.         event.Key = MapWindowsToRadonVirtualKeys(wParam, lParam);
  227.         if(event.Key != VirtualKey::NotSet)
  228.         {
  229.             wnd->OnKeyRelease(event);
  230.         }
  231.         break;
  232.     }
  233. ...
  234.     }
  235.     return DefWindowProcW(hWnd,uMsg,wParam,lParam);
  236. // KeyboardEvent.hpp
  237. class KeyboardEvent
  238. {
  239. public:
  240.     KeyboardEvent():Key(VirtualKey::NotSet), Ctrl(false), Alt(false), Shift(false){}
  241.     RF_Type::String PrintableCharacter;
  242.     VirtualKey Key;
  243.     RF_Type::Bool Ctrl;
  244.     RF_Type::Bool Alt;
  245.     RF_Type::Bool Shift;
  246. };
  247. // VirtualKey.hpp
  248. enum class VirtualKey : RF_Type::UInt8
  249. {
  250.     NotSet,
  251.     Escape,
  252.     Left,
  253.     Up,
  254.     Right,
  255.     Down,
  256.     ShiftLeft,
  257.     ShiftRight,
  258.     ControlLeft,
  259.     ControlRight,
  260.     AltLeft,
  261.     AltRight,
  262.     Enter,
  263.     Tab,
  264.     Backspace,
  265.     Insert, Delete, Home, End, PageUp, PageDown,
  266.     Keypad0, Keypad1, Keypad2, Keypad3, Keypad4, Keypad5, Keypad6, Keypad7, Keypad8, Keypad9,
  267.     KeypadDivide, KeypadMultiply, KeypadSubtract, KeypadAdd, KeypadDecimal, KeypadEnter,
  268.     F1, F2, F3, F4, F5, F6, F7,F8, F9, F10, F11, F12
  269. };


Der Code Löst aktuell folgende Problem.
*Unterscheidung von linken und rechten Modifier Tasten(Shift, Ctrl, Alt)
*Unicode zu UTF-8

Was nicht geht sind.
*Modifier mit Unicode z.B. ctrl+v
*Der Code sieht ziemlich unübersichtlich aus und ist auf dauer schwer zu warten, da er Logisch mit allen Platformen kompatibel sein muss.

Hat wer Vorschläge und/oder Lösungen ?

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Windows Keyboard Eingabe
BeitragVerfasst: Mo Mai 16, 2016 17:54 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ohne genau den Scope zu verstehen (ist der Code da nur für Windows? WM klingt irgendwie so).

Eingabe ist superfrickelig und einer der Gründe warum ich auf ein vollständiges GUI-Framework (Qt) umgestiegen bin für Spieleentwicklung. Spätestens sobald man Textinput hat und der User keine Standardeingabemethode sondern irgendwas mit Compose-Magie benutzt wird es anstrengend. X11 kann ja die wildesten Dinge was das betrifft, man muss theoretisch ein Fenster bereitstellen können wo die Eingabemethode einen Zwischenzustand reinrendern kann für so arkane Eingabemodi (ich glaube für chinesisch).

Das ist mir alles zu haarig. Um aber zum Punkt zurückzukommen: Das ist denke ich der Grund, warum SDL & Co. das Problem versuchen möglichst zu ignorieren. Das ist einfach eine Hausnummer zu groß für so eher kleine Frameworks; eine vollständige Lösung findet man dann eher bei GTK und Qt.

viele Grüße,
Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Windows Keyboard Eingabe
BeitragVerfasst: Di Mai 17, 2016 11:42 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Das gehört zum Radon Framework und ich hab das Windows Backend erweitert.
Ich habe die Hoffnung, dass ich nicht der einzige bin, der sich mit dem Thema auseinander setzt und wollte dazu mal die Erfahrungen hören und eventuell bei mir was ändern.

Aktuell hab ich ne Lösung die geht aber die ist halt ziemlich frickelig.
Also Unicode, Tastenkombinationen und normale Tasten gehen aber ich halte den aktuellen Code für sehr Wartungsintensive, weil er viele Logische Bedingungen hat, die zu unterschiedlichen Verhalten in der Applikation führen könnten, wenn man von Platform zu Platform hüpft.
| und ~ sind aktuell die einzigen Zeichen die bei mir nicht wollen, weil die über AltGr + '<' und AltGr + '+' gehen. Da hab ich irgendein dreh noch nicht raus.

Da merkt man schon mal, dass die API echt alt ist(WinXP/Win2k).
Ein Forumbeitrag, den ich gefunden habe hat es sehr gut beschrieben.
Die API sieht so aus als ob jemand am Zeichenbrett es versucht hat in verschiedene Teile zu zerschlagen und getrennt zu lösen und dann die Realität kam.

WM_CHAR, WM_UNICHAR sind für Texteingabe aber kodieren noch modifier in den Wert, was bei Shift(h wird zu H und 5 zu %) und AltGr(3. belegung von Tasten) sinn macht aber nicht bei Ctrl(sind nur für Hotkeys).
WM_CHAR ist UTF16 und kann als Surrogate kommen, wenn es nicht in ein UTF16 passt, da gibt es aber wohl nur 2x UTF16, wobei es theoretisch eigentlich noch 3x UTF16 für ein Zeichen geben könnte aber die unterstützt Windows nicht.
WM_UNICHAR ist UTF32 und kommen einzeln, Windows hat aber kein Nativen support für UTF32 zu UTF8.
Hier hatte ich mein Problem, weil ich UTF8 überall benutze.
SFML hat sich da was eigenes gebastelt, weil UTF32->16->8 ist dann doch arg lahm, weil das Zeichenweise aufgerufen werden muss.
Ich hab daher WM_CHAR genommen, weil Windows UTF16->8 für Strings anbietet und der c++ Standard auch eine passende Funktion hat.
Die Funktion(wcstombs), scheint gut optimiert zu sein, die ist sehr flink, die gleichnamige aus dem C++ Standard hab ich nicht getestet.

WM_KEYDOWN/UP, WM_DEADKEY, WM_SYSKEYDOWN/Up, WM_SYSDEADKEY sind nur für Logische eingaben gedacht, also Shortcuts, Cursorbewegung und co.
Dort werden die Modifiertasten als Message aber auch im internen MessageQueue gelagert.
Wenn man also Ctrl+A abfangen will, dann sollte man mit GetKeyState den Modifier abfragen, wenn der Key code 'A' ist, statt erst Ctrl und dann A abfragen zu wollen.
Windows lagert die ganzen Tastaturmessages, wo noch der Counterpart nicht verarbeitet wurde intern und GetKeyState guckt genau in der Liste.
Also ist WM_KEYDOWN mit Ctrl gekommen aber noch nicht bei WM_KEYUP, bekommt man VK_CONTROL zurück.
Sollte man aber nicht mit GetASyncKeyState verwechseln, den Fehler hatte SFML und GLWF gemacht, denn die Funktion fragt die Hardware direkt und nutzt nicht die Message Queue. Daher ist die nicht nur langsamer, sondern sogar in einigen schrägen Fällen Falsch.
Diese Funktionen kennen nur alle Hardware-Tasten in der erstbelegung, da die Modifier nicht auf die Tasten angewendet werden, dass bekommen wir ja von WM_CHAR/UNICHAR.
Dann macht das ganze auch auf einmal Sinn, wieso man 0-9, a-z und einige weitere sondertasten hat.
Windows wirft erstmal die Physikalische Taste über WM_KEYDOWN/UP und je nach Sprache und Tastarturlayout vom User wird dann diese umgewandelt und über WM_CHAR/UNICHAR zurück gegeben.
So wird dann aus der Taste '['(WM_KEYDOWN) ein 'ü'(WM_CHAR) auf dem Deutschen Tastaturlayout.

Soweit ist nun mein Wissensstand.

QT und Delphi haben die Events auch getrennt und so hab ich das nun auch gemacht, um weitere Komplexität zu ersparen.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Windows Keyboard Eingabe
BeitragVerfasst: Mi Mai 18, 2016 17:16 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
mhh ja Keyboard kann ziemlich nervig werden unter Windows. Da kommt halt der ganze Legacy-Kram von alten IBM-Keyboards und co. mal richtig zum tragen. Der einfachste Weg ist es wenn du nur die Char-Events verarbeitest und KeyDown / KeyUp mittels RawInput behandelst. Damit umgehst du zumindest solche Geschichten wie z.B. die AltGr Problematik und kannst die relativ easy ein eigenes virtuelles Keyboard basteln. Meine Handler hierfür schaut wie folgt aus:

Code:
  1.  
  2.         case window_message_types::Input:
  3.  
  4.             GetRawInputData((HRAWINPUT) lParam, RID_INPUT, nullptr, &rawInputSize, sizeof(RAWINPUTHEADER));
  5.             if (GetRawInputData((HRAWINPUT) lParam, RID_INPUT, &rawInput,
  6.                                 &rawInputSize, sizeof(RAWINPUTHEADER)) == rawInputSize)
  7.             {
  8.  
  9.                 DWORD thread_id = GetCurrentThreadId();
  10.                 auto kbl = GetKeyboardLayout(thread_id);
  11.                 if (rawInput.header.dwType == RIM_TYPEKEYBOARD)
  12.                 {
  13.                     auto &keyboardData = rawInput.data.keyboard;
  14.                     UINT virtualKey = keyboardData.VKey;
  15.                     UINT scanCode = keyboardData.MakeCode;
  16.                     UINT flags = keyboardData.Flags;
  17.                     if (virtualKey == 255)
  18.                     {
  19.                         return wParam == RIM_INPUT;
  20.                     }
  21.                     if (virtualKey == VK_CONTROL)
  22.                     {
  23.                         if ((flags & RI_KEY_E0) != 0)
  24.                         {
  25.                             virtualKey = VK_RCONTROL;
  26.                         }
  27.                         else
  28.                         {
  29.                             virtualKey = VK_LCONTROL;
  30.                         }
  31.                     }
  32.                     else if (virtualKey == VK_MENU)
  33.                     {
  34.                         if ((flags & RI_KEY_E0) != 0)
  35.                         {
  36.                             virtualKey = VK_RMENU;
  37.                         }
  38.                         else
  39.                         {
  40.                             virtualKey = VK_LMENU;
  41.                         }
  42.                     }
  43.                     else if (virtualKey == VK_RETURN)
  44.                     {
  45.                         if ((flags & RI_KEY_E0) != 0)
  46.                         {
  47.                             virtualKey = (unsigned int) virtual_keys::Enter;
  48.                         }
  49.                     }
  50.                     else if (virtualKey == VK_SHIFT)
  51.                     {
  52.                         virtualKey = MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK_EX, kbl);
  53.                     }
  54.                     else if (virtualKey != VK_LWIN && virtualKey != VK_RWIN && virtualKey != VK_DIVIDE)
  55.                     {
  56.                         if ((flags & RI_KEY_E1) != 0)
  57.                         {
  58.                             if (virtualKey == VK_PAUSE)
  59.                             {
  60.                                 virtualKey = 0x45;
  61.                             }
  62.                             else
  63.                             {
  64.                                 scanCode = MapVirtualKeyEx(virtualKey, MAPVK_VK_TO_VSC, kbl);
  65.                             }
  66.                         }
  67.                         if ((flags & RI_KEY_E0) != 0)
  68.                         {
  69.                             switch (virtualKey)
  70.                             {
  71.                                 case VK_INSERT:
  72.                                 case VK_END:
  73.                                 case VK_DOWN:
  74.                                 case VK_NEXT:
  75.                                 case VK_LEFT:
  76.                                 case VK_CLEAR:
  77.                                 case VK_RIGHT:
  78.                                 case VK_HOME:
  79.                                 case VK_UP:
  80.                                 case VK_PRIOR:
  81.                                 case VK_DELETE:
  82.                                     virtualKey = MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK_EX, kbl);
  83.                                     break;
  84.  
  85.                             }
  86.                         }
  87.  
  88.  
  89.                     }
  90.                     if (keyboardData.Message == WM_KEYDOWN || keyboardData.Message == WM_SYSKEYDOWN)
  91.                     {
  92.                         window_message m
  93.                                 {
  94.                                         window_message_types::KeyDown,
  95.                                         (WPARAM) virtualKey,
  96.                                         (LPARAM) wParam == RIM_INPUT
  97.                                 };
  98.                         startupMessageBuffer.push_back(m);
  99.                     }
  100.                     else
  101.                     {
  102.                         window_message m
  103.                                 {
  104.                                         window_message_types::KeyUp,
  105.                                         (WPARAM) virtualKey,
  106.                                         (LPARAM) wParam == RIM_INPUT
  107.                                 };
  108.                         startupMessageBuffer.push_back(m);
  109.                     }
  110.                 }
  111.             }
  112.             return wParam == RIM_INPUT;
  113.  

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Windows Keyboard Eingabe
BeitragVerfasst: Fr Mai 20, 2016 16:26 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2621
Wohnort: Berlin
Programmiersprache: Go, C/C++
Das liest sich erstmal ziemlich gut.
Ich hab noch ein bisschen gegoogelt, weil ich wissen wollte, ob man Tasten verschlucken kann, leider schreibt keiner was dazu aber Indirekt sagt Molecular-Matters, dass es die beste Wahl ist für nicht Texteingabe.
WM_INPUT von Molecular-Matters
Also werde ich WM_KEYDOWN,WM_SYSKEYDOWN und co raus werfen und mit WM_CHAR und WM_INPUT weiter machen.
Das macht dann auch mein Code kleiner und weniger Wartungsintensive.

Damit hat es sich gelohnt das Topic auf zu machen und der nächste der sich fragt wie man richtig die Tastatur anbindet findet hier alles wichtige :)

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Windows Keyboard Eingabe
BeitragVerfasst: Fr Mai 20, 2016 17:18 
Offline
DGL Member
Benutzeravatar

Registriert: Mo Nov 08, 2010 18:41
Beiträge: 769
Programmiersprache: Gestern
Nu es gibt natürlich auch ToASCII und ToUnicode, aber keine Ahnung ob Umwandeln besser ist als die vorhandenen Nachrichten ...

_________________
Meine Homepage


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 21 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.061s | 17 Queries | GZIP : On ]