windows 如何从活动窗口中检索选定的文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1007185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to retrieve the selected text from the active window
提问by George Notaras
I am trying to create a simple open source utility for windows using Pythonthat can perform user-defined actions on the selected text of the currently active window. The utility should be activated using a pre-defined keyboard shortcut.
我正在尝试使用Python为 Windows 创建一个简单的开源实用程序,该实用程序可以对当前活动窗口的选定文本执行用户定义的操作。该实用程序应使用预定义的键盘快捷键激活。
Usage is partially outlined in the following example:
以下示例部分概述了用法:
- The user selects some text using the mouse or the keyboard (in any application window)
- The user presses a pre-defined keyboard shortcut
- The selected text is retrieved by our utility or copied to clipboard (both approaches should be fine)
- The keyboard shortcut-dependent action is performed on the selected text
- 用户使用鼠标或键盘选择一些文本(在任何应用程序窗口中)
- 用户按下预定义的键盘快捷键
- 所选文本由我们的实用程序检索或复制到剪贴板(两种方法都可以)
- 对所选文本执行依赖于键盘快捷键的操作
What puzzles me is step 3. How the selected text is retrieved from the active window. This should work with all applications.
令我困惑的是第 3 步。如何从活动窗口中检索所选文本。这应该适用于所有应用程序。
I use the pywin32module.
我使用pywin32模块。
Thanks in advance for your answers and tips.
预先感谢您的回答和提示。
Update #1:
更新#1:
Turns out that there are two approaches to accomplish the task:
事实证明,有两种方法可以完成任务:
- Find the active window, then send a message/keystroke (Ctrl-C) to it in order to copy the selected text to the clipboard. Then the utility can work on the text by accessing it using the clipboard-related functions.
- Find the active Window, then retrieve the selected text directly (without copying it to clipboard). This seems more difficult than the 1st approach.
- 找到活动窗口,然后向其发送消息/击键 (Ctrl-C) 以将所选文本复制到剪贴板。然后,该实用程序可以通过使用剪贴板相关功能访问文本来处理文本。
- 找到活动窗口,然后直接检索所选文本(无需将其复制到剪贴板)。这似乎比第一种方法更难。
As starting points:
作为起点:
Get the active window ID as Anurag Uniyal has pointed out in his reply.
获取 Anurag Uniyal 在他的回复中指出的活动窗口 ID 。
Or get the window object with the following code:
或者使用以下代码获取窗口对象:
import win32ui
wnd = win32ui.GetForegroundWindow()
print wnd.GetWindowText()
回答by Berry Tsakala
the code below will work only on simple text boxes (just did it in VB6, and ported to python)
下面的代码仅适用于简单的文本框(只是在 VB6 中完成,并移植到 python)
edit: it was tested only on python 2.6
编辑:它仅在 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()
回答by Anurag Uniyal
It won't be trivial but here is the starting point
这不是微不足道的,但这是起点
import win32gui
hwnd = win32gui.GetForegroundWindow()
print win32gui.GetWindowText(hwnd)
Maybe you will have to use FindWindow
,FindWindowEx
to get child windows with focus
也许您将不得不使用FindWindow
,FindWindowEx
来获得具有焦点的子窗口
edit: also while experimenting use spy++ to see how it retrieves information about various windows, see hwnd, window class etc
编辑:也在试验时使用 spy++ 来查看它如何检索有关各种窗口的信息,请参阅 hwnd、窗口类等
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
基本上,如果你能在 C/C++/C# 中找到一个例子,那么将它翻译成 pywin32 等价物并不难,所以在某种程度上它是 win32 api 的特定问题
回答by Bob Moore
You're far better off using the Ctrl-C method. Fetching text directly will work for something like an edit control, but is useless for retrieving text that an application has painted directly on its own window.
使用 Ctrl-C 方法会好得多。直接获取文本适用于编辑控件之类的东西,但对于检索应用程序直接在其自己的窗口上绘制的文本是无用的。