简体   繁体   English

从热键启动时,将SendInput转换为Ctrl + C文本不起作用

[英]SendInput to Ctrl+C text Doesn't Work When Launched from Hotkey

Currently using this code to Copy selected text in currently open Window in Windows 10. This code is working fine if I run it on its own by when my target program (Notepad) has focus. 当前正在使用此代码在Windows 10的当前打开的窗口中复制选定的文本。如果我在目标程序(记事本)具有焦点时自行运行该代码,则此代码可以正常工作。 The selected text in notepad is copied into data variable OK. 在记事本中选择的文本将复制到数据变量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
    }
}

However, if I launch the exact same code via Hotkey, it doesn't work: 但是,如果我通过热键启动完全相同的代码,它将无法正常工作:

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";
        }
    }
}

Now, in both cases, GetWindowText() is showing the title of the program I want to copy text from. 现在,在两种情况下, GetWindowText()都显示了我要从中复制文本的程序的标题。

In addition, I wrote a simple test utility to check Ctrl+C is being passed to Window, which it is. 另外,我编写了一个简单的测试实用程序,以检查Ctrl + C是否传递给了Window。 It seems like Ctrl+C is being passed, but the copy is not occurring. 似乎正在传递Ctrl + C ,但是没有发生复制。

Is it possible that Alt is still down because of the hotkey and you are actually sending Ctrl + Alt + C ? 由于热键, Alt是否仍然处于关闭状态,而您实际上正在发送Ctrl + Alt + C SendInput inserts the input directly into the global input queue. SendInput将输入直接插入到全局输入队列中。

You could try setting a timer in response to the hotkey and call GetAsyncKeyState in the timer handler until all modifier keys are up before generating input. 您可以尝试设置一个响应于热键的计时器,并在计时器处理程序中调用GetAsyncKeyState ,直到所有修改器键都打开,然后再生成输入。

A better alternative would be to use UI Automation instead of a hack like this. 更好的选择是使用UI自动化而不是像这样的黑客。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c++ 上的 SendInput 不考虑 Ctrl 和 Shift - SendInput on c++ doesn't take Ctrl and Shift in account 如果一个是由system()或CreateProcess()从另一个程序启动的,如何阻止Ctrl + Break / Ctrl + C关闭这两个程序? - how to prevent Ctrl+Break/Ctrl+C from closing both programs if one was launched from another by system() or CreateProcess()? 将Ctrl + C事件发送到在Windows上使用QProcess启动的进程 - Sending Ctrl+C event to a process launched using QProcess on Windows SendInput() function 在游戏中不起作用(C++) - SendInput() function doesn't work inside game (C++) 客户端关闭(使用Ctrl + C键)后,错误10093不会阻塞 - accept() doesn't block after client close (with Ctrl+C) error 10093 INPUT / vector数组不适用于SendInput - Array of INPUT / vector doesn't work with SendInput SendInput不适用于Print Screen键 - SendInput doesn't work with Print Screen key 如何使用 CTRL+C 停止从用户那里获取输入? - How to use CTRL+C to stop getting input from the user? 当 Ctrl 在“C”之前释放时,如何使用 Qt 捕获 Ctrl+C 键事件? - How to catch Ctrl+C key event with Qt when Ctrl is released before 'C'? 使用 SendInput 或 mouse_event 不适用于 clock()? - Using SendInput or mouse_event doesn't work with clock()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM