2009-06-17 4 views
12

Sto cercando di creare una semplice utility open source per Windows utilizzando Python che può eseguire azioni definite dall'utente sul testo selezionato della finestra correntemente attiva. L'utilità dovrebbe essere attivata utilizzando una scorciatoia da tastiera predefinita.Come recuperare il testo selezionato dalla finestra attiva

uso è parzialmente illustrato nel seguente esempio:

  1. L'utente seleziona un testo utilizzando il mouse o la tastiera (in qualsiasi finestra dell'applicazione)
  2. l'utente preme un collegamento predefinito tastiera
  3. Il testo selezionato viene recuperato dalla nostra utilità o copiato negli appunti (entrambi gli approcci dovrebbero andare bene)
  4. L'azione dipendente dalla scelta rapida da tastiera viene eseguita sul testo selezionato

Quale puzzle mi è passaggio 3. Come viene recuperato il testo selezionato dalla finestra attiva. Questo dovrebbe funzionare con tutte le applicazioni.

Uso il modulo pywin32.

Grazie in anticipo per le vostre risposte e suggerimenti.

Update # 1:

scopre che ci sono due approcci per realizzare il compito:

  1. Trovare la finestra attiva, quindi inviare un messaggio/combinazione di tasti (Ctrl-C) ad esso per copiare il testo selezionato negli Appunti. Quindi l'utilità può lavorare sul testo accedendo utilizzando le funzioni relative agli Appunti.
  2. Trova la finestra attiva, quindi recupera direttamente il testo selezionato (senza copiarlo negli appunti). Questo sembra più difficile del primo approccio.

come punto di partenza:

ottenere la finestra ID attiva come Anurag Uniyal ha sottolineato nel suo reply.

O ottenere l'oggetto finestra con il seguente codice:

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

Può chiarire indipendentemente dal fatto che questa utility stia effettivamente creando la finestra attiva o questa finestra sia attiva da un'altra applicazione? –

+0

La "finestra attiva" è una finestra di un'altra applicazione. Questa utility dovrebbe essere eseguita in background (o systray) e dovrebbe essere attivata con un tasto predefinito. –

+0

Hai capito come recuperare il testo selezionato? – iMath

risposta

1

non sarà banale, ma qui è il punto di partenza

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

Forse si dovrà utilizzare FindWindow, FindWindowEx a Ottiene finestre figlio con fuoco

modifica: anche durante la sperimentazione utilizzare spy ++ per vedere come recupera informazioni su varie finestre, vedere hwnd, classe di finestra ecc

in fondo se è possibile trovare un esempio in C/C++/C# non sarà difficile tradurlo in pywin32 equivalente, quindi in un certo senso è API Win32 domanda specifica

+0

Sono stato sempre l'oggetto finestra attiva con il seguente: import win32ui WND = win32ui.GetForegroundWindow() wnd.GetWindowText print() Ma ho difficoltà ad arrivare al testo selezionato da lì. Grazie per i suggerimenti. Guarderò nella spia ++. –

1

È stai molto meglio usando il metodo Ctrl-C. Recuperare il testo direttamente funzionerà per qualcosa come un controllo di modifica, ma è inutile per recuperare il testo che un'applicazione ha dipinto direttamente sulla propria finestra.

+0

Grazie. Ciò presuppone che tutte le applicazioni, che supportano la selezione del testo, facciano uso degli appunti. Questo è probabilmente vero per il 99,99% delle applicazioni, ma sai se questa è la regola? –

+0

Ricorda che ci sono alcune applicazioni che supportano la copia del testo negli appunti, ma assegnano un significato diverso a Ctrl + C rispetto alla "copia degli appunti". Un esempio che mi viene in mente è la shell dei comandi (cmd.exe). –

2

il codice qui sotto funziona solo su semplici caselle di testo (appena fatto in VB6, e portato a python)

edit: è stato testato solo su pitone 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() 
+0

Ho testato il codice con Python 3, restituisce solo , nessun testo. – iMath