如何使用本机Win32 API从聚焦窗口中获取所选文本?
我的应用程式将在系统上运行尝试监控一个热键;当用户在任何窗口中选择一些文本并按下热键时,如何获取所选文本,当我收到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编程首先可能相当令人生畏,但过了一段时间…还是令人生畏的。 干杯! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows – 使用带有Dell Perc 4e(LSI)的RAID时如何访问SMA
- microsoft-office – 用于Microsoft Office 2013安装的Serv
- windows-server-2008 – Windows Server 2008 r2目录可以安
- Office 365 REST Api和Microsoft Graph之间的区别
- 为什么VS.NET会尝试为WPF和ClickOnce包含Microsoft.Windows
- windows-7 – 最佳实践 – Windows 7 Remote Road Warrior笔
- wcf – 无法启动服务.无法注册网址
- windows – 有什么方法可以在Vista X64上本地播放quicktime
- windows-server-2003 – RAID-1驱动器故障 – 丢失的数据是
- 如何在Window窗体中使用UserControl编程C#