在Delphi XE中,我正在尝试实现一个"即时搜索"功能 - 一种类似于Firefox的"在键入时搜索"的功能,但在开源剪贴板扩展器中类似的功能更好地说明了,Ditto:

有一个处理典型导航事件的项目列表.但是,任何字母数字键以及导航和编辑命令(向右/向左箭头,移位+箭头,退格键,删除等)都应该重新路由到列表下方的编辑框.编辑框的OnChange事件将触发刷新列表.
UI的要点是用户不必在控件之间使用制表符或shift键.这两个控件(列表和编辑框)应该"感觉"好像它们是单个控件.搜索UI的行为不应该取决于哪个控件具有焦点.
似乎我最好的选择是将某些键盘事件从列表控件(我使用TcxTreeList)转发到编辑框,并将一些导航键从编辑框转发到列表.我怎样才能做到这一点?
笔记:
TcxTreeList当然支持增量搜索,但这不是我追求的.搜索转到SQLite数据库并查找子字符串匹配.该列表仅显示db中的匹配项.
有一些重叠,例如两个控件通常会处理VK_HOME和VK_END,但这没关系 - 在这种情况下,键将进入列表.我需要决定是否转发每个单独的按键,或者在接收它的控件中处理它.
在编辑: 一个显而易见的方法似乎是调用编辑控件的相应KeyDown,KeyUp和KeyPress方法,如下所示:
type
THackEdit = class( TEdit );
procedure TMainForm.cxTreeList1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
THackEdit( edit1 ).KeyDown( Key, Shift );
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这没有任何效果.我的猜测是TEdit不会处理关键事件,除非它是专注的.使用SendMessage(THackEdit(edit1).Handle,WM_KEYDOWN,Key,0)也没有效果.
我将子类化为NSView并在应用程序完成启动时启动全屏模式.该视图作为fooView应用程序委托中的属性提供.
// AppDelegate.m
- (void)applicationDidFinishLaunching:(NSNotification*)notification {
[[self window] makeKeyAndOrderFront:self];
[[self fooView] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];
}
Run Code Online (Sandbox Code Playgroud)
该类FooView本身实现了以下功能.
// FooView.m
- (void)keyDown:(NSEvent*)event {
NSLog(@"%@ %@ - %@", self.className, NSStringFromSelector(_cmd), event);
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
- (void)cancelOperation:(id)sender {
NSLog(@"%@ %@ - %@", self.className, NSStringFromSelector(_cmd), sender);
[self exitFullScreenModeWithOptions:nil];
}
Run Code Online (Sandbox Code Playgroud)
离开全屏模式后,视图不再接收键盘事件.为什么?
编辑:
这似乎与我退出全屏模式的方式有关.当我点击视图(而不是窗口)时,keyDown:并cancelOperation:在下面做出响应.
我正在尝试向应用程序发送WM_INPUT消息,但是遇到一些我无法解决的障碍。我创建了如下的RAWINPUT结构:
//try sending 'W'
RAWINPUT raw = {0};
char c = 'W';
//header
raw.header.dwSize = sizeof(raw);
raw.header.dwType = RIM_TYPEKEYBOARD;
raw.header.wParam = 0; //(wParam & 0xff =0 => 0)
raw.header.hDevice = hDevice;
//data
raw.data.keyboard.Reserved = 0;
raw.data.keyboard.Flags = RI_KEY_MAKE; //Key down
raw.data.keyboard.MakeCode = static_cast<WORD>(MapVirtualKeyEx(c, MAPVK_VK_TO_VSC, GetKeyboardLayout(0)));
raw.data.keyboard.Message = WM_KEYDOWN;
raw.data.keyboard.VKey = VkKeyScanEx(c, GetKeyboardLayout(0));
raw.data.keyboard.ExtraInformation = 0; //???
//Send the message
SendMessage(hPSWnd, WM_INPUT, 0, (LPARAM)raw/*Raw input handle*/); //TODO: Handle to raw input
Run Code Online (Sandbox Code Playgroud)
我卡住的位置至少是两个位置:
是否需要将特殊的东西传递给raw.data.keyboard.ExtraInformation,或者是GetMessageExtraInfo(),或者是否不需要在这里传递任何东西?
WM_INPUT消息的LPARAM参数包含RAWINPUT结构的句柄,而不是地址或结构本身...如何创建这样的句柄?
我不想使用SendInput,因为它要求该窗口为活动窗口。我已经做到了,并且工作正常,但是当我激活另一个窗口时(当然),它停止了在前一个窗口上的工作。
因此,我想实现的目标是,将输入发送到不需要处于活动状态的应用程序。
我正在编写一些执行简单键盘事件捕获的测试应用程序。
我对这种基本方法没有任何疑问。
但是,现在我需要对我的应用程序有更好的体验,并且我想连接至少两个或多个USB或PS / 2键盘,区分哪个键盘是按键事件的来源,以便能够通过JavaScript在本地使用Web浏览器(和HTML5),就好像它是同时具有多个控制器的游戏控制台。
我知道即使在Windows或Linux下,正常的行为是使多个键盘触发相同的事件。但是,我也知道,完全有可能知道触发该事件的特定键盘硬件设备。
JavaScript是否可能或有限制?将来可能会支持同一基本类型的多个输入设备的区别,是否有其他选择(至少使用HTML5),或者在使用Web浏览器JavaScript的情况下几乎失去了希望和HTML5?
我所有的代码都基于linuxjournal.com上的一篇文章, 这是我基于我的代码编写的文章
我正在编写一个嵌入式应用程序,并且试图从键盘上读取按键。
这是我正在使用的代码
uint8_t key_b[KEY_MAX/8 + 1];
memset(key_b, 0, sizeof(key_b));
ioctl(fd, EVIOCGKEY(sizeof(key_b)), key_b);
for (yalv = 0; yalv < KEY_MAX; yalv++) {
if (test_bit(yalv, key_b)) {
/* the bit is set in the key state */
printf(" Key 0x%02x ", yalv);
switch ( yalv)
{
case KEY_RESERVED :
printf(" (Reserved)\n");
break;
case KEY_ESC :
printf(" (Escape)\n");
break;
/* other keys / buttons not shown */
case BTN_STYLUS2 :
printf(" (2nd Stylus Button )\n");
break;
case KEY_1:
printf("The key 1 …Run Code Online (Sandbox Code Playgroud) CapsLock似乎是重新映射的两个最棘手的键之一(另一个是电源按钮).
我可以全局拦截NSEvent-s:
_eventTap = CGEventTapCreate( kCGHIDEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit( kCGEventFlagsChanged ),
(CGEventTapCallBack)_tapCallback,
(__bridge void *)(self));
:
Run Code Online (Sandbox Code Playgroud)
但是,我没有为每个键上/下获得一个事件.实际发生的是:
(CapsLock的初始状态关闭)
按键:NSSystemDefined:40a00 NSSystemDefined:40b00(此时绿灯亮)
密钥:NSSystemDefined:40b00
按键:NSSystemDefined:40a00(此时绿灯熄灭)
关键:(没什么)
所以我无法在这个级别进行映射.
但我想我可以使用IOKit监视较低级别,IOKit检测每个键盘按键向下/向上事件,然后在此级别吃掉CAPSLOCK事件(通过返回NULL):
- (CGEventRef)processEvent:(CGEventRef)cgEvent
{
NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
NSUInteger modifiers = [event modifierFlags] &
( NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask | NSAlphaShiftKeyMask );
NSUInteger flags_changed = _modifiers ^ modifiers;
if( flags_changed & NSAlphaShiftKeyMask )
{
NSLog( @"Eating CAPSLOCK" );
return NULL;
}
_modifiers = modifiers;
:
Run Code Online (Sandbox Code Playgroud)
但是,这并不能阻止CapsLock做它的事情(即大写字母).
我甚至尝试从处理程序中的每个键盘事件中删除CapsLock修饰符标志:
if( modifiers & …Run Code Online (Sandbox Code Playgroud) 我在iPad Pro上尝试了3种不同的蓝牙键盘,我得到了相同的结果.一个是Logitech CLEAR iPad Pro键盘保护套,一个是Apple无线键盘,另一个是iPad智能键盘.
从keyup JavaScript事件检查事件对象时,无论按下哪个键,我都没有在事件对象中获取数据,以帮助我区分蓝牙键盘上按下了哪个键.这是我从事件对象得到的:
{
...
keyIdentifier: 0,
keyCode: 0,
key: undefined,
charCode: 0,
char: undefined,
which: 0,
...
}
Run Code Online (Sandbox Code Playgroud)
当然,当我在iOS中使用虚拟键盘时,一切正常,我得到了我需要的数据.
有没有人知道这方面的方法?或者,基于网络的应用程序,iPad的蓝牙键盘是否已经瘫痪?:(
我知道其他人也问了类似的问题,但我还没有看到明确的答案,我仍然被困住了.我正在尝试编写一个Swift函数,它接受硬件生成的键盘扫描代码,例如来自NSEvent,并返回密钥的alpha-caps-locked名称,用于特定的键排列(Dvorak,Qwerty等). )当前在OS中有效(可能与生成代码时生效的安排不同).
我的理解是,这样做的唯一方法就是调用一些非常古老的Carbon功能,避开Swift的极端类型安全性,这是我感觉不舒服的事情.这是The Show So Far:
import Cocoa
import Carbon
func keyName (scanCode: UInt16) -> String?
{ let maxNameLength = 4, modifierKeys: UInt32 = 0x00000004 // Caps Lock (Carbon Era)
let deadKeys = UnsafeMutablePointer<UInt32>(bitPattern: 0x00000000),
nameBuffer = UnsafeMutablePointer<UniChar>.alloc(maxNameLength),
nameLength = UnsafeMutablePointer<Int>.alloc(1),
keyboardType = UInt32(LMGetKbdType())
let source = TISGetInputSourceProperty ( TISCopyCurrentKeyboardLayoutInputSource()
.takeRetainedValue(),
kTISPropertyUnicodeKeyLayoutData )
let dataRef = unsafeBitCast(source, CFDataRef.self)
let dataBuffer = CFDataGetBytePtr(dataRef)
let keyboardLayout = unsafeBitCast(dataBuffer, UnsafePointer <UCKeyboardLayout>.self)
let osStatus = UCKeyTranslate (keyboardLayout, scanCode, UInt16(kUCKeyActionDown),
modifierKeys, keyboardType, UInt32(kUCKeyTranslateNoDeadKeysMask),
deadKeys, maxNameLength, …Run Code Online (Sandbox Code Playgroud) 我<textarea>在Elm中实现了这样一个功能,即制表符可以缩进和缩进,而不是将焦点更改为另一个HTML元素。效果很好,除了缩进有时会导致选择消失!如果要选择第5个字符到第12个字符,请按shift- tab,这将删除2个制表符,但同时也会使选择变为位置10的光标。选择范围应保持不变。
我在Ellie拥有SSCCE:https ://ellie-app.com/3x2qQdLqpHga1/2
这里是一些截图来说明问题。按安装程序将显示以下内容:
然后按Unindent 应该显示以下内容(“ def \ ng”的选择仍保持不变):
不幸的是,按Unindent 实际上显示以下内容。文字是没有锯齿的罚款,但选择范围消失而且也只是在之间的光标g和h:
我正在使用本机TextInput组件。如果用户单击textInput字段,则需要在键盘上方显示InputBox。
我在下面尝试过,但是我面临的问题
1.键盘避开视线
a. Here it shows some empty space below the input box
b. Manually I need to scroll up the screen to see the input field which I was given in the text field
c. Input box section is hiding while placing the mouse inside the input box
Run Code Online (Sandbox Code Playgroud)
2. react-native-keyboard-aware-scroll-view
a.It shows some empty space below the input box
b.ScrollView is reset to the top of the page after I moving to the next input box
Run Code Online (Sandbox Code Playgroud)
在这里,我在ScrollView组件内设置了键盘感知滚动视图
请澄清 …
keyboard-events ×10
javascript ×2
windows ×2
bluetooth ×1
c ×1
c++ ×1
capslock ×1
delphi ×1
elm ×1
forwarding ×1
fullscreen ×1
ioctl ×1
ios ×1
keyboard ×1
linux ×1
macos ×1
macos-carbon ×1
nsresponder ×1
nsview ×1
objective-c ×1
raw-input ×1
react-native ×1
safari ×1
selection ×1
swift ×1
textarea ×1
textbox ×1
textinput ×1
visual-c++ ×1