如何在没有NSTextView的情况下从关键事件中捕获Unicode [英] How to capture Unicode from key events without an NSTextView
问题描述
我想从应用程序的任何窗口捕获关键事件,并将其解释为Unicode.例如,如果用户键入 Option-e-e (在默认配置的美国英语键盘上),我想将其识别为é".
我尝试捕获按键事件并调用-[NSEvent characters]
.但是,如文档中所述,此方法为空键返回空字符串,例如Option-e."如果我键入 Option-ee ,那么对于 Option-e 它没有任何帮助,而对于第二个 e 则为普通的"e". >
是否可以将一系列键码(来自-[NSEvent keyCode]
)组合成Unicode字符?
或者一种为每个键入的Unicode字符接收事件的方式(例如 Java的键类型事件)?
这是采取一系列按键事件并获取其键入的Unicode字符的方法.
基本上,调用收到每个按键事件的UCKeyTranslate().使用其deadKeyState
参数捕获死键并将其传递给后续调用.
示例:
- 接收 Option-e 的按键事件.
- 使用虚拟键代码(对于 e ),修饰键状态(对于 Option )和用于存储死键状态的变量调用
UCKeyTranslate()
.-
UCKeyTranslate()
输出一个空字符串并更新死键状态.
-
- 接收 e 的按键事件.
- 使用虚拟键代码(用于 e )和保存死键状态的变量调用
UCKeyTranlate()
.-
UCKeyTranslate()
输出é".
-
示例代码(每次按键事件调用的函数):
/**
* Returns the Unicode characters that would be typed by a key press.
*
* @param event A key press event.
* @param deadKeyState To capture multi-keystroke characters (e.g. Option-E-E for "é"), pass a reference to the same
* variable on consecutive calls to this function. Before the first call, you should initialize the variable to 0.
* @return One or more Unicode characters.
*/
CFStringRef getCharactersForKeyPress(NSEvent *event, UInt32 *deadKeyState)
{
// http://stackoverflow.com/questions/12547007/convert-key-code-into-key-equivalent-string
// http://stackoverflow.com/questions/8263618/convert-virtual-key-code-to-unicode-string
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef layoutData = TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
CGEventFlags flags = [event modifierFlags];
UInt32 modifierKeyState = (flags >> 16) & 0xFF;
const size_t unicodeStringLength = 4;
UniChar unicodeString[unicodeStringLength];
UniCharCount realLength;
UCKeyTranslate(keyboardLayout,
[event keyCode],
kUCKeyActionDown,
modifierKeyState,
LMGetKbdType(),
0,
deadKeyState,
unicodeStringLength,
&realLength,
unicodeString);
CFRelease(currentKeyboard);
return CFStringCreateWithCharacters(kCFAllocatorDefault, unicodeString, realLength);
}
I'd like to capture key events from any window in the application and interpret them as Unicode. For example, if the user types Option-e-e (on a default-configured US English keyboard), I would like to recognize that as "é".
I tried capturing keypress events and calling -[NSEvent characters]
. However, as it says in the documentation, "This method returns an empty string for dead keys, such as Option-e." If I type Option-e-e, then it gives me nothing for the Option-e and plain "e" for the second e.
Is there a way to combine a series of keycodes (from -[NSEvent keyCode]
) into a Unicode character?
Or a way to receive an event for each Unicode character typed (like Java's key-typed event)?
Here's a way to take a series of key press events and get the Unicode character(s) they'd type.
Basically, call UCKeyTranslate() for each key press event received. Use its deadKeyState
argument to capture a dead key and pass it along to the subsequent call.
Example:
- Receive key press event for Option-e.
- Call
UCKeyTranslate()
with the virtual key code (for e), the modifier key state (for Option), and a variable to store the dead key state.UCKeyTranslate()
outputs an empty string and updates the dead key state.
- Receive key press event for e.
- Call
UCKeyTranlate()
with the virtual key code (for e) and the variable that holds the dead key state.UCKeyTranslate()
outputs "é".
Sample code (the function to call for each key press event):
/**
* Returns the Unicode characters that would be typed by a key press.
*
* @param event A key press event.
* @param deadKeyState To capture multi-keystroke characters (e.g. Option-E-E for "é"), pass a reference to the same
* variable on consecutive calls to this function. Before the first call, you should initialize the variable to 0.
* @return One or more Unicode characters.
*/
CFStringRef getCharactersForKeyPress(NSEvent *event, UInt32 *deadKeyState)
{
// http://stackoverflow.com/questions/12547007/convert-key-code-into-key-equivalent-string
// http://stackoverflow.com/questions/8263618/convert-virtual-key-code-to-unicode-string
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef layoutData = TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
CGEventFlags flags = [event modifierFlags];
UInt32 modifierKeyState = (flags >> 16) & 0xFF;
const size_t unicodeStringLength = 4;
UniChar unicodeString[unicodeStringLength];
UniCharCount realLength;
UCKeyTranslate(keyboardLayout,
[event keyCode],
kUCKeyActionDown,
modifierKeyState,
LMGetKbdType(),
0,
deadKeyState,
unicodeStringLength,
&realLength,
unicodeString);
CFRelease(currentKeyboard);
return CFStringCreateWithCharacters(kCFAllocatorDefault, unicodeString, realLength);
}
这篇关于如何在没有NSTextView的情况下从关键事件中捕获Unicode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!