加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

如何使用本机Win32 API从聚焦窗口中获取所选文本?

发布时间:2020-12-13 20:53:44 所属栏目:Windows 来源:网络整理
导读:我的应用程式将在系统上运行尝试监控一个热键;当用户在任何窗口中选择一些文本并按下热键时,如何获取所选文本,当我收到WM_HOTKEY消息? 要将文本捕获到剪贴板,我尝试使用keybd_event()和SendInput()发送Ctrl C到活动窗口(GetActiveWindow())和forground窗
我的应用程式将在系统上运行尝试监控一个热键;当用户在任何窗口中选择一些文本并按下热键时,如何获取所选文本,当我收到WM_HOTKEY消息?

要将文本捕获到剪贴板,我尝试使用keybd_event()和SendInput()发送Ctrl C到活动窗口(GetActiveWindow())和forground窗口(GetForegroundWindow());尝试组合这些;都徒劳无功可以使用简单的Win32系统API在Windows中获取关注窗口的选定文本吗?

TL; DR:是的,有一种使用简单的win32系统API执行此操作的方法,但是很难正确实现。

WM_COPY和WM_GETTEXT可能工作,但不是在所有情况下。它们依赖于正确处理请求的接收窗口 – 在许多情况下它不会。让我运行一个可能的方法来做到这一点。它可能不像你希望的那么简单,但是在win32编程的冒险世界里呢是什么?准备?好。我们走吧。

首先我们需要获取目标窗口的HWND ID。有很多方法可以做到这一点。一个这样的方法是你上面提到的:获取前景窗口,然后是焦点的窗口等。但是,有一个巨大的骗子,许多人忘记了。获取前台窗口后,您必须使用AttachThreadInput获取焦点的窗口。否则GetFocus()将简单地返回NULL。

有一个更简单的方法。简单(小姐)使用GUITREADINFO功能。它更安全,因为它避免了与另一个程序连接输入线程相关联的所有隐患。

LPGUITHREADINFO lpgui = NULL;
HWND target_window = NULL;

if( GetGUIThreadInfo( NULL,lpgui ) )
    target_window = lpgui->hwndFocus;
else
{
    // You can get more information on why the function failed by calling
    // the win32 function,GetLastError().
}

发送按键来复制文本有更多的参与…

我们将使用SendInput而不是keybd_event,因为它更快,最重要的是不能被并发用户输入或其他模拟键击的程序弄乱。

这的确意味着该程序将需要在Windows XP或更高版本上运行,所以,对不起,如果你运行98!

// We're sending two keys CONTROL and 'V'. Since keydown and keyup are two
// seperate messages,we multiply that number by two.
int key_count = 4;

INPUT* input = new INPUT[key_count];
for( int i = 0; i < key_count; i++ )
{
    input[i].dwFlags = 0;
    input[i].type = INPUT_KEYBOARD;
}

input[0].wVK = VK_CONTROL;
input[0].wScan = MapVirtualKey( VK_CONTROL,MAPVK_VK_TO_VSC );
input[1].wVK = 0x56 // Virtual key code for 'v'
input[1].wScan = MapVirtualKey( 0x56,MAPVK_VK_TO_VSC );
input[2].dwFlags = KEYEVENTF_KEYUP;
input[2].wVK = input[0].wVK;
input[2].wScan = input[0].wScan;
input[3].dwFlags = KEYEVENTF_KEYUP;
input[3].wVK = input[1].wVK;
input[3].wScan = input[1].wScan;

if( !SendInput( key_count,(LPINPUT)input,sizeof(INPUT) ) )
{
    // You can get more information on why this function failed by calling
    // the win32 function,GetLastError().
}

那里。那没那么坏,是吗

现在我们只需要看看剪贴板上的内容。这不像你先想的那么简单。 “剪贴板”实际上可以容纳同一件事情的多个表示。复制到剪贴板时活动的应用程序可以控制要在剪贴板中放置的内容。

例如,当您从Microsoft Office复制文本时,它会将RTF数据放入剪贴板,以及相同文本的纯文本表示。这样可以将其粘贴到wordpad和记事本中。写字板将使用富文本格式,而记事本将使用纯文本格式。

对于这个简单的例子,我们假设我们只对纯文本感兴趣。

if( OpenClipboard(NULL) )
{
    // Optionally you may want to change CF_TEXT below to CF_UNICODE.
    // Play around with it,and check out all the standard formats at:
    // http://msdn.microsoft.com/en-us/library/ms649013(VS.85).aspx
    HGLOBAL hglb = GetClipboardData( CF_TEXT );
    LPSTR lpstr = GlobalLock(hglb);

    // Copy lpstr,then do whatever you want with the copy.

    GlobalUnlock(hglb);
    CloseClipboard();
}
else
{
    // You know the drill by now. Check GetLastError() to find out what
    // went wrong. :)
}

在那里你有它!只需确保将lpstr复制到要使用的变量,不要直接使用lpstr,因为我们必须在关闭剪贴板的内容之前对其进行控制。

Win32编程首先可能相当令人生畏,但过了一段时间…还是令人生畏的。

干杯!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读