- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个VB6代码需要转换为Delphi代码,所有代码都已转换,但是当我遇到InstrB时,我在delphi中找不到任何等效的函数。 VB6的InStrB有与delphi等效的代码吗?
这是 VB6 代码:
'Author: John Kozee
'Purpose: Enumerate Label captions given a known hWnd
'Date: June 12, 2004
Option Explicit
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Const VBM_WINDOWTITLEADDR = &H1091
Private Declare Function SendMessage Lib "USER32.DLL" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, wParam As Any, lParam As Any) As Long
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 blnheritHandle As Long, ByVal dwAppProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const MEM_PRIVATE = &H20000
Private Const MEM_COMMIT = &H1000
Private Const PROCESS_VM_READ = (&H10)
Private Const PROCESS_VM_WRITE = (&H20)
Private Const PROCESS_VM_OPERATION = (&H8)
Private Const PROCESS_QUERY_INFORMATION = (&H400)
Private Const PROCESS_READ_WRITE_QUERY = PROCESS_VM_READ + PROCESS_VM_WRITE + PROCESS_VM_OPERATION + PROCESS_QUERY_INFORMATION
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 Declare Function VirtualQueryEx& Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength 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 abBuffer() As Byte 'Heap Buffer
Private lBaseAddress As Long
Private hProcess As Long
Public Sub GetFormLabels(hwnd As Long, OutData As String)
Dim sClass As String
Dim lRet As Long
Dim pid As Long
Dim hProcess As Long
Dim lFormCaptionHeapAddress As Long
Dim lpMem As Long
Dim lLenMBI As Long
Dim lBytesRead As Long
Dim mbi As MEMORY_BASIC_INFORMATION
'Make sure we are working with a VB Form hWnd
sClass = Space(256)
lRet = GetClassName(hwnd, sClass, 255)
sClass = Left(sClass, lRet)
If Not sClass = "ThunderRT6FormDC" Then
MsgBox "This function only works on VB RunTime 6 Forms ThunderFormRT6DC"
Exit Sub
End If
'Now get the internal heap address of the form caption. All that we need can be found in this heap (hopefully!)
'This is done with a little undocumented SendMessage magic
lFormCaptionHeapAddress = SendMessage(hwnd, VBM_WINDOWTITLEADDR, ByVal 0&, ByVal 0&)
'Get a handle on the process with required access
lRet = GetWindowThreadProcessId(hwnd, pid)
If pid = 0 Then
MsgBox "Unable to determine pid of this hwnd."
Exit Sub
End If
hProcess = OpenProcess(PROCESS_READ_WRITE_QUERY, False, pid)
'Get the Heap at the caption point
lLenMBI = Len(mbi)
lpMem = lFormCaptionHeapAddress
mbi.AllocationBase = lpMem
mbi.BaseAddress = lpMem
lRet = VirtualQueryEx(hProcess, ByVal lpMem, mbi, lLenMBI)
If lRet <> lLenMBI Then GoTo Finished
'Now go back and get the entire heap
lBaseAddress = mbi.AllocationBase
lpMem = lBaseAddress
mbi.BaseAddress = lBaseAddress
mbi.RegionSize = 0
lRet = VirtualQueryEx(hProcess, ByVal lpMem, mbi, lLenMBI)
If lRet <> lLenMBI Then GoTo Finished
'A couple of sanity checks, just to be safe
If Not ((mbi.lType = MEM_PRIVATE) And (mbi.State = MEM_COMMIT) And mbi.RegionSize > 0) Then
MsgBox "Unexpected Heap Type, State, or Size."
GoTo Finished
End If
'Allocate a buffer and read it in
ReDim abBuffer(0 To mbi.RegionSize - 1)
ReadProcessMemory hProcess, ByVal mbi.BaseAddress, abBuffer(LBound(abBuffer)), mbi.RegionSize, lBytesRead
'So far, so good. Things get messy from here. We have to
'do some manual parsing of the buffer to get what we are after. To
'make things easier, I'll will get every label on every form in the
'exe. Otherwise, you will need to first find the form that is
'reference the caption. Then find every label between it and the next
'form.
Dim iCnt As Integer
Dim al() As Long
Debug.Print "start"
'Print all of the label captions
If EnumVBObjectPtrs("VB.Label", 44, al) > 0 Then
For iCnt = LBound(al) To UBound(al)
OutData = OutData & "|Hit at: " & Hex(al(iCnt) + lBaseAddress + 44) & " Object At: " & Hex(al(iCnt) + lBaseAddress) & " Caption =: " & GetLabelCaption(al(iCnt))
Next iCnt
End If
Finished:
CloseHandle hProcess
abBuffer() = ""
End Sub
Private Function GetLabelCaption(lpLocalObjPtr As Long) As String
Dim lStrPtr As Long
'Get local pointer to caption
CopyMemory lStrPtr, abBuffer(lpLocalObjPtr + 136), 4
lStrPtr = lStrPtr - lBaseAddress
'Get caption
If lStrPtr <> 0 Then
GetLabelCaption = StrConv(MidB(abBuffer, lStrPtr + 1, 260), vbUnicode)
End If
GetLabelCaption = Left$(GetLabelCaption, InStr(GetLabelCaption, vbNullChar) - 1)
End Function
'This function will search the buffer for a given VBObjectIDString, then
'find the start of that control by searching for a refence to it in the 600
'bytes prior.
'It then finds any object of that type by searching the buffer for any
'references to the Heap Location of that control, and adds it to the enumeration
'if the reference hit position is at the correct offset (pos-offset = lBaseAddress)
'setting the EnumObj entry to the start location (local buffer address) and
'returns the counrt
Private Function EnumVBObjectPtrs(VBObjectIDString As String, _
lOffset As Long, _
EnumObj() As Long) As Integer
Dim abObjectPtr(0 To 3) As Byte 'LittleEndian byte array of the Heap Address of the VBObject
Dim abBaseAddress(0 To 3) As Byte 'LittleEndian byte array of the Heap Base Memory Address
Dim abLong(0 To 3) As Byte 'Byte array for ptr manipulation
Dim lPtr As Long 'Local Buffer pointer for search hits
Dim lHeapPtr As Long 'Heap pointer (lPtr + lBaseAddress)
Dim iCnt As Integer
Dim alRet() As Long
Dim iPos As Long
'Find the location of the VBObjectIDString string
Dim Val
Val = StrConv(VBObjectIDString, vbFromUnicode)
MsgBox Val
lPtr = InStrB(1, abBuffer, Val) - 1
lHeapPtr = lBaseAddress + lPtr
If lPtr = 0 Then Exit Function
'We now need to find the location that points to the start of the object
'which should be 244 bytes prior (on XP at least) we go back 300 just in
'case. This is at offset 36, so we'll need to adjust back to the beginning
'of the object
CopyMemory abLong(0), lHeapPtr, 4
lPtr = InStrB(lPtr - 600, abBuffer, abLong) - 1
If lPtr = 0 Then Exit Function
lPtr = lPtr - 36 'Adjust back to the beginning of the object
lHeapPtr = lBaseAddress + lPtr
CopyMemory abObjectPtr(0), lHeapPtr, 4
'Turn the lBaseAddress into LittleEndian byte array for searching
CopyMemory abBaseAddress(0), lBaseAddress, 4
'Loop through the buffer
lPtr = 1
Do Until lPtr = 0
'Find a reference to this object
lPtr = InStrB(lPtr, abBuffer, abObjectPtr)
If lPtr > 0 Then
'make sure that this is really a VB object
'move back from the offset of the object
'and make sure that it has the correct base memory value
iPos = InStrB(lPtr - lOffset - 1, abBuffer, abBaseAddress)
If iPos = lPtr - lOffset Then
ReDim Preserve alRet(0 To iCnt)
alRet(iCnt) = lPtr - lOffset - 1
iCnt = iCnt + 1
End If
'Keep searching from the next byte
lPtr = lPtr + 1
End If
Loop
EnumVBObjectPtrs = iCnt
EnumObj = alRet
End Function
最佳答案
此函数通常用于搜索字符串中的子字符串。所以我猜想可能的等价物是Pos
。另一方面,也许您的代码是在字节数组而不是文本上运行的。在这种情况下,答案可能会有所不同。我不知道与 Pos
等效的二进制文件,但编写一个非常容易。
即使经过您的编辑,我们也没有太多背景信息。你知道这段代码吗?你知道它在做什么吗?它操作什么数据类型等等。如果您可以提供此类详细信息,那么也许您会得到更明确的答案。
更新
考虑到您对问题的最新编辑,代码似乎正在使用 InStrB
来搜索字节数组中的特定模式。您需要编写一个 Delphi 辅助函数来执行此操作,因为我不相信标准运行时库具有这样的函数。
关于delphi - InStrB VB6 到 Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27797977/
请在标记为重复之前阅读。 我正在创建一组依赖智能卡进行身份验证的应用程序。到目前为止,每个应用程序都单独控制智能卡读卡器。几周后,我的一些客户将同时使用多个应用程序。因此,我认为创建一个控制身份验证过
我想设置一个小程序,从数据库中检索信息,然后根据请求将该信息分发给另一个程序。例如,一个名为“Master”的程序将从数据库中检索数据并创建一个对象集合(列表、数组等,无论哪种效果最好),然后一个名为
我有两台电脑,都装有 XE2。我以为我在两者上安装了相同的安装,但在其中一个上安装第 3 方软件包时遇到问题,而另一个则正常。 无论如何,我希望两者都一样。最简单的人可能只是通过移入我的 Dropbo
有冲突吗? 最佳答案 所有新版本的 Delphi 始终可以安全地安装到旧版本的下一个版本。 每个新版本都应安装在其自己的目录中。 如果您要安装多个版本,请始终先安装最旧的版本,然后再安装最新版本。 我
快速提问:如果我从代码中删除 // 或 (* *) 中的注释,Delphi 2007 的执行时间会受到影响吗?最终结果是一个可能包含数千行注释的 EXE 文件。 最佳答案 编译器会简单地忽略注释,并且
我必须对照另一个文件检查文件的每一行。 如果第二个文件中存在第一个文件中的一行,则必须删除它。 现在,我正在使用2个列表框,并且“对于listbox1.items.count-1可以开始...” 我的
我正在尝试在访问数据库中添加一些数据。但是我有麻烦,因为这会返回错误: ADOQuery1 missing sql property 实现了对代码的几次修改,到目前为止没有任何效果。 我究竟做错了什么
我用Delphi 5编写了一个程序,在Windows 8 32位PC上可以正常运行。我发现在Windows 7 64位笔记本电脑上运行它最终会导致reallocmem错误,而该错误在32位PC上不会发
看来这是我需要的工具,用于提取XML并与TClientDataset连接。我已经在几篇文章和文档中看到了它,但是我无法在XE2组件列表中找到它-在任何地方!应该在哪里?是否在可能未安装的可选软件包中?
我正在寻找一个非常通用的TDBTree组件,我想听听一些建议。我正在特别寻找一种显示主记录和“ n”个链接表记录的记录。 (我的意思是来自各个表的记录)。例如,TDBTree将钩接到主表,明细表1,附
我需要将按钮制作成旋转三角形的形状(或者说是任何多边形)。谁能提供任何建议? 最佳答案 查看Win32 API CreatePolygonRgn()和SetWindowRgn()函数,以创建一个HRG
你好专家 我的JvPasswordForm1有一个旧的JVC组件。 似乎该组件不再存在:它替换为哪个组件? 重新获得 最佳答案 尝试查找TJvLoginDialog,TjvPassword已合并到其中
几天前,我已经设置了我的开发环境(在装有Win 7的VM和域上的用户的VM上安装了delphi 2009),并安装了我的组件(jedi's,devExpress,ADS等)。 今天,我启动机器,打开d
开始对控件进行子分类的正确位置/时间是什么? 恢复原始窗口proc的正确时间是几点? 现在我在表单创建过程中子类化: procedure TForm1.FormCreate(Sender: TObje
有人可以给我一些有关如何登录访问的网页(使用任何网络浏览器)的指示吗?我应该建立一个全球代理....钩住网络....吗?我需要记录的只是页面地址,而不是其中包含的信息。 我正在使用Delphi。 谢谢
我创建了一个像 TMyClass = class(TObject) private FList1: TObjectList; FList2: TObjectList; public end;
我有一个BPG文件,我已对其进行修改以用作我们公司的自动构建服务器的make文件。为了使其正常工作,我必须进行更改 用途*用途 'unit1.pas'中的unit1 * unit1 'unit2.pa
我将Delphi 7代码迁移到了Delphi XE4。我在Delphi XE4的LoadFromStram方法中遇到错误,但对于Delphi 7来说也可以正常工作。 错误: First chance
我正在尝试学习一些新技巧,以便更好地组织我在 Delphi 中的单元中的一些源代码。 我注意到我访问的一些函数或方法似乎是类中的类,但是我还没有成功地在类中创建一个工作类,虽然它编译得很好,但在执行代
我有一个包含许多类的大单元,现在我想通过将某些类分成新的单元来重构该单元。 我不得不承认我缺乏使用Delphi内置IDE功能的经验。利用内置功能“查找|查找对类型的本地引用”并没有多大帮助,因为类方法
我是一名优秀的程序员,十分优秀!