Reputation: 151
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()
Upvotes: 15
Views: 19259
Reputation: 1
It appears that while the clipboard and associated copy and paste shortcuts are ubiquitous, they must be added to applications by developers. The best bet is to use a listener to capture when ctrl+c is activated, check that the clipboard is not in use and has data on it, and then manipulate the data from there.
You can check out Microsoft's dev page here:
Upvotes: 0
Reputation: 16610
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()
Upvotes: 2
Reputation: 88757
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
edit: also while experimenting use spy++ to see how it retrieves information about various windows, see hwnd, window class etc
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
Upvotes: 1
Reputation: 6894
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.
Upvotes: 1