listar nombre de ventana de los procesos. No lo consigo.

Iniciado por 70N1, 10 Marzo 2009, 14:24 PM

0 Miembros y 1 Visitante están viendo este tema.

70N1

Tengo ese problema, no consigo listar los nombres de las ventanas de los procesos

e intentado con:


dim recogidadedatos as string, handle as long
handle=openprocess( information or read,0, id)
getwindowtext(handle,recogidadedatos,100)
msgbox(recogidadedatos)


Pero parece que no encuentra el handle. Alguien me puede explicar el motivo?

A ¡¡, En el proceso vb leido con openprocess me da un handle pero en otro programa me sale otro handle en el mismo proceso.

Este es el modulo que lista los procesos en un treeview y pone en handle el classname y las dependencias:

Public Function FillProcessListNT(treeview As MSComctlLib.treeview) As Long
    '=========================================================
    'Clears the listbox specified by the DestListBox parameter
    'and then fills the list with the processes and the
    'modules used by each process
    '=========================================================

    Dim cb                  As Long
    Dim cbNeeded            As Long
    Dim NumElements         As Long
    Dim ProcessIDs()        As Long
    Dim cbNeeded2           As Long
    Dim NumElements2        As Long
    Dim Modules(1 To 1024)  As Long
    Dim lRet                As Long
    Dim ModuleName          As String
    Dim nSize               As Long
    Dim hProcess            As Long
    Dim i                   As Long
    Dim sModName            As String
    Dim sChildModName       As String
    Dim iModDlls            As Long
    Dim iProcesses          As Integer
    Dim nodo(5)             As Node
   
   
    treeview.Nodes.Clear
     
     Set nodo(0) = treeview.Nodes.Add(, , , "Procesos en ejecucion")
               
    'Get the array containing the process id's for each process object
    cb = 8
    cbNeeded = 96
   
    'One important note should be made. Although the documentation
    'names the returned DWORD "cbNeeded", there is actually no way
    'to find out how big the passed in array must be. EnumProcesses()
    'will never return a value in cbNeeded that is larger than the
    'size of array value that you passed in the cb parameter.
   
    'if cbNeeded == cb upon return, allocate a larger array
    'and try again until cbNeeded is smaller than cb.
    Do While cb <= cbNeeded
       cb = cb * 2
       ReDim ProcessIDs(cb / 4) As Long
       lRet = EnumProcesses(ProcessIDs(1), cb, cbNeeded)
    Loop
   
    'calculate how many process IDs were returned
    NumElements = cbNeeded / 4
   
    For i = 1 To NumElements
   
        'Get a handle to the Process
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION _
            Or PROCESS_VM_READ, 0, ProcessIDs(i))

        ' Iterate through each process with an ID that <> 0
        If hProcess Then
           
            'Retrieve the number of bytes that the array of module handles requires
            lRet = EnumProcessModules(hProcess, Modules(1), 1024, cbNeeded2)
            'Get an array of the module handles for the specified process
            lRet = EnumProcessModules(hProcess, Modules(1), cbNeeded2, cbNeeded2)
           
            'If the Module Array is retrieved, Get the ModuleFileName
            If lRet <> 0 Then
               
                'Fill the ModuleName buffer with spaces
                ModuleName = Space(MAX_PATH)
               
                'Preset buffer size
                nSize = 500
               
                'Get the module file name
                lRet = GetModuleFileNameExA(hProcess, Modules(1), ModuleName, nSize)
                frmModuleList.Text1.Text = Modules(1)
                'Get the module file name out of the buffer, lRet is how
                'many characters the string is, the rest of the buffer is spaces
                sModName = Left$(ModuleName, lRet)
               
                'Add the process to the listbox
                Set nodo(1) = treeview.Nodes.Add(nodo(0), tvwChild, , sModName, "false")
               
               treeview.Nodes.Add nodo(1), tvwChild, , "Class name :"
               treeview.Nodes.Add nodo(1), tvwChild, , "Pid :" & ProcessIDs(i)
                       treeview.Nodes.Add nodo(1), tvwChild, , "Hwnd :" & hProcess
                Set nodo(2) = treeview.Nodes.Add(nodo(1), tvwChild, , "Dependencias")
             
                'Increment the count of processes we've added
                iProcesses = iProcesses + 1
               
                iModDlls = 1
                Do
                    iModDlls = iModDlls + 1
                   
                    'Fill the ModuleName buffer with spaces
                    ModuleName = Space(MAX_PATH)
                   
                    'Preset buffer size
                    nSize = 500
                   
                    'Get the module file name out of the buffer, lRet is how
                    'many characters the string is, the rest of the buffer is spaces
                    lRet = GetModuleFileNameExA(hProcess, Modules(iModDlls), ModuleName, nSize)
                    sChildModName = Left$(ModuleName, lRet)
                   
                    If sChildModName = sModName Then Exit Do
                    If Trim(sChildModName) <> "" Then treeview.Nodes.Add nodo(2), tvwChild, , sChildModName, "false"
                Loop
            End If
        Else
            'Return the number of Processes found
            FillProcessListNT = 0
        End If
       
        'Close the handle to the process
        lRet = CloseHandle(hProcess)
    Next
   
    'Return the number of Processes found
    FillProcessListNT = iProcesses
   
End Function

70N1

Dessa

Cita de: 70N1 en 10 Marzo 2009, 14:24 PM
Pero parece que no encuentra el handle. Alguien me puede explicar el motivo?

A ¡¡, En el proceso vb leido con openprocess me da un handle pero en otro programa me sale otro handle en el mismo proceso.


El handle que usas para abrir un proceso (openprocess) es el PID o ID del proceso.

Este Handle_Proceso no es mismo handle de las ventanas (aplicaciones) que se enumeran con EnumWindows   

Adrian Desanti

seba123neo

Hola, aca te paso un codigo que me parecio bueno para lo que queres, despues modificalo vos para lo que realmente necesitas, lo que hace es listarte las todas las ventanas..con su HWND, nombre de clase y caption de la ventana...y al hacer click accedes tambien a las Ventanas Hijas...necesitas 2 listview , 1 check, y un boton...ponelos asi nomas con las propiedades por defecto y despues pega este codigo...el checkbox sirve para elegir si queres listar todas las ventanas del sistema o solo las que tienen caption...

En un Modulo:

Código (vb) [Seleccionar]
Option Explicit

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) 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 GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Any) As Long
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public Declare Function EnumChildWindows Lib "user32" (ByVal hwndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Any) As Long

Public Const WM_GETTEXT = &HD
Public Const WM_GETTEXTLENGTH = &HE
Public Const EM_GETPASSWORDCHAR = &HD2

Public VCount As Integer, ICount As Integer

Public Function WndEnumProc(ByVal hwnd As Long, ByVal lParam As ListView) As Long
    Dim WText As String * 512
    Dim bRet As Long, WLen As Long
    Dim WClass As String * 50
       
    WLen = GetWindowTextLength(hwnd)
    bRet = GetWindowText(hwnd, WText, WLen + 1)
    GetClassName hwnd, WClass, 50

    With Form1
        If (.Check1.Value = vbUnchecked) Then
            Insertar hwnd, lParam, WText, WClass
        ElseIf (.Check1.Value = vbChecked And WLen <> 0) Then
            Insertar hwnd, lParam, WText, WClass
        End If
    End With
   
    WndEnumProc = 1
End Function

Private Sub Insertar(iHwnd As Long, lParam As ListView, iText As String, iClass As String)
    lParam.ListItems.Add.Text = Str(iHwnd)
    lParam.ListItems.Item(VCount).SubItems(1) = iClass
    lParam.ListItems.Item(VCount).SubItems(2) = iText
    VCount = VCount + 1
End Sub

Public Function WndEnumChildProc(ByVal hwnd As Long, ByVal lParam As ListView) As Long
    Dim bRet As Long
    Dim myStr As String * 50
    bRet = GetClassName(hwnd, myStr, 50)
    With lParam.ListItems
        .Add.Text = Str(hwnd)
        .Item(ICount).SubItems(1) = myStr
        .Item(ICount).SubItems(2) = GetText(hwnd)
        If SendMessage(hwnd, EM_GETPASSWORDCHAR, 0, 0) = 0 Then
            .Item(ICount).SubItems(3) = "NO"
        Else
            .Item(ICount).SubItems(3) = "SI"
            .Item(ICount).ForeColor = vbRed
            .Item(ICount).Bold = True
            .Item(ICount).ListSubItems.Item(1).ForeColor = vbRed
            .Item(ICount).ListSubItems.Item(1).Bold = True
            .Item(ICount).ListSubItems.Item(2).ForeColor = vbRed
            .Item(ICount).ListSubItems.Item(2).Bold = True
            .Item(ICount).ListSubItems.Item(3).ForeColor = vbRed
            .Item(ICount).ListSubItems.Item(3).Bold = True
        End If
    End With
    ICount = ICount + 1
    WndEnumChildProc = 1
End Function

Function GetText(iHwnd As Long) As String
    Dim Textlen As Long
    Dim Text As String
    Textlen = SendMessage(iHwnd, WM_GETTEXTLENGTH, 0, 0)
    If Textlen = 0 Then
        GetText = "No se encontro Texto..."
        Exit Function
    End If
    Textlen = Textlen + 1
    Text = Space(Textlen)
    Textlen = SendMessage(iHwnd, WM_GETTEXT, Textlen, ByVal Text)
    GetText = Left(Text, Textlen)
End Function


En el Formulario:

Código (vb) [Seleccionar]
Option Explicit

Private Sub Form_Load()
    Command1.Caption = "Listar Ventanas"
    Check1.Caption = "Solo Ventanas con Caption"
    Call ConfiguraListview
End Sub

Private Sub ConfiguraListview()
    ListView1.View = lvwReport
    ListView1.FullRowSelect = True
    ListView2.FullRowSelect = True
    With ListView1.ColumnHeaders
        .Add , , "HWND", 1000
        .Add , , "Nombre de Clase", 1500
        .Add , , "Caption Ventana", 3000
    End With
    VCount = 1
    ListView2.View = lvwReport
    With ListView2.ColumnHeaders
        .Add , , "HWND", 1000
        .Add , , "Nombre de Clase", 1500
        .Add , , "Caption Ventana", 2500
        .Add , , "Textbox de Password", 1500
    End With
    ICount = 1
End Sub

Private Sub Command1_Click()
    ListView1.ListItems.Clear
    ListView2.ListItems.Clear
    ListView1.GridLines = True
    VCount = 1
    EnumWindows AddressOf WndEnumProc, ListView1
End Sub

Private Sub Listview1_Click()
    Call ListarHijas
End Sub

Private Sub ListarHijas()
On Error Resume Next
    Dim Numero As Long
    Numero = Val(ListView1.SelectedItem)
    ListView2.ListItems.Clear
    ListView2.GridLines = True
    ICount = 1
    EnumChildWindows Numero, AddressOf WndEnumChildProc, ListView2
End Sub


saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson