VB.NET: In ProcessCmdKey simplest way to determine if a key prints or not?

旧巷老猫 提交于 2020-01-15 08:23:01

问题


What's the simplest way to identify whether a keystroke is a printable character (one that should appear in a textbox) or not? I want to separate keys like F1, Home, etc. from those that would actually appear in a textbox. I am trying to avoid a massive IF statement by identifying all the non-printable characters myself.

Using an event like KeyUp, KeyPress etc. is not an option due to the design of the control.


回答1:


There is no simple way. And you should never put yourself in this spot. The translation of virtual keys, as observed in ProcessCmdKey or KeyDown, to typing keys, as observed by the KeyPress event, is highly convoluted. It depends on the keyboard layout that the user has selected. Keyboard layouts vary a great deal from machine to machine across the world. A Chinese keyboard doesn't look much like an English keyboard, surely you can imagine this. Furthermore, languages with a lot of characters, like Chinese and Japanese, use a dedicated program to allow the user to select one of tens of thousands of glyphs. An IME (Input Method Editor).

Notably problematic too are the "dead keys", special keys on some keyboards that are used to enter letters with diacritics. Not common in English, very common in other parts of the world. Like the AltGr key on a German keyboard. Such layouts are very stateful, a key produces a different typing character depending on that state. In other words, what dead keys were pressed before. This state is also process specific and cannot be retrieved by another process.

I probably didn't scare you enough, hard to do with an English speaking programmer. Caution to the wind, and it sounds like you only want to do this for your own process, you can pinvoke the ToUnicodeEx() winapi function. It needs the keyboard state, you get that from pinvoking GetKeyboardState(). It needs the active keyboard layout, you get that from GetKeyboardLayout(). Which needs the thread ID, you get that from GetCurrentThreadId(). A return value of 1 or more indicates that the KeyPress event is likely to fire. Visit pinvoke.net to have a shot at getting the pinvoke declarations correct.



来源:https://stackoverflow.com/questions/16218249/vb-net-in-processcmdkey-simplest-way-to-determine-if-a-key-prints-or-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!