【问题标题】:How to retrieve the selected text from the active window如何从活动窗口中检索选定的文本
【发布时间】:2010-11-03 16:17:31
【问题描述】:

我正在尝试使用 Python 为窗口创建一个简单的开源实用程序,该实用程序可以对当前活动窗口的选定文本执行用户定义的操作。应使用预定义的键盘快捷键激活该实用程序。

以下示例中部分概述了用法:

  1. 用户使用鼠标或键盘选择一些文本(在任何应用程序窗口中)
  2. 用户按下预定义的键盘快捷键
  3. 所选文本由我们的实用程序检索或复制到剪贴板(两种方法都可以)
  4. 对选定文本执行与键盘快捷键相关的操作

让我感到困惑的是第 3 步如何从活动窗口中检索选定的文本。这应该适用于所有应用程序。

我使用 pywin32 模块。

提前感谢您的回答和提示。

更新 #1

原来有两种方法可以完成任务:

  1. 找到活动窗口,然后向它发送消息/击键 (Ctrl-C),以便将选定的文本复制到剪贴板。然后,该实用程序可以通过使用剪贴板相关功能访问文本来处理文本。
  2. 找到活动窗口,然后直接检索所选文本(无需将其复制到剪贴板)。这似乎比第一种方法更难。

作为起点:

获取活动窗口 ID,正如 Anurag Uniyal 在他的 reply 中指出的那样。

或者用如下代码获取window对象:

import win32ui
wnd = win32ui.GetForegroundWindow()
print wnd.GetWindowText()

【问题讨论】:

  • 你能澄清一下这个实用程序实际上是在创建活动窗口还是这个活动窗口来自不同的应用程序?
  • “活动窗口”是来自不同应用程序的窗口。此实用程序应在后台(或系统托盘)运行,并应使用预定义的按键激活。
  • 你知道如何检索选中的文本了吗?
  • 你知道如何检索选中的文本了吗???

标签: python windows winapi pywin32


【解决方案1】:

下面的代码只适用于简单的文本框(刚刚在 VB6 中完成,并移植到 python)

编辑:仅在 python 2.6 上测试过

from ctypes import *
import win32gui
import win32api
import win32con


user32 = windll.user32
kernel32 = windll.kernel32

class RECT(Structure):
 _fields_ = [
     ("left", c_ulong),
     ("top", c_ulong),
     ("right", c_ulong),
     ("bottom", c_ulong)
 ]

class GUITHREADINFO(Structure):
 _fields_ = [
     ("cbSize", c_ulong),
     ("flags", c_ulong),
     ("hwndActive", c_ulong),
     ("hwndFocus", c_ulong),
     ("hwndCapture", c_ulong),
     ("hwndMenuOwner", c_ulong),
     ("hwndMoveSize", c_ulong),
     ("hwndCaret", c_ulong),
     ("rcCaret", RECT)
 ]



def get_selected_text_from_front_window(): # As String
    ''' vb6 to python translation '''

    gui = GUITHREADINFO(cbSize=sizeof(GUITHREADINFO))
    txt=''
    ast_Clipboard_Obj=None
    Last_Clipboard_Temp = -1


    user32.GetGUIThreadInfo(0, byref(gui))

    txt = GetCaretWindowText(gui.hwndCaret, True)

    '''
    if Txt = "" Then
        LastClipboardClip = ""
        Last_Clipboard_Obj = GetClipboard
        Last_Clipboard_Temp = LastClipboardFormat
        SendKeys "^(c)"
        GetClipboard
        Txt = LastClipboardClip
        if LastClipboardClip <> "" Then Txt = LastClipboardClip
        RestoreClipboard Last_Clipboard_Obj, Last_Clipboard_Temp
        print "clbrd: " + Txt
    End If
    '''    
    return txt



def GetCaretWindowText(hWndCaret, Selected = False): # As String

    startpos =0
    endpos =0

    txt = ""

    if hWndCaret:

        buf_size = 1 + win32gui.SendMessage(hWndCaret, win32con.WM_GETTEXTLENGTH, 0, 0)
        if buf_size:
            buffer = win32gui.PyMakeBuffer(buf_size)
            win32gui.SendMessage(hWndCaret, win32con.WM_GETTEXT, buf_size, buffer)
            txt = buffer[:buf_size]

        if Selected and buf_size:
            selinfo  = win32gui.SendMessage(hWndCaret, win32con.EM_GETSEL, 0, 0)
            endpos   = win32api.HIWORD(selinfo)
            startpos = win32api.LOWORD(selinfo)
            return txt[startpos: endpos]

    return txt

if __name__ == '__main__':
    print get_selected_text_from_front_window()

【讨论】:

  • 我用 Python 3 测试了你的代码,它只返回 ,没有文本。
  • 我也是,我用3.7.3 python测试了你的代码,返回一个空字符串
【解决方案2】:

您最好使用 Ctrl-C 方法。直接获取文本将适用于编辑控件之类的东西,但对于检索应用程序直接在其自己的窗口上绘制的文本是无用的。

【讨论】:

  • 谢谢。这假定所有支持文本选择的应用程序都使用剪贴板。这可能适用于 99.99% 的应用程序,但您是否知道这是否是规则?
  • 请记住,有一些应用程序确实支持文本的剪贴板复制,但为 Ctrl+C 分配的含义与“剪贴板复制”不同。想到的一个例子是命令 shell (cmd.exe)。
【解决方案3】:

这不是微不足道的,但这是起点

import win32gui
hwnd = win32gui.GetForegroundWindow()
print win32gui.GetWindowText(hwnd)

也许你必须使用FindWindow,FindWindowEx 来获得焦点的子窗口

编辑:还在试验中使用 spy++ 来查看它如何检索有关各种窗口的信息,请参阅 hwnd、窗口类等

基本上,如果你能在 C/C++/C# 中找到一个示例,将其转换为 pywin32 等价物并不难,所以在某种程度上它是 win32 api 特定问题

【讨论】:

  • 我一直在使用以下内容获取活动窗口对象: import win32ui wnd = win32ui.GetForegroundWindow() print wnd.GetWindowText() 但我很难从那里获取选定的文本。感谢您的提示。我会调查 spy++。
  • 您好,我对basically if you can find a example in C/C++/C# it won't be difficult to translate that into pywin32 equivalent, so in a way it is win32 api specific question 有疑问,我可以在 64 位机器上使用它吗?
【解决方案4】:

看起来,虽然剪贴板和相关的复制和粘贴快捷方式无处不在,但开发人员必须将它们添加到应用程序中。最好的办法是使用监听器在 ctrl+c 被激活时进行捕获,检查剪贴板是否未使用并且上面有数据,然后对数据进行操作从那里开始。
你可以在这里查看微软的开发页面:

https://docs.microsoft.com/en-us/windows/win32/dataxchg/using-the-clipboard#implementing-the-cut-copy-and-paste-commands

【讨论】:

猜你喜欢
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 2010-12-26
  • 2017-04-19
  • 1970-01-01
相关资源
最近更新 更多