首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#并非所有键盘事件都能正确重播

C#并非所有键盘事件都能正确重播
EN

Stack Overflow用户
提问于 2009-09-09 18:32:57
回答 1查看 1.2K关注 0票数 0

我正在为验证工程师编写一个工具,以便在尝试重现失败时记录会话交互。它创建了一段桌面视频,我将键盘和鼠标挂在C#上,以记录它们与操作系统的交互。这些事件被序列化到一个文件中,以便稍后读入。我使用SendInput重播鼠标和键盘事件。

除了重放剪切和粘贴交互之外,所有的东西都运行得很好。CTRL-Insert SHIFT-Insert

有人知道我做错了什么吗?

我的钩子代码:

代码语言:javascript
运行
复制
   // if it's a keyboard event
{

   Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
   KeyEventArgs e = new KeyEventArgs(keyData);                    
   MyKeyEventArgs akea = new MyKeyEventArgs();
   akea.ExtraInfo = GetMessageExtraInfo();
   akea.Code = wParam;
   akea.KeyArgs = e;
   KeyDown(this, akea); // call to my event handler
}

我的SendInput代码

代码语言:javascript
运行
复制
    // if it's a keyboard event
    {
     case KeyBoardHook.WM_KEYUP:
        tssKeyPress.Text = hec.KeyCode.ToString() + " Up";
        mi.mkhi.mi.dwExtraInfo = hec.ExtraInfo;
        k.mkhi.ki.dwFlags = KEYEVENTF_KEYUP;
        if (
            ((int)hec.KeyCode >= (int)VK.VK_PRIOR && (int)hec.KeyCode <= (int)VK.VK_DELETE) ||
            ((int)hec.KeyCode >= (int)VK.VK_LWIN && (int)hec.KeyCode <= (int)VK.VK_APPS) ||
            ((int)hec.KeyCode >= (int)VK.VK_SPACE && (int)hec.KeyCode <= (int)VK.VK_HELP) ||
            ((int)hec.KeyCode >= (int)VK.VK_SHIFT && (int)hec.KeyCode <= (int)VK.VK_MENU)
           )
        {
            k.mkhi.ki.dwFlags += KEYEVENTF_EXTENDEDKEY;
        }
        k.mkhi.ki.wVk = (ushort)hec.KeyCode;
        k.mkhi.ki.wScan = 0;
        //k.mkhi.mi.wScan = (short)hec.KeyData;
        k.mkhi.mi.time = 0;
        SendInput(1, ref k, Marshal.SizeOf(k));
        break;
    case KeyBoardHook.WM_KEYDOWN:
        tssKeyPress.Text = hec.KeyCode.ToString() + " Down";

        k.mkhi.ki.time = 0;
        k.mkhi.ki.dwExtraInfo = IntPtr.Zero;
        if (
            ((int)hec.KeyCode >= (int)VK.VK_PRIOR && (int)hec.KeyCode <= (int)VK.VK_DELETE ) ||
            ((int)hec.KeyCode >= (int)VK.VK_LWIN && (int)hec.KeyCode <= (int)VK.VK_APPS) ||
            ((int)hec.KeyCode >= (int)VK.VK_SPACE && (int)hec.KeyCode <= (int)VK.VK_HELP) ||
            ((int)hec.KeyCode >= (int)VK.VK_SHIFT && (int)hec.KeyCode <= (int)VK.VK_MENU)
           )
        {
            k.mkhi.ki.dwFlags += KEYEVENTF_EXTENDEDKEY;
        }
        k.mkhi.ki.dwFlags = 0;
        k.mkhi.ki.wVk = (ushort)hec.KeyCode;
        k.mkhi.ki.wScan = 0;
        //k.mkhi.mi.wScan = (short)hec.KeyData;
        SendInput(1, ref k, Marshal.SizeOf(k));
        break;
}
EN

回答 1

Stack Overflow用户

发布于 2009-09-10 17:01:48

以下是我重放键盘的有效解决方案:

代码语言:javascript
运行
复制
case KeyBoardHook.WM_KEYUP:
    tssKeyPress.Text = hec.KeyCode.ToString() + " Up";
    k.mkhi.mi.dwExtraInfo = hec.ExtraInfo;
    k.mkhi.ki.dwFlags = KEYEVENTF_KEYUP;
    SetExtendedFlag( hec.KeyCode, ref k );
    k.mkhi.ki.wScan = 0;
    k.mkhi.mi.time = 0;
    SendInput(1, ref k, Marshal.SizeOf(k));
    break;
case KeyBoardHook.WM_KEYDOWN:
    tssKeyPress.Text = hec.KeyCode.ToString() + " Down";
    k.mkhi.mi.dwExtraInfo = hec.ExtraInfo;
    k.mkhi.ki.time = 0;
    k.mkhi.ki.dwFlags = 0;
    SetExtendedFlag( hec.KeyCode, ref k );
    k.mkhi.ki.wScan = 0;
    SendInput(1, ref k, Marshal.SizeOf(k));
    break;

private void SetExtendedFlag(Keys keys, ref INPUT k )
{
    k.mkhi.ki.wVk = (ushort)keys;
    if (((int)keys == (int)VK.VK_LSHIFT && (int)keys == (int)VK.VK_RSHIFT))
    {
        k.mkhi.ki.wVk = (ushort)VK.VK_SHIFT;
    }
    if (((int)keys == (int)VK.VK_LCONTROL && (int)keys == (int)VK.VK_RCONTROL))
    {
        k.mkhi.ki.wVk = (ushort)VK.VK_CONTROL;
    }
    if (((int)keys == (int)VK.VK_LMENU && (int)keys == (int)VK.VK_RMENU))
    {
        k.mkhi.ki.wVk = (ushort)VK.VK_MENU;
    }
    switch ((int)keys)
    {
        case((int) VK.VK_RMENU):
        case ((int)VK.VK_RCONTROL):                
        case ((int)VK.VK_INSERT):
        case ((int)VK.VK_DELETE):
        case ((int)VK.VK_LEFT):
        case ((int)VK.VK_HOME):
        case ((int)VK.VK_END):
        case ((int)VK.VK_UP):
        case ((int)VK.VK_DOWN):
        case ((int)VK.VK_PRIOR):
        case ((int)VK.VK_NEXT):
        case ((int)VK.VK_RIGHT):
        case ((int)VK.VK_LWIN):
        case ((int)VK.VK_RWIN):
        case ((int)VK.VK_APPS):
        case ((int)VK.VK_SLEEP):
            k.mkhi.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
            break;
    }
}

我现在可以使用CTRL-INSERT和SHIFT-INSERT成功地重放复制、剪切和粘贴。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1401315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档