【问题标题】:Could not send backspace key using ::SendInput() to wordpad application无法使用 ::SendInput() 将退格键发送到写字板应用程序
【发布时间】:2010-03-10 23:33:52
【问题描述】:

我已经使用 sendinput() 函数和 windows 键盘挂钩来开发印度语言的自定义键盘。 项目在谷歌代码中:http://code.google.com/p/ekalappai

键盘钩子和sendinput函数被放置在一个win32 dll中。它们是从 Qt exe 调用的。 我们的应用程序适用于大多数键和应用程序。我发现以下问题:

我无法将 Backspace 键发送到 Wordpad/Openoffice/MsOffice 等少数应用程序。我发现箭头键和删除键有同样的问题。

这是我的代码:

extern "C" __declspec(dllexport) void GenerateKey(int vk , bool bExtended)
{
    //update previous characters
    previous_2_character = previous_1_character;
    previous_1_character = vk;

    KEYBDINPUT kb={0};
    INPUT Input={0};

    //keydown
    kb.wVk    =  0;
    kb.wScan = vk;/*enter unicode here*/;
    kb.dwFlags = KEYEVENTF_UNICODE; // KEYEVENTF_UNICODE=4
    Input.type = INPUT_KEYBOARD;
    Input.ki = kb;

    ::SendInput(1,&Input,sizeof(Input));

    //keyup
    kb.wVk    =  0;
    kb.wScan = vk;/*enter unicode here*/;
    kb.dwFlags = KEYEVENTF_UNICODE|KEYEVENTF_KEYUP; //KEYEVENTF_UNICODE=4
    Input.type = INPUT_KEYBOARD;
    Input.ki = kb;

    ::SendInput(1,&Input,sizeof(Input));
}

完整的 dll 代码在这里:http://code.google.com/p/ekalappai/source/browse/trunk/ekhook/ekhook/dllmain.cpp

调用代码:

generatekey = (GenerateKey) myLib->resolve( "GenerateKey" );

generatekey(44,FALSE); //comma - THis works in wordpad/MsOffice/Openoffice
generatekey(2949,FALSE); //tamil character "a" works in Wordpad/Msoffice/Openoffice

generatekey(8,FALSE); //backspace - This is NOT working in Wordpad/Msoffice/Openoffice

Qt Exe 的完整调用代码在这里: http://code.google.com/p/ekalappai/source/browse/trunk/ekalappai/window.cpp

我尝试在谷歌中搜索,但还没有找到合适的解决方案。如果有人有解决此问题的线索,请提供帮助。谢谢。

【问题讨论】:

    标签: c++ winapi qt4 keyboard sendinput


    【解决方案1】:

    您混淆了虚拟键和扫描码。 wVk 成员是重要的成员,只有在虚拟键不明确时才会使用扫码。修复:

    kb.wVk   = vk;
    kb.wScan = 0;   // TODO: look at VkKeyScanEx()
    

    【讨论】:

    • 否...来自文档:“如果 dwFlags 成员指定 KEYEVENTF_UNICODE,wVk 必须为 0。” msdn.microsoft.com/en-us/library/ms646271(VS.85).aspx
    • 成功了!是的,对于发送 unicode 字符,我保留了现有代码(即 kb.wVK = 0)。对于其他非字符键,例如退格键,我使用了 kb.wVK = vk;我的问题就解决了。感谢大家的帮助:)
    • 请注意上面的文档链接:如果您要设置 wVk,那么您应该删除 KEYEVENTF_UNICODE。如果在您的系统 上忽略对 有效的内容,则可能只是一个怪癖或错误。当人们实现诸如 Wine 模拟器之类的东西时,他们会根据文档进行操作,而您不会通过使用未记录的行为来为他们提供服务。此外,Microsoft 可能会发布一个补丁程序,使例程合规并破坏您的程序。
    【解决方案2】:

    文档说:

    如果指定了 KEYEVENTF_UNICODE,SendInput 将 WM_KEYDOWN 或 WM_KEYUP 消息发送到前台线程的消息队列,其中 wParam 等于 VK_PACKET。一旦 GetMessage 或 PeekMessage 获得此消息,将消息传递给 TranslateMessage 就会发布一条 WM_CHAR 消息,该消息具有最初由 wScan 指定的 Unicode 字符。

    只是一个猜测,但文字处理程序可能会触发 WM_KEYDOWN/WM_KEYUP 消息而不是 WM_CHAR 的退格行为。因此他们可能期望 VK_BACKSPACE(不是 VK_PACKET)作为这些消息的 wParam。甚至可以使用基于 VKEY 而不是字符的加速器来完成……哎呀,你在 Windows 上,所以几乎一切皆有可能。 :)

    您是否尝试过不使用 KEYEVENTF_UNICODE,而使用 kb.wVk = VK_BACKSPACE

    (另外,您可以使用 Spy++ 更好地了解哪些关键消息被发送到目标应用程序,以及它与按文字退格键时有何不同。)

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 2014-04-06
      • 1970-01-01
      • 2014-02-25
      • 2010-12-16
      • 1970-01-01
      • 2021-10-13
      • 2013-06-20
      相关资源
      最近更新 更多