如何从活动窗口中检索所选文本

时间:2009-06-17 13:54:58

标签: python windows winapi pywin32

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

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

  1. 用户使用鼠标或键盘(在任何应用程序窗口中)选择一些文本
  2. 用户按下预定义的键盘快捷键
  3. 我们的实用程序检索所选文本或将其复制到剪贴板(两种方法都应该没问题)
  4. 对所选文本执行与键盘快捷键相关的操作
  5. 让我感到困惑的是第3步如何从活动窗口中检索所选文本。这适用于所有应用程序。

    我使用 pywin32 模块。

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

    更新#1

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

    1. 找到活动窗口,然后向其发送消息/按键(Ctrl-C),以便将所选文本复制到剪贴板。然后,该实用程序可以使用与剪贴板相关的函数访问文本来处理文本。
    2. 找到活动窗口,然后直接检索所选文本(不将其复制到剪贴板)。这似乎比第一种方法更难。
    3. 作为起点:

      获取Anurag Uniyal在reply中指出的活动窗口ID。

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

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

4 个答案:

答案 0 :(得分:2)

下面的代码只适用于简单的文本框(只是在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()

答案 1 :(得分:1)

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

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

也许您必须使用FindWindowFindWindowEx才能获得具有焦点的子窗口

编辑:同时在试验中使用spy ++来查看它如何检索各种窗口的信息,请参阅hwnd,window class等

基本上如果你能在C / C ++ / C#中找到一个例子,将它转换成pywin32等价就不难了,所以在某种程度上它是win32 api的具体问题

答案 2 :(得分:1)

使用Ctrl-C方法会好得多。直接获取文本将适用于类似编辑控件的内容,但对于检索应用程序直接在其自己的窗口上绘制的文本无效。

答案 3 :(得分:0)

似乎剪贴板和相关的复制和粘贴快捷方式无处不在,但开发人员必须将其添加到应用程序中。最好的选择是激活ctrl + c时使用侦听器捕获,检查剪贴板未在使用中并且上面有数据,然后从那里操作数据。您可以在此处查看Microsoft的开发页面。

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