Estoy creando un trainer para el Age Of Empires The Conquerors en el que utilizo estas dos apis, y necesitaba saber como puedo almacenar en una variable el valor de una dirección.
Gracias de antemano.
a readprocess ya le pasas un buffer, si te interesa guardar algo en concreto pues despues de leer guardas en otra variable lo que necesites.
¿Me podrías poner un ejemplo?
no me creo que sepas usar read/writeprocessmemory y no sepas que tienes un buffer con los datos. y menos me creo que no sepas asignar a otra variable lo que has leido. repasa el libro.
Yo no he dicho que supiese utilizarlas, solo que las utilizo.
pues explicame tu entonces, como sin saber utilizarlas puedes utilizarlas. o me estoy quedando anticuado o no entiendo las formas que teneis ultimamente de programar.
Vi un código similar y lo estoy intentando adaptar para lo que me interesa.
Cita de: aaronduran2 en 5 Mayo 2008, 14:11 PM
Vi un código similar y lo estoy intentando adaptar para lo que me interesa.
Pues no es asi k se programa, leete esto:
http://msdn.microsoft.com/en-us/library/ms681674(VS.85).aspx
http://msdn.microsoft.com/en-us/library/ms680553(VS.85).aspx
en el api - guide hay ejemplos basicos de estas 2 api's,de como guardar variables en memoria y recuperarlas despues...
saludos.
hola yo mucho no te puedo explicar del tema, pero, como el tema es interesante tambien estoy buscando algo de info, porque quiero obtener el codigo html de el IExplorer para modificarlo y devolverselo, pero bueno todavía no saco nada, te paso dos ejemplo que vale mas que 1000 palabras.
el primero es el del api guide (el que te nombraba Seba123neo)
agrega un Command1
' MaRi� G. Serrano. 16/Abril/2002.-
Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteString Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
'Private Declare Function WriteValue Lib "kernel32" Alias "WriteProcessMemory" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Sub Command1_Click()
Dim str As String, MyString As String
MyString = "HELLO"
'in this case I read the memory of my own process
MsgBox "MyString= " & MyString
str = ReadMemory(Me.hWnd, StrPtr(MyString), LenB(MyString), "BYE!!")
MsgBox "Now, MyString=" & MyString & vbCr & "Old Value= " & str
End Sub
Private Function ReadMemory(hWnd As Long, Address As Long, Bytes As Long, Optional strReplaceWith As String) As String
'Runs For Not Unicode Strings (VB-Strings)
On Error Resume Next
Dim pId As Long ' Used to hold the Process Id
Dim pHandle As Long ' Holds the Process Handle
Dim bytValue As Long 'Stores the value of a byte in the memory
Dim i As Long
Dim Text As String
' Get the ProcId of the Window
GetWindowThreadProcessId hWnd, pId
' use the pId to get a handle
pHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pId)
If (pHandle = 0) Then
'MsgBox "Unable to open process!"
Exit Function
End If
If Address = 0 Then Exit Function
For i = 1 To Bytes Step 2
' Read Byte to Byte
ReadProcessMemory pHandle, Address + i - 1, bytValue, 1, 0&
'value now contains the long value of the byte located in [Address + i - 1] pos.
'ReadMemory is a string...
ReadMemory = ReadMemory & Chr$(bytValue)
Next
'to write numeric values you can ..(Must) use WriteValue API
If LenB(strReplaceWith) <> 0 Then
'No Unicode!!
WriteString pHandle, Address, StrPtr(strReplaceWith), LenB(strReplaceWith), 0&
End If
'Close the Handle
CloseHandle pHandle
End Function
otro agrega 3 labels, 3 textboxes y 1 commandbutton en un form
Lo que hace es cambiar el caption del boton retroceso de la calculadora por otro.
Option Explicit
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Private Type MEMORY_BASIC_INFORMATION ' 28 bytes
BaseAddress As Long
AllocationBase As Long
AllocationProtect As Long
RegionSize As Long
State As Long
Protect As Long
lType As Long
End Type
Private Type SYSTEM_INFO ' 36 Bytes
dwOemID As Long
dwPageSize As Long
lpMinimumApplicationAddress As Long
lpMaximumApplicationAddress As Long
dwActiveProcessorMask As Long
dwNumberOrfProcessors As Long
dwProcessorType As Long
dwAllocationGranularity As Long
wProcessorLevel As Integer
wProcessorRevision As Integer
End Type
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (LpVersionInformation As OSVERSIONINFO) As Long
Private Declare Function VirtualQueryEx& Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long)
Private Declare Sub GetSystemInfo Lib "kernel32" (lpSystemInfo As SYSTEM_INFO)
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Const GW_HWNDNEXT = 2
Private Declare Function InvalidateRect Lib "user32" (ByVal hWnd As Long, ByVal lpRect As Long, ByVal bErase As Long) As Long
Const PROCESS_VM_READ = (&H10)
Const PROCESS_VM_WRITE = (&H20)
Const PROCESS_VM_OPERATION = (&H8)
Const PROCESS_QUERY_INFORMATION = (&H400)
Const PROCESS_READ_WRITE_QUERY = PROCESS_VM_READ + PROCESS_VM_WRITE + PROCESS_VM_OPERATION + PROCESS_QUERY_INFORMATION
Const MEM_PRIVATE& = &H20000
Const MEM_COMMIT& = &H1000
Private Sub Command1_Click()
Dim pid As Long, hProcess As Long, hWin As Long
Dim lpMem As Long, ret As Long, lLenMBI As Long
Dim lWritten As Long, CalcAddress As Long, lPos As Long
Dim sBuffer As String
Dim sSearchString As String, sReplaceString As String
Dim si As SYSTEM_INFO
Dim mbi As MEMORY_BASIC_INFORMATION
sSearchString = Text2
sReplaceString = Text3 & Chr(0)
If IsWindowsNT Then 'NT store strings in RAM in UNICODE
sSearchString = StrConv(sSearchString, vbUnicode)
sReplaceString = StrConv(sReplaceString, vbUnicode)
End If
pid = Shell(Text1) 'launch application (calc.exe in this sample)
hWin = InstanceToWnd(pid) 'get handle of launched window - only to repaint it after changes
'Open process with required access
hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
lLenMBI = Len(mbi)
'Determine applications memory addresses range
Call GetSystemInfo(si)
lpMem = si.lpMinimumApplicationAddress
'Scan memory
Do While lpMem < si.lpMaximumApplicationAddress
mbi.RegionSize = 0
ret = VirtualQueryEx(hProcess, ByVal lpMem, mbi, lLenMBI)
If ret = lLenMBI Then
If ((mbi.lType = MEM_PRIVATE) And (mbi.State = MEM_COMMIT)) Then ' this block is In use by this process
If mbi.RegionSize > 0 Then
sBuffer = String(mbi.RegionSize, 0)
'Read region into string
ReadProcessMemory hProcess, ByVal mbi.BaseAddress, ByVal sBuffer, mbi.RegionSize, lWritten
'Check if region contain search string
lPos = InStr(1, sBuffer, sSearchString, vbTextCompare)
If lPos Then
CalcAddress = mbi.BaseAddress + lPos
Me.Show
ret = MsgBox("Search string was found at address " & CalcAddress & "." & vbCrLf & "Do you want to replace it?", vbInformation + vbYesNo, "VB-O-Matic")
If ret = vbYes Then
'Replace string in virtual memory
Call WriteProcessMemory(hProcess, ByVal CalcAddress - 1, ByVal sReplaceString, Len(sReplaceString), lWritten)
'Redraw window
InvalidateRect hWin, 0, 1
End If
Exit Do
End If
End If
End If
'Increase base address for next searching cicle. Last address may overhead max Long value (Windows use 2GB memory, which is near max long value), so add Error checking
On Error GoTo Finished
lpMem = mbi.BaseAddress + mbi.RegionSize
On Error GoTo 0
Else
Exit Do
End If
Loop
Finished:
CloseHandle hProcess
End Sub
Private Sub Form_Load()
Caption = "VB-O-Matic"
Label1 = "Start application:"
Label2 = "String to find:"
Label3 = "Replace with:"
Text1 = "Calc.exe"
Text2 = "Retroceso"
Text3 = "VB-O-Matic"
Command1.Caption = "&Launch It!"
End Sub
Private Function InstanceToWnd(ByVal target_pid As Long) As Long
Dim test_hwnd As Long
Dim test_pid As Long
Dim test_thread_id As Long
test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
Do While test_hwnd <> 0
If GetParent(test_hwnd) = 0 Then
test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
If test_pid = target_pid Then
InstanceToWnd = test_hwnd
Exit Do
End If
End If
test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
Loop
End Function
Private Function IsWindowsNT() As Boolean
Dim verinfo As OSVERSIONINFO
verinfo.dwOSVersionInfoSize = Len(verinfo)
If (GetVersionEx(verinfo)) = 0 Then Exit Function
If verinfo.dwPlatformId = 2 Then IsWindowsNT = True
End Function
y bueno ya que esta el hilo abierto estaria lindo quien tenga otros ejemplo lo ponga a continuacion para hacer una pequeña recopilacion sobre el uso de estas dos apis.
Citary bueno ya que esta el hilo abierto estaria lindo quien tenga otros ejemplo lo ponga a continuacion para hacer una pequeña recopilacion sobre el uso de estas dos apis.
que no entiendes? Yo tengo codes pero en C o asm, si te vale...
A ver, el uso de estas dos apis es muy simple, me autocito de un tuto de rootkits q escribí, ya de paso pongo algunas apis relaccionadas q os serán utiles:
Citar
OpenProcess:
HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance flag
DWORD dwProcessId // process identifier
);
Esta es la documentación que Microsoft nos proporciona sobre este api. Ahora os la
detallo un poco:
Valor de retorno: El valor devuelto es el manejador del proceso, explicado de una
forma simple es la forma que tendremos en el código para referirnos al proceso. El
valor que devuelve lo almacenaremos en una variable del tipo HANDLE.
DWORD dwDesiredAccess: Es el modo de apertura del proceso, en nuestro caso
nos daremos todos los privilegios con PROCESS_ALL_ACCESS.
BOOL bInheritHandle: Toma valor true (hereda) o false (no hereda). Nosotros
pondremos false.
DWORD dwProcessId: Es el PID del proceso, luego veremos como obtenerlo con el
nombre del proceso.
VirtualAllocEx:
Sirve para reservar espacio en la memoria de un proceso.
LPVOID VirtualAllocEx(
HANDLE hProcess, // process within which to allocate memory
LPVOID lpAddress, // desired starting address of allocation
DWORD dwSize, // size, in bytes, of region to allocate
DWORD flAllocationType, // type of allocation
DWORD flProtect // type of access protection
);
Valor de retorno: La dirección donde empezaremos a escribir con
WriteProcessMemory.
HANDLE hProcess: El manejador del proceso en el cual vamos a escribir. Es el valor
que nos devuelve OpenProcess.
LPVOID lpAddress: La dirección donde empezamos a reservar espacio, lo
dejaremos en NULL.
DWORD dwSize: El tamaño en bytes de la región que queremos reservar, en
nuestro caso será el tamaño de la cadena que contiene la ruta de la dll a inyectar.
DWORD flAllocationType: El motivo por el cual queremos reservar la memoria, en
nuestro caso MEM_COMMIT|MEM_RESERVE.
DWORD flProtect: El tipo de protección, en nuestro caso PAGE_READWRITE.
WriteProcessMemory:
Sirve para escribir en la memoria anteriormente reservada.
BOOL WriteProcessMemory(
HANDLE hProcess, // handle to process whose memory is written to
LPVOID lpBaseAddress, // address to start writing to
LPVOID lpBuffer, // pointer to buffer to write data to
DWORD nSize, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // actual number of bytes
//written
);
Valor de retorno: Ver LPDWORD lpNumberOfBytesWritten.
HANDLE hProcess: El valor devuelto por OpenProcess.
LPVOID lpBaseAddress: La dirección por donde empezaremos a escribir. Es el valor
devuelto por VirtualAllocEx.
LPVOID lpBuffer: Lo que queremos escribir, en nuestro caso la ruta de nuestra dll.
DWORD nSize: El tamaño en bytes de lo que queremos escribir, es decir el tamaño
en bytes de la ruta de nuestra dll.
LPDWORD lpNumberOfBytesWritten: Es el numero de bytes que se han escrito
correctamente, así como el valor de retorno, nosotros lo dejaremos en NULL ya que
no nos interesa.
Y ReadProcessMemory es lo mismo q WritePM pero para leer xD
Poned dudas mas concretas ;)
1S4ludo
CitarPoned dudas mas concretas
no se si me lo preguntas a mi?, yo en realidad si entiendo, tampoco soy un experto, pero lo que propuese fue codear un poco.
yo utilize estas apis en algunas ocasiones para pasar msg a controles como listview del systema, u otras.
en fin si tuviera que decirte una duda en concreto, ahora, que por falta de tiempo no me puse a imbestigar, es como obtener el codigo html del iExplorer, se que de alguna manera se puede porque tengo una aplicacion en vb que lo hace(lamentablemente no tengo el codigo)
la duda es en que parte de la memoria tendria que leer y de que tamaño.
Saludos
Cita de: LeandroA en 6 Mayo 2008, 03:01 AM
CitarPoned dudas mas concretas
no se si me lo preguntas a mi?, yo en realidad si entiendo, tampoco soy un experto, pero lo que propuese fue codear un poco.
yo utilize estas apis en algunas ocasiones para pasar msg a controles como listview del systema, u otras.
en fin si tuviera que decirte una duda en concreto, ahora, que por falta de tiempo no me puse a imbestigar, es como obtener el codigo html del iExplorer, se que de alguna manera se puede porque tengo una aplicacion en vb que lo hace(lamentablemente no tengo el codigo)
la duda es en que parte de la memoria tendria que leer y de que tamaño.
Saludos
Hola Leandro, pues eso no tiene k ver con leer memoria.
Acabo de escribirte un ejemplo, aver si lo entiendes.
Option Explicit
Dim SWs As New SHDocVw.ShellWindows
Dim IE As SHDocVw.InternetExplorer
Private Sub Command1_Click()
For Each IE In SWs
DoEvents
If IE.readyState = READYSTATE_COMPLETE Then
If IE.LocationURL = "http://www.elhacker.net/" Then
Text1.Text = IE.document.body.innerHTML
Exit For
End If
End If
Next IE
End Sub
En las "references" anade la "Microsoft HTML Object Library" y el ""Microsoft Internet Controls".
Saludos
tambien se puede hacer directamente con api's,pero esto se desvio del tema me parece... :P
Cita de: seba123neo en 6 Mayo 2008, 03:46 AM
tambien se puede hacer directamente con api's,pero esto se desvio del tema me parece... :P
Con apis? Bueno entonces pone esas apis aki :rolleyes:
es con la libreria wininet.dll,lo vi muy util cuando lo postearon en un foro:
Option Explicit
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Long, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Long) As Long
Private Declare Function InternetOpenUrl Lib "wininet.dll" Alias "InternetOpenUrlA" (ByVal hInternetSession As Long, ByVal sURL As String, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal lFlags As Long, ByVal lContext As Long) As Long
Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInet As Long) As Integer
Private Const IF_FROM_CACHE = &H1000000
Private Const IF_MAKE_PERSISTENT = &H2000000
Private Const IF_NO_CACHE_WRITE = &H4000000
Private Const BUFFER_LEN = 256
Public Function CodigoWeb(Pagina As String) As String
Dim sBuffer As String * BUFFER_LEN, iResult As Integer, sData As String
Dim hInternet As Long, hSession As Long, lReturn As Long
hSession = InternetOpen("vb wininet", 1, vbNullString, vbNullString, 0)
If hSession Then hInternet = InternetOpenUrl(hSession, Pagina, vbNullString, 0, IF_NO_CACHE_WRITE, 0)
If hInternet Then
iResult = InternetReadFile(hInternet, sBuffer, BUFFER_LEN, lReturn)
sData = sBuffer
Do While lReturn <> 0
iResult = InternetReadFile(hInternet, sBuffer, BUFFER_LEN, lReturn)
sData = sData + Mid(sBuffer, 1, lReturn)
Loop
End If
iResult = InternetCloseHandle(hInternet)
CodigoWeb = sData
End Function
Private Sub Form_Load()
MsgBox CodigoWeb("http://www.google.com.ar")
End Sub
saludos.
Ya sabia k ibas a poner eso, pero con eso tienes k abrir una nueva instancia, no es lo mismo k puse yo.
Con lo k puse yo puedes elijir kualkier instancia ya abierta o incluso crear una nueva y manejar todo lo k kieras. Investigalo y veras k es mejor.
No quiero decir k lo k has puesto no es util, simplemente no es lo mejor para esto k ha pedido Leandro.
Saludos
es util para el que no quiere agregar referencias externas,a mi no me gusta agregar muchas cosas,trato de hacerlo todo con codigo por eso me parecio bueno..tambien hay otra forma muy corta con la libreria XML agregandola como referencia,bue y con el control Inet con una linea de codigo..pero no me gusta ::)
saludos.
Cita de: TughackOption Explicit
Dim SWs As New SHDocVw.ShellWindows
Dim IE As SHDocVw.InternetExplorer
Private Sub Command1_Click()
For Each IE In SWs
DoEvents
If IE.readyState = READYSTATE_COMPLETE Then
If IE.LocationURL = "http://www.elhacker.net/" Then
Text1.Text = IE.document.body.innerHTML
Exit For
End If
End If
Next IE
End Sub
jaja :laugh: buenisimo era eso, ahora que recuerdo Cobein en una vuelta me habia pasado algo parecido con SHDocVw.ShellWindows pero no savia como hacer el For Each IE In SWs, la verdad que me la iva a complicar mucho, lamentablemnte esto no va a servir obtener los script o para firefox u opera. pero bueno me safa.
Saludos y muchas gracias
PD:el que quiera puede seguir agregando algunos ejemplos mas de ReadProcessMemory y WriteProcessMemory para tenerlos a mano, no estarian de mas.
Leandro,te queria preguntar,una vez vi que pusiste un codigo para poder saber en que icono del escritorio se hizo click,usando estas 2 api's,y despues vi que tenias un codigo para sacar los items de un listview de visual sabiendo su hwnd,pero tiraba error para uno de windows,¿ya lo corregiste?,la verdad siempre quise hacer eso y la otra vez encontre un codigo que lo hace con estas 2 api's y es re-cortito,no tira error con los de windows,ahora estoy viendo si le puedo sacar tambien el icono del listview...
saludos.
Cita de: aaronduran2 en 5 Mayo 2008, 14:11 PM
Vi un código similar y lo estoy intentando adaptar para lo que me interesa.
Los codigos no se adaptan se programan (o si no eres lammer)
hola Seba123neo utilizando sendmensage a secas si va a dar error, encambio con estas dos apis no da error pero el problema es que produce un incremento en el uso de la memoria del la aplicacion que porta el listview. (esto con algunos msg no todos)
ya que esta dejo aca el que havia puesto en canalvisualbasic.net
1 saber cuantos items hay
2 saber cual esta selecionado
3 Selecionar un items
4 ver el texto del items o del subitems
el modulo
Option Explicit
Private Type LVITEM
mask As Long
iItem As Long
iSubitem As Long
state As Long
stateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
End Type
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 Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Const LVIF_IMAGE = &H2
Private Const LVIF_TEXT = &H1
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_GETITEM As Long = (LVM_FIRST + 5)
Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
Private Const LVM_GETITEMSTATE = (LVM_FIRST + 44)
Private Const LVIS_SELECTED = &H2
Private Const LVM_SETITEMSTATE = (LVM_FIRST + 43)
Private Const LVIF_STATE = &H8&
Private Const PAGE_READWRITE = &H4&
Private Const MEM_RESERVE = &H2000
Private Const MEM_COMMIT = &H1000
Private Const MEM_RELEASE = &H8000
Private Const PROCESS_VM_OPERATION = &H8
Private Const PROCESS_VM_READ = &H10
Private Const PROCESS_VM_WRITE = &H20
Private hWndlvw As Long
Function ListViewGetText(ByVal hwnd As Long, ByVal iSubitem As Integer, ByVal iItem As Integer) As String
Dim lngProcID As Long, lngProcHandle As Long
Dim typLvItem As LVITEM, strLvItem As String
Dim lngVarPtr1 As Long, lngVarPtr2 As Long
Dim lngMemVar1 As Long, lngMemVar2 As Long
Dim lngMemLen1 As Long, lngMemLen2 As Long
Call GetWindowThreadProcessId(hwnd, lngProcID)
If lngProcID <> 0 Then
lngProcHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, lngProcID)
If lngProcHandle <> 0 Then
strLvItem = String(255, vbNullChar)
lngVarPtr1 = StrPtr(strLvItem)
lngVarPtr2 = VarPtr(typLvItem)
lngMemLen1 = LenB(strLvItem)
lngMemLen2 = LenB(typLvItem)
lngMemVar1 = VirtualAllocEx(lngProcHandle, 0, lngMemLen1, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
lngMemVar2 = VirtualAllocEx(lngProcHandle, 0, lngMemLen2, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
With typLvItem
.cchTextMax = 255
.iItem = iItem
.iSubitem = iSubitem
.mask = LVIF_TEXT
.pszText = lngMemVar1
End With
Call WriteProcessMemory(lngProcHandle, ByVal lngMemVar1, ByVal lngVarPtr1, lngMemLen1, 0)
Call WriteProcessMemory(lngProcHandle, ByVal lngMemVar2, ByVal lngVarPtr2, lngMemLen2, 0)
Call SendMessage(hwnd, LVM_GETITEM, ByVal 0, ByVal lngMemVar2)
Call ReadProcessMemory(lngProcHandle, ByVal lngMemVar1, ByVal lngVarPtr1, lngMemLen1, 0)
strLvItem = StrConv(strLvItem, vbUnicode)
strLvItem = Left(strLvItem, InStr(1, strLvItem, vbNullChar) - 1)
ListViewGetText = strLvItem
Call VirtualFreeEx(lngProcHandle, ByVal lngMemVar1, lngMemLen1, MEM_RELEASE)
Call VirtualFreeEx(lngProcHandle, ByVal lngMemVar2, lngMemLen2, MEM_RELEASE)
Call CloseHandle(lngProcHandle)
End If
End If
End Function
Private Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
hWndlvw = FindWindowEx(hwnd, 0&, "ListView20WndClass", "")
EnumWindowsProc = (hWndlvw = 0) 'Stop when we find first listview
End Function
' This demonstration example finds first child window with class "ListView20WndClass"
' which may not be what you want. Use your own method to find the real hWnd that you want
Public Function FindListView() As Long
EnumWindows AddressOf EnumWindowsProc, 0&
FindListView = hWndlvw
End Function
Public Function SelectedItem(ByVal hwnd As Long, ItemPos As Long)
Dim lProcID As Long
Dim hProc As Long
Dim lxprocLVITEM As Long
Dim LV_ITEM As LVITEM
GetWindowThreadProcessId hwnd, lProcID ' Get the process ID in which the ListView is running
If lProcID <> 0 Then
hProc = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, lProcID) ' makwe sure we have read write permissions in the process space
If hProc <> 0 Then
lxprocLVITEM = VirtualAllocEx(hProc, 0, LenB(LV_ITEM), MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE) ' Grab enough memory in the other procedure's space to hold our LV_ITEM
' Set up our local LV_ITEM to change the selected item
LV_ITEM.mask = LVIF_STATE
LV_ITEM.state = True
LV_ITEM.stateMask = LVIS_SELECTED
' Copy the local LV_ITEM into the space we reserved in the foreign process
WriteProcessMemory hProc, ByVal lxprocLVITEM, ByVal VarPtr(LV_ITEM), LenB(LV_ITEM), 0
' Now send the message, but pass the address of the copy of our LV_ITEM that now exists in the foreign process instead of our local versiony
SendMessage hwnd, LVM_SETITEMSTATE, ItemPos, ByVal lxprocLVITEM
' Clean up
VirtualFreeEx hProc, ByVal lxprocLVITEM, LenB(LV_ITEM), MEM_RELEASE
CloseHandle hProc
End If
End If
End Function
Function GetListViewCount(ByVal hwnd As Long) As Long
'this simply get number of items
GetListViewCount = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, ByVal 0)
End Function
Function GetItemSelected(hwnd As Long) As Long
Dim i As Long, Index As Long
For i = 1 To GetListViewCount(hwnd)
Index = SendMessage(hwnd, LVM_GETITEMSTATE, i - 1, ByVal LVIS_SELECTED)
If Index > 0 Then
GetItemSelected = i
Exit For
End If
Next
End Function
y en un formulario con un listview y 4 botones
Dim Handle As Long
Dim Index As Long
Private Sub Command1_Click()
Index = InputBox("Selectiona el index")
SelectedItem Handle, Index
End Sub
Private Sub Command2_Click()
Index = InputBox("Selectiona el index del cual quieres ver")
MsgBox ListViewGetText(Handle, 0, Index)
End Sub
Private Sub Command3_Click()
MsgBox "el listview tiene " & GetListViewCount(Handle) & " Items"
End Sub
Private Sub Command4_Click()
MsgBox "El item selecionado es el " & GetItemSelected(Handle)
End Sub
Private Sub Form_Load()
ListView1.View = lvwList
ListView1.HideSelection = False
ListView1.ListItems.Add , , "hola"
ListView1.ListItems.Add , , "Mansana"
ListView1.ListItems.Add , , "Sapallo"
ListView1.ListItems.Add , , "terotero"
Handle = ListView1.hwnd
End Sub
para sacar los iconos del listview tenes que hacer un sendmesage con la constante getimagelist , y despues usar lo podes usar con imagelistdraw (disculpa que escriva bien las apis es que estoy en laburo :})
Saludos
si esta muy bueno ese ejemplo,pero como decis se incrementa el 8 kb cada vez que consultas o a veces mas :-(
saludos.