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
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
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:
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:
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.