2009-06-17 11 views
12

Estoy tratando de crear una utilidad de código abierto simple para Windows usando Python que puede realizar acciones definidas por el usuario en el texto seleccionado de la ventana actualmente activa. La utilidad debe activarse usando un atajo de teclado predefinido.Cómo recuperar el texto seleccionado de la ventana activa

uso se describe parcialmente en el siguiente ejemplo:

  1. El usuario selecciona un texto utilizando el ratón o el teclado (en cualquier ventana de la aplicación)
  2. el usuario pulsa una pre-definido atajo de teclado
  3. El texto seleccionado es recuperado por nuestra utilidad o copiado en el portapapeles (ambos enfoques deben estar bien)
  4. La acción dependiente del atajo de teclado se realiza en el texto seleccionado

Lo que me desconcierta es paso 3. Cómo se recupera el texto seleccionado de la ventana activa. Esto debería funcionar con todas las aplicaciones.

Uso el módulo pywin32.

Gracias de antemano por sus respuestas y sugerencias.

Actualización # 1:

Resulta que hay dos enfoques para llevar a cabo la tarea:

  1. Encuentra la ventana activa, a continuación, enviar un mensaje/pulsaciones de teclas (Ctrl-C) para que para copiar el texto seleccionado al portapapeles. Entonces la utilidad puede trabajar en el texto accediendo a él usando las funciones relacionadas con el portapapeles.
  2. Encuentra la ventana activa, luego recupera el texto seleccionado directamente (sin copiarlo en el portapapeles). Esto parece más difícil que el primer enfoque.

como puntos de partida:

obtener la ventana ID activo como Anurag Uniyal ha señalado en su reply.

O conseguir el objeto de la ventana con el siguiente código:

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

Puede aclarar si esta utilidad está realmente creando la ventana activa o esta ventana activa de una aplicación diferente? –

+0

La "ventana activa" es una ventana de una aplicación diferente. Esta utilidad debe ejecutarse en segundo plano (o bandeja del sistema) y debe activarse con una pulsación de tecla predefinida. –

+0

¿Has descubierto cómo recuperar el texto seleccionado? – iMath

Respuesta

1

no será trivial, pero aquí está el punto

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

Quizás partida tendrá que utilizar FindWindow, a FindWindowEx obtener ventanas secundarias con foco

editar: también durante la experimentación use spy ++ para ver cómo recupera información sobre varias ventanas, consulte hwnd, clase de ventana etc

básicamente si se puede encontrar un ejemplo en C/C++/C# que no será difícil de traducir eso en pywin32 equivalente, por lo que en cierto modo es la API de Win32 pregunta específica

+0

He estado recibiendo el objeto ventana activa con lo siguiente: importación win32ui WND = win32ui.GetForegroundWindow() wnd.GetWindowText de impresión() Pero tengo dificultades en conseguir que el texto seleccionado a partir de ahí. Gracias por los consejos. Investigaré el espía ++. –

1

Usted Está mucho mejor usando el método Ctrl-C. Obtener texto directamente funcionará para algo así como un control de edición, pero es inútil para recuperar el texto que una aplicación ha pintado directamente en su propia ventana.

+0

Gracias. Esto supone que todas las aplicaciones, que admiten selección de texto, hacen uso del portapapeles. Esto es probablemente cierto para el 99.99% de las aplicaciones, pero ¿sabes si esta es la regla? –

+0

Tenga en cuenta que hay algunas aplicaciones que sí admiten la copia de texto del portapapeles, pero le asigna un significado diferente a Ctrl + C que "copia del portapapeles". Un ejemplo que me viene a la mente es el shell de comandos (cmd.exe). –

2

el código de abajo sólo funcionará en los cuadros de texto simples (sólo lo hizo en VB6, y portado a pitón)

edición: que fue probado sólo en pitón 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

Probé tu código con Python 3, solo devuelve , sin texto. – iMath

Cuestiones relacionadas