我想从应用程序中的任何窗口捕获关键事件,并将它们解释为Unicode。例如,如果用户键入 Option-e-e (在默认配置的美国英语键盘上),我想将其识别为“é”。
我尝试捕获按键事件并调用-[NSEvent characters]
。但是,正如文档中所述,“此方法为死键返回一个空字符串,例如Option-e。”如果我输入 Option-ee ,则它不会为 Option-e 提供任何内容,而为第二个 e 提供简单的“e”。
有没有办法将一系列密码(从-[NSEvent keyCode]
)组合成Unicode字符?
或者为每个键入的Unicode字符(如Java's key-typed event)接收事件的方法?
答案 0 :(得分:10)
这是一种获取一系列按键事件并获取他们键入的Unicode字符的方法。
基本上,请为收到的每个按键事件致电UCKeyTranslate()。使用其deadKeyState
参数捕获死键并将其传递给后续调用。
示例:
UCKeyTranslate()
州。
UCKeyTranslate()
输出一个空字符串并更新死键状态。 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);
}
答案 1 :(得分:0)
将想要捕获“é”事件的视图/窗口子类化,并添加此实例变量
BOOL optionE_Pressed;
然后,覆盖keyDown:使用此
-(void) keyDown:(NSEvent *)theEvent {
NSString *chars = theEvent.charactersIgnoringModifiers;
unichar aChar = [chars characterAtIndex: 0];
if (aChar==101 && [theEvent modifierFlags]&NSAlternateKeyMask) {
optionE_Pressed=YES;
}
else if (aChar==101 && optionE_Pressed) {
NSLog(@"spanish é pressed");
}
else {
optionE_Pressed=NO;
}
[super keyDown:theEvent];
}
当用户按下选项和e键时,将激活布尔变量“optionE_Pressed”。如果按下的下一个键是e,意味着它们已经有效地创建了西班牙语é,那么它将记录“西班牙语é按下”。否则,Boolien将切换回NO。最后的“超级”调用允许用户仍然可以正常输入所有事件