对于一些VB6工程代码来说,需要完成从VB到VB.net的转换,在转换过程中需要注意很多内容,利用VB.net的直接转换功能很少能完全成 功,需要我们付出很大的努力。
下面的VB.net代码实现从其他应用程序中的ListView控件中异地获取文本内容,是从VB6的代码中转换而来,包括一些旧类型的转换和数据类型声明的变 化。
Option Explicit On Module Module1 Public Structure LV_ITEMA Dim mask As Integer Dim iItem As Integer Dim iSubItem As Integer Dim state As Integer Dim stateMask As Integer Dim pszText As Integer Dim cchTextMax As Integer Dim iImage As Integer Dim lParam As Integer Dim iIndent As Integer End Structure 'Constants Private Const LVFI_PARAM = 1 Private Const LVM_FIRST = &H1000 Private Const LVM_FINDITEM = LVM_FIRST + 13 Private Const LVM_GETITEMTEXT = LVM_FIRST + 45 Private Const LVM_SORTITEMS = LVM_FIRST + 48 Private Const LVM_GETHEADER = LVM_FIRST + 31 Private Const LVM_GETITEMCOUNT = (LVM_FIRST + 4) Private Const HDM_FIRST = &H1200 '// Header messages Private Const HDM_GETITEMCOUNT = (HDM_FIRST + 0) Private Const HDM_ORDERTOINDEX = (HDM_FIRST + 15) Private Const PROCESS_QUERY_INFORMATION = 1024 Private Const PROCESS_VM_OPERATION = &H8 Private Const PROCESS_VM_READ = &H10 Private Const PROCESS_VM_WRITE = &H20 Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF Private Const STANDARD_RIGHTS_required = &HF0000 Private Const MAX_LVMSTRING As Integer = 255 '可根椐读取数据长度设置适当的数值 Private Const MEM_COMMIT = &H1000 Private Const MEM_RELEASE = &H8000 Private Const PAGE_READWRITE = &H4 Private Const LVIF_TEXT As Integer = &H1 'API declarations Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Integer,ByVal lpBaseAddress As Integer,ByRef lpBuffer As Byte,ByVal nSize As Integer,ByVal lpNumberOfBytesWritten As Integer) As Integer Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Integer,ByVal lpAddress As Integer,ByVal dwSize As Integer,ByVal dwFreeType As Integer) As Integer Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Integer,ByRef lpBuffer As LV_ITEMA,ByVal lpNumberOfBytesWritten As Integer) As Integer Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Integer,ByVal flAllocationType As Integer,ByVal flProtect As Integer) As Integer Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer,ByVal bInheritHandle As Integer,ByVal dwProcId As Integer) As Integer Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Integer,ByRef lpdwProcessId As Integer) As Integer Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer,ByVal wMsg As Integer,ByVal wParam As Integer,ByVal lParam As Integer) As Integer Public Function GetListviewItem(ByVal hWindow As Integer,ByVal ProcessID As Integer,ByVal pColumn As Integer,ByVal pRow As Integer) As String Dim Result As Integer Dim myItem As LV_ITEMA Dim pHandle As Integer Dim pStrBufferMemory As Integer Dim pMyItemMemory As Integer Dim strBuffer() As Byte Dim Index As Integer Dim tmpString As String Dim strLength As Integer '****************************** '为动态数组变量重新分配存储空间 '****************************** ReDim strBuffer(MAX_LVMSTRING) '***************************************************************************************************** '打开一个现有进程的句柄,返回值Long,如执行成功,返回进程句柄;零表示失败。会设置GetLastError 'Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long,ByVal bInheritHandle As Long,ByVal dwProcId As Long) As Long '参数 类型及说明 'dwDesiredAccess Long,指定这个句柄要求的访问方法。指定API32.TXT文件中以PROCESS_???开头的一个或多个常数 'bInheritHandle Long,如句柄能够由子进程继承,则为TRUE 'dwProcessId Long,要打开那个进程的进程标识符 '***************************************************************************************************** pHandle = OpenProcess(PROCESS_ALL_ACCESS,False,ProcessID) '***************************************************************************************************** 'VirtualAllocEx(目标进程的句柄,内存区域的大小,分配类型,新分配内存的存取保护类型) 返回所分配页面的基址 '***************************************************************************************************** pStrBufferMemory = VirtualAllocEx(pHandle,MAX_LVMSTRING,MEM_COMMIT,PAGE_READWRITE) '************************************************* '初始化LV_ITEM 结构 'MyItem.iSubItem 列的索引号 'myItem.pszText 数据内容(此处是一个分配的内存地址) '************************************************* myItem.mask = LVIF_TEXT myItem.iSubItem = pColumn myItem.pszText = pStrBufferMemory myItem.cchTextMax = MAX_LVMSTRING '*********************************************************** '把这个结构写入远程进程process's 存储量 'WriteProcessMemory(目标进程的句柄,地址,写入的数据,字节数,0) '*********************************************************** pMyItemMemory = VirtualAllocEx(pHandle,Len(myItem),PAGE_READWRITE) Result = WriteProcessMemory(pHandle,pMyItemMemory,(myItem),0&) '******************************** '发送消息,得到项目信息和写入内存 '******************************** strLength = SendMessage(hWindow,LVM_GETITEMTEXT,pRow,pMyItemMemory) Result = ReadProcessMemory(pHandle,pStrBufferMemory,strBuffer(0),0) tmpString = System.Text.Encoding.Default.GetString(strBuffer).Trim Result = ReadProcessMemory(pHandle,myItem,0) '**************************** '释放分配的内存和关闭进程句柄 '**************************** Result = VirtualFreeEx(pHandle,MEM_RELEASE) Result = VirtualFreeEx(pHandle,MEM_RELEASE) Result = CloseHandle(pHandle) If Len(tmpString) > 0 Then GetListviewItem = tmpString End Function End Module
实现转换的过程其实就是一个按图索骥的过程,按照VB.net丰富的运行错误信息提示,一步步的来完成。
VB6实现代码可参考:
Get listview contents using API
获取其他进程中 ListView的文本
Read the text from another programs listview control