代码之家  ›  专栏  ›  技术社区  ›  Malcolm McCaffery

从热键启动时,将输入发送到Ctrl+C文本不起作用

  •  0
  • Malcolm McCaffery  · 技术社区  · 7 年前

    当前正在使用此代码在Windows 10中当前打开的窗口中复制选定的文本。如果我在目标程序(记事本)有焦点时自行运行此代码,则此代码工作正常。记事本中选定的文本被复制到数据变量OK中。

    wchar_t title[MAX_PATH];
    HWND target_window = GetForegroundWindow();
    GetWindowText(target_window, title, MAX_PATH);
    std::wcout << "Target window is '" << title << "'" << std::endl;
    
    // Send Control + C
    int key_count = 4;
    
    INPUT* input = new INPUT[key_count];
    for (int i = 0; i < key_count; i++)
    {
        input[i].ki.dwFlags = 0;
        input[i].type = INPUT_KEYBOARD;
    }
    
    input[0].ki.wVk = VK_CONTROL;
    input[0].ki.wScan = MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC);
    input[1].ki.wVk = 0x43; // Virtual key code for 'c'
    input[1].ki.wScan = MapVirtualKey(0x43, MAPVK_VK_TO_VSC);
    input[2].ki.dwFlags = KEYEVENTF_KEYUP;
    input[2].ki.wVk = input[0].ki.wVk;
    input[2].ki.wScan = input[0].ki.wScan;
    
    input[3].ki.dwFlags = KEYEVENTF_KEYUP;
    input[3].ki.wVk = input[1].ki.wVk;
    input[3].ki.wScan = input[1].ki.wScan;
    
    if (!SendInput(key_count, (LPINPUT)input, sizeof(INPUT)))
    {
        // TODO: error handling
    }
    else
    {
        // not ideal but not sure of another way to wait for SendInput to complete
        Sleep(100); 
        if (OpenClipboard(NULL))
        {
            HGLOBAL hglb = GetClipboardData(CF_UNICODETEXT);
            LPWSTR lpwstr = (LPWSTR)(GlobalLock(hglb));
            std::wstring data(lpwstr);
            GlobalUnlock(hglb);
            CloseClipboard();
            // do something with selected text in data
        }
        else
        {
            // TODO: error handling
        }
    }
    

    if (RegisterHotKey(
        NULL,
        1,
        MOD_CONTROL | MOD_ALT | MOD_NOREPEAT,
        VK_OEM_2))  // back slash question mark key
    {
        std::cout << "Hotkey 'Ctrl+Alt+/' registered, using MOD_NOREPEAT flag\n";
    }
    
    MSG msg = { 0 };
    while (GetMessage(&msg, NULL, 0, 0) != 0)
    {
        if (msg.message == WM_HOTKEY)
        {
            std::cout << "WM_HOTKEY received\n";
    
            // Call function to COPY TEXT here
    
            if (RegisterHotKey(
                NULL,
                1,
                MOD_CONTROL | MOD_ALT | MOD_NOREPEAT,
                VK_OEM_2))  // back slash question mark key
            {
                std::cout << "Hotkey 'Ctrl+Alt+/' registered, using MOD_NOREPEAT flag\n";
            }
        }
    }
    

    现在,在这两种情况下, GetWindowText()

    Ctrl+C 正在被传递到窗口,它就是。看起来像 Ctrl+C 正在传递,但没有复制。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Anders    7 年前

    有没有可能 由于热键,仍处于关闭状态,您实际上正在发送 Ctrl键 + 中高音 C ? SendInput 将输入直接插入全局输入队列。

    您可以尝试设置计时器以响应热键和呼叫 GetAsyncKeyState 在计时器处理程序中,直到所有修改键都启动,然后再生成输入。

    更好的选择是使用 UI Automation