I am trying to create a simple open source utility for windows using Python that 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.
Usage is partially outlined in the following example:
What puzzles me is step 3. How the selected text is retrieved from the active window. This should work with all applications.
I use the pywin32 module.
Thanks in advance for your answers and tips.
Update #1:
Turns out that there are two approaches to accomplish the task:
As starting points:
Get the active window ID as Anurag Uniyal has pointed out in his reply.
Or get the window object with the following code:
import win32ui
wnd = win32ui.GetForegroundWindow()
print wnd.GetWindowText()
the code below will work only on simple text boxes (just did it in VB6, and ported to python)
edit: it was tested only on 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()
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With