............ Foro Excel
Si no lo has hecho aún: REGISTRATE!!!

Capturar el texto de una ventana

Ver el tema anterior Ver el tema siguiente Ir abajo

Capturar el texto de una ventana

Mensaje por GalileoGali el Dom Mayo 17, 2009 6:08 pm

Objetivo:
Pasar el caption de una ventana a una API y que me devuelva el texto de dicha ventana. Digamos que con GetWindowsText conseguimos obtener el Texto del Caption de una ventana, ahora yo me pregunto: ¿hay alguna manera de simular el SelectAll y el Copy y obtener una ventana de puro texto cargada en el Clipboard??? Descartado el envio de Teclazos Simulados con SendKeys o KbEvents. Manualmente la ventana que me preocupa sólo admite (o por lo menos es lo único que he logrado con éxito), seleccionar Texto con el Mouse y luego manejarse con un CommandBar llamado "Edicion" que despliega dos únicos CommandButtons: "Copiar" y "Pegar". La ventana que me interesa carece de Interactividad es del tipo "Sólo Lectura - Consulta" y el empalme con mi programa ya lo tengo todo armado, solo que por ahora el "Pintado" y el Edicion - Copiar, lo estoy haciendo inevitablemente con el Mouse, pero.....
Si aparece alguna opcion mejor: Bienvenida sea.....!!!!

_________________
GalileoGali
M.A.P. 2010-2013
Microsoft Active Professional
avatar
GalileoGali
Admin

Masculino Cantidad de envíos : 1963
Edad : 62
Ciudad - Pais : QUIROGA, Argentina
Version de Excel : 2000-2003-2007-2010
Fecha de inscripción : 24/01/2008

http://excelgali.mejorforo.net

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por P@li el Dom Mayo 17, 2009 6:55 pm

Gali,

  • Tratándose de un Input (análogo al InpuxBox de VBA)

  • No solamente tenemos que conseguir el hWnd de la ventana madre, también el del Input en cuestión. Para ello vamos a tener que hacer buen uso de la función EnumChildWindows, con la que podemos recuperar todos los identificadores de los controles que contenga el formulario (siempre que no sea un Form 2.0 de VBA). Avisame si necesitás una mano para ponerla en funcionamiento.

  • Una vez que obtenemos el hWnd del Input, podemos usar la función SendMessage, con la que vamos a poder obtener el texto sin necesidad de usar el clipboard
    Código:

    Private Const WM_GETTEXT = &HD
    Private Const WM_GETTEXTLENGTH = &HE

    ' Declaración del Api SendMessage
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

    Function DevolverTexto(ByVal Input_hWnd As Long) As String
        Dim longitud As Long
        longitud = SendMessage(Input_hWnd, WM_GETTEXTLENGTH, 0&, 0&)
        If longitud Then
            DevolverTexto = Space(longitud + 1)
            Call SendMessage(Input_hWnd, WM_GETTEXT, ByVal longitud + 1, ByVal DevolverTexto)
        End If
    End Function


Saludos.


Última edición por P@li el Dom Mayo 17, 2009 6:59 pm, editado 2 veces (Razón : Me olvidé de poner las llamadas de API.)

P@li
Admin

Masculino Cantidad de envíos : 243
Edad : 34
Ciudad - Pais : Buenos Aires, Argentina
Version de Excel : Microsoft Excel 2002 (10.2614.2625)
Fecha de inscripción : 03/03/2008

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por GalileoGali el Lun Mayo 18, 2009 10:53 pm

P@li:
1) No tengo ningún apuro
y
2) No tengo ni la menor idea de como enlazar el codigo que me aportas

Realmente espero que te alivies un poco de tus examenes, como par esperar algo mas concreto.

En principio tengo dos ventanas, la de Excel (la receptora, supongo que esta será tu Input) y la del programa de donde quiero copiar los datos que se muestran en Pantalla (origen , supongo que es lo que llamas hoja Madre?).

Te aclaro que la ventana Origen, aparentemente, carece de controles, usando el portapapeles y pegando se copia texto y tal como se ve se pega. De todas maneras seria bueno detectar los controles, para copiar solo texto, ya que si bien en este caso parece innecesario, tengo otras ventanas en vista (para futuras aplicaciones) donde resultaraia util
Mientras tanto sigo investigando como

_________________
GalileoGali
M.A.P. 2010-2013
Microsoft Active Professional
avatar
GalileoGali
Admin

Masculino Cantidad de envíos : 1963
Edad : 62
Ciudad - Pais : QUIROGA, Argentina
Version de Excel : 2000-2003-2007-2010
Fecha de inscripción : 24/01/2008

http://excelgali.mejorforo.net

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por GalileoGali el Mar Mayo 19, 2009 12:14 am

En un intento: creé un Word, con un texto muy simple e hilvane algo de lo que me mandaste + FindWindow, pero no puedo escapar de devolver el Caption, y no,logro conectar con el contenido de la ventana.

Código:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
 
Private Const WM_GETTEXTLENGTH = &HE
Private Const WM_GETTEXT = &HD
Sub Dialog_Control()
   
    Dim lngHwndOrigen As Long, lngHwndDestino As Long
    Dim strWindowOrigen As String, strWindowDestino As String
    Dim strResultado As String
  strWindowOrigen = "Documento1 - Microsoft Word"
  strWindowDestino = "Microsoft Excel - SendMessage.xls"

    lngHwndOrigen = FindWindow(vbNullString, strWindowOrigen)
    lngHwndDestino = FindWindow(vbNullString, strWindowDestino)
   
    If lngHwndOrigen > 0 And lngHwndDestino > 0 Then
       
    strResultado = DevolverTexto(lngHwndDestino)
               
    End If
   
End Sub
Function DevolverTexto(ByVal Input_hWnd As Long) As String
    Dim longitud As Long
    longitud = SendMessage(Input_hWnd, WM_GETTEXTLENGTH, 0&, 0&)
    If longitud Then
        DevolverTexto = Space(longitud + 1)
        Call SendMessage(Input_hWnd, WM_GETTEXT, ByVal longitud + 1, ByVal DevolverTexto)
    End If
End Function

_________________
GalileoGali
M.A.P. 2010-2013
Microsoft Active Professional
avatar
GalileoGali
Admin

Masculino Cantidad de envíos : 1963
Edad : 62
Ciudad - Pais : QUIROGA, Argentina
Version de Excel : 2000-2003-2007-2010
Fecha de inscripción : 24/01/2008

http://excelgali.mejorforo.net

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por P@li el Mar Mayo 19, 2009 9:47 am

Gali,
Hay un problema, aparentemente Word usa controles creados "a medida", que no responden a las llamadas convencionales de API, por lo que pude averiguar resultaria imposible capturar el texto de un Word a través de esta herramienta. No creo que sea tan así, pero es lo que leí.

Lo único que pude averiguar del control en el cual se escribe el texto es que su nombre de clase es _WwG, y lo demás lo podemos averiguar poniendo esa palabra en google.

Sin embargo, existe la posibilidad de trabajar con el objeto Word, Document, etc, capturando el Word abierto con la función:
set objWord = getObject("Word.Application")

Teniendo una referencia a Microsoft Word # Object Library, podemos declarar una variable objWord de tipo Word, y otra objDoc de tipo Document, que podríamos recuperar de la siguiente manera:
set objDoc = objWord.ActiveDocument

Y a partir de ahí, te dejo la mejor parte a vos...

Es una idea, de paso aprovechás los objetos del paquete office.

Para otras ventanas que no dependan de Word, pero que contengan textos que necesites recuperar, dejo una solución posible con enumChildWindows.

Esto ponerlo en un módulo:
Código:

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
 Private Const WM_GETTEXTLENGTH = &HE
Private Const WM_GETTEXT = &HD
Public Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

Dim retval As Long ' return value
Dim hwnds As String
Dim functionAddress As Long

Sub getChilds(hwnd As Long)
    hwnds = ""
    Debug.Print "hWnd", "Clase", " Texto"
    functionAddress = getFunctionAddress(AddressOf EnumChildProc)
    retval = EnumChildWindows(hwnd, functionAddress, 0)
End Sub

Public Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
    If Not hwnds Like "*" & hwnd & "|*" Then
        hwnds = hwnds & hwnd & "|"
        Debug.Print hwnd, DevolverClase(hwnd), DevolverTexto(hwnd)
        EnumChildWindows hwnd, functionAddress, 0
    End If
    EnumChildProc = 1
End Function

Function DevolverTexto(ByVal Input_hWnd As Long) As String
    Dim longitud As Long
    longitud = SendMessage(Input_hWnd, WM_GETTEXTLENGTH, 0&, 0&)
    If longitud Then
        DevolverTexto = Space(longitud + 1)
        Call SendMessage(Input_hWnd, WM_GETTEXT, ByVal longitud + 1, ByVal DevolverTexto)
    End If
End Function

Function DevolverClase(ByVal Input_hWnd As Long) As String
    Dim longitud As Long
    DevolverClase = Space(128)
    'Recupera el Classname y lo devuelve en el Buffer
    longitud = GetClassName(Input_hWnd, DevolverClase, 128)
    'Extraemos el nombre de la clase
    DevolverClase = Left(DevolverClase, longitud)
End Function

Function getFunctionAddress(ByVal funcion As Long) As Long
    getFunctionAddress = funcion
End Function

Y esto en el formulario (con un botón llamado CommandButton1):
Código:

Sub CommandButton1_Click()
    Dim lngHwndOrigen As Long, lngHwndDestino As Long
    Dim strWindowOrigen As String, strWindowDestino As String
    Dim strResultado As String
    strWindowOrigen = "Nombre de la ventana"
    strWindowDestino = ""
    lngHwndOrigen = FindWindow(vbNullString, strWindowOrigen)
    'lngHwndDestino = FindWindow(vbNullString, strWindowDestino)
    If lngHwndOrigen > 0 Then
        Call getChilds(lngHwndOrigen)
    End If
End Sub

Saludos.

P@li
Admin

Masculino Cantidad de envíos : 243
Edad : 34
Ciudad - Pais : Buenos Aires, Argentina
Version de Excel : Microsoft Excel 2002 (10.2614.2625)
Fecha de inscripción : 03/03/2008

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por GalileoGali el Mar Mayo 19, 2009 11:18 pm

Aca va la adaptacion de un codigo ([Tienes que estar registrado y conectado para ver este vínculo] para "pasar" línea a línea el texto de la ventana abierta de un "Bloc de Notas", a un textbox (multiline)


_________________
GalileoGali
M.A.P. 2010-2013
Microsoft Active Professional
avatar
GalileoGali
Admin

Masculino Cantidad de envíos : 1963
Edad : 62
Ciudad - Pais : QUIROGA, Argentina
Version de Excel : 2000-2003-2007-2010
Fecha de inscripción : 24/01/2008

http://excelgali.mejorforo.net

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por P@li el Miér Mayo 20, 2009 9:19 am

Excelente ejemplo Gali.
Si encuentro algún ejemplo para obtener el texto de una ventana de Word te aviso.

Saludos.

P@li
Admin

Masculino Cantidad de envíos : 243
Edad : 34
Ciudad - Pais : Buenos Aires, Argentina
Version de Excel : Microsoft Excel 2002 (10.2614.2625)
Fecha de inscripción : 03/03/2008

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por federico ramirez marron el Vie Nov 06, 2009 3:49 pm

Estoy haciendo pruebas con el archivo SendMessage , y trabaja muy bien, solo que al borrar datos del blok de notas y escribir algo mas, claro primero me salgo del form para inicializarlo, y me manda cero, ya no lo recupera a un cuando no guardo con ningun nombre el blok de notas, sera que falta que se limpie la variable, para que pueda volver a trabajar bien sin tener que cerrar el excel y volverlo abrir?
avatar
federico ramirez marron

Masculino Cantidad de envíos : 95
Edad : 43
Ciudad - Pais : acapulco, gro mexico
Fecha de inscripción : 03/03/2008

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por GalileoGali el Sáb Nov 07, 2009 9:26 am

Si modificas la ventana:
1) reiniciando "Bloc de Notas", necesitaras volver a obtener el hwnd de la ventana.

2) Si guardas con un nombre el Bloc de Notas, ya no sera "Sin Titulo - Bloc de Notas" el caption de la ventana y por ende la API devolvera hwnd = 0 que es el equivalente a "No encontre ninguna ventana"

Hay formas de buscar por el Nombe de todas las ventanas visibles e invisibles la que corresponda, buscnado mediante "like" aquella ventana que contenga "*Bloc de Notas", o en caso de que ya sepas el nombre que pensas dar al archivo, previendo cambies el codigo, donde dice "Sin título - Bloc de Notas", poner "NombredelArchivo previsto - Bloc de Notas"

_________________
GalileoGali
M.A.P. 2010-2013
Microsoft Active Professional
avatar
GalileoGali
Admin

Masculino Cantidad de envíos : 1963
Edad : 62
Ciudad - Pais : QUIROGA, Argentina
Version de Excel : 2000-2003-2007-2010
Fecha de inscripción : 24/01/2008

http://excelgali.mejorforo.net

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por federico ramirez marron el Vie Nov 13, 2009 6:49 pm

Mil gracias Gali, esto es interesante!!!.

varios dias sin internet aqui en acapulco, se cayo la red de cablemas, puras fallas!!!!
avatar
federico ramirez marron

Masculino Cantidad de envíos : 95
Edad : 43
Ciudad - Pais : acapulco, gro mexico
Fecha de inscripción : 03/03/2008

Volver arriba Ir abajo

Re: Capturar el texto de una ventana

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


 
Permisos de este foro:
No puedes responder a temas en este foro.