原来显示背包物品的方法不是很完善,因为是游戏里鼠标移上去时候的提示,在没有打开物品窗口的时候是不能显示的。最后感谢gaiyue的强烈要求!
这次用了真正的物品显示方法,原理就是得到物品的ID然后用已知的对应表替换成文字物品名称。
学习目的:
1.显示背包物品
2.读取指定文件
内容:
1.在模块添加以下代码:
'读配置文件
Public Declare Function GetPrivateProfileString& Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String)
2.以下是用于刷新背包物品名称Timer3的代码:
Private Sub Timer3_Timer() '用于刷新背包物品名称
Dim base As Long '存储地址
Dim mecxi As Long '存储地址
Dim pn As Integer '循环变量
Dim pd As Long '判断变量
'Dim BaoName(35) As Byte '存储物品名称
Dim BaoN As Long '背包格数
List3.Clear '清除,用于刷新物品列表
If hProcess Then
ReadProcessMemory hProcess, ByVal Buffer, mecxi, 4, 0
ReadProcessMemory hProcess, ByVal mecxi + &H24, mecxi, 4, 0
ReadProcessMemory hProcess, ByVal mecxi + &H854, mecxi, 4, 0
ReadProcessMemory hProcess, ByVal mecxi + &H10, BaoN, 4, 0 '得到背包格数
ReadProcessMemory hProcess, ByVal mecxi + &HC, mecxi, 4, 0
For pn = 0 To BaoN - 1 '循环查询背包内所有格子内的物品
ReadProcessMemory hProcess, ByVal mecxi + pn * 4, base, 4, 0
ReadProcessMemory hProcess, ByVal base + &H14, pd, 4, 0 '得到格子内物品数量,因为没有确认格内存在物品的地址,所以暂用这个判断是否存在物品
If pd > 0 Then '大于0表示存在物品
ReadProcessMemory hProcess, ByVal base + &H8, base, 4, 0 '得到物品ID
ItemList (CStr(base)) '交给转换名称函数处理
'ReadProcessMemory hProcess, ByVal base + &H44, base, 4, 0
'ReadProcessMemory hProcess, ByVal base + &HE, BaoName(0), 34, 0
'If InStr(BaoName, "/r") - 1 > 0 Then List3.AddItem Left(BaoName, InStr(BaoName, "/r") - 1)
End If
base = 0
pd = 0
Next pn
Frame3.Caption = "背包物品 * " & List3.ListCount '根据list3的项目数得到物品数量
End If
End Sub
3.自建一个函数用于把得到ID转换成物品名称,以下是代码:
Private Sub ItemList(ItemName As String) '用于转换物品名称函数
Dim name As String '存储物品名称
Dim dz As String '存放文件地址
Dim a As Integer '用于判断
name = Space$(35) '定义读取值的字串宽度
a = GetPrivateProfileString("item", ItemName, "", name, 35, App.Path & "/config.ini") '在文件中查找匹配物品名称
name = Trim$(name) '去掉多余字符
If a = 0 Then '输出到List的判断
List3.AddItem ItemName & "****" '当无匹配项目则输出物品ID和无资料
Else
List3.AddItem name
End If
End Sub
4.我用config.ini保存物品名称对应表
[item]
28=精炼石
34=菜鸟布衣(男)
35=丝衣(男)
36=缎衣(男)
38=掩心甲(男)
39=鳞甲(男)
40=金缕甲(男)
41=豹皮战甲(男)
42=狮蛮甲(男)
............
5.程序运行,物品名称正确的显示出来,不过随着游戏的更新你也许需要不断的更新你的文config.ini。
注:
背包物品地址:
[[[[&H8C9E54]+&h24]+&h854]+&h10] 是角色背包最大容量
[[[[&H8C9E54]+&h24]+&h854]+&hC] 是角色背包首地址
[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号] 是格子物品首地址(格子数从0开始)
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h14] 是此格物品的数量
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h18] 是此格物品的堆叠上限
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h4] 背包内物品类型
(装备&戒指&项链为0,生产材料&声望材料为1,药品为2,精炼石为7,垃圾石头为8,配方为17,宠物牌为23)
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h8] 物品ID
GetPrivateProfileString:
DWORD GetPrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName);
参数的意义:
lpAppName : 配置文件的section名
lpKeyName : 配置文件的key名
lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.
lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.
nSize : 目的缓存器的大小.
lpFileName : 是完整的INI文件名.
例:
config.ini的内容:
[item]
28=精炼石
34=菜鸟布衣(男)
35=丝衣(男)
36=缎衣(男)
38=掩心甲(男)
39=鳞甲(男)
40=金缕甲(男)
41=豹皮战甲(男)
42=狮蛮甲(男)
GetPrivateProfileString& "item", 36, "", name, 35, App.Path & "/config.ini")
在[item]下,找36这项,将值存入变量name,宽度为35,文件地址为App.Path & "/config.ini"
这次用了真正的物品显示方法,原理就是得到物品的ID然后用已知的对应表替换成文字物品名称。
学习目的:
1.显示背包物品
2.读取指定文件
内容:
1.在模块添加以下代码:
'读配置文件
Public Declare Function GetPrivateProfileString& Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String)
2.以下是用于刷新背包物品名称Timer3的代码:
Private Sub Timer3_Timer() '用于刷新背包物品名称
Dim base As Long '存储地址
Dim mecxi As Long '存储地址
Dim pn As Integer '循环变量
Dim pd As Long '判断变量
'Dim BaoName(35) As Byte '存储物品名称
Dim BaoN As Long '背包格数
List3.Clear '清除,用于刷新物品列表
If hProcess Then
ReadProcessMemory hProcess, ByVal Buffer, mecxi, 4, 0
ReadProcessMemory hProcess, ByVal mecxi + &H24, mecxi, 4, 0
ReadProcessMemory hProcess, ByVal mecxi + &H854, mecxi, 4, 0
ReadProcessMemory hProcess, ByVal mecxi + &H10, BaoN, 4, 0 '得到背包格数
ReadProcessMemory hProcess, ByVal mecxi + &HC, mecxi, 4, 0
For pn = 0 To BaoN - 1 '循环查询背包内所有格子内的物品
ReadProcessMemory hProcess, ByVal mecxi + pn * 4, base, 4, 0
ReadProcessMemory hProcess, ByVal base + &H14, pd, 4, 0 '得到格子内物品数量,因为没有确认格内存在物品的地址,所以暂用这个判断是否存在物品
If pd > 0 Then '大于0表示存在物品
ReadProcessMemory hProcess, ByVal base + &H8, base, 4, 0 '得到物品ID
ItemList (CStr(base)) '交给转换名称函数处理
'ReadProcessMemory hProcess, ByVal base + &H44, base, 4, 0
'ReadProcessMemory hProcess, ByVal base + &HE, BaoName(0), 34, 0
'If InStr(BaoName, "/r") - 1 > 0 Then List3.AddItem Left(BaoName, InStr(BaoName, "/r") - 1)
End If
base = 0
pd = 0
Next pn
Frame3.Caption = "背包物品 * " & List3.ListCount '根据list3的项目数得到物品数量
End If
End Sub
3.自建一个函数用于把得到ID转换成物品名称,以下是代码:
Private Sub ItemList(ItemName As String) '用于转换物品名称函数
Dim name As String '存储物品名称
Dim dz As String '存放文件地址
Dim a As Integer '用于判断
name = Space$(35) '定义读取值的字串宽度
a = GetPrivateProfileString("item", ItemName, "", name, 35, App.Path & "/config.ini") '在文件中查找匹配物品名称
name = Trim$(name) '去掉多余字符
If a = 0 Then '输出到List的判断
List3.AddItem ItemName & "****" '当无匹配项目则输出物品ID和无资料
Else
List3.AddItem name
End If
End Sub
4.我用config.ini保存物品名称对应表
[item]
28=精炼石
34=菜鸟布衣(男)
35=丝衣(男)
36=缎衣(男)
38=掩心甲(男)
39=鳞甲(男)
40=金缕甲(男)
41=豹皮战甲(男)
42=狮蛮甲(男)
............
5.程序运行,物品名称正确的显示出来,不过随着游戏的更新你也许需要不断的更新你的文config.ini。
![](http://www.ghoffice.com/bbs/attachment/Fid_74/74_16889_ee23eb4e3572381.jpg)
注:
背包物品地址:
[[[[&H8C9E54]+&h24]+&h854]+&h10] 是角色背包最大容量
[[[[&H8C9E54]+&h24]+&h854]+&hC] 是角色背包首地址
[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号] 是格子物品首地址(格子数从0开始)
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h14] 是此格物品的数量
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h18] 是此格物品的堆叠上限
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h4] 背包内物品类型
(装备&戒指&项链为0,生产材料&声望材料为1,药品为2,精炼石为7,垃圾石头为8,配方为17,宠物牌为23)
[[[[[[&H8C9E54]+&h24]+&h854]+&hC]+4*格子序号]+&h8] 物品ID
GetPrivateProfileString:
DWORD GetPrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName);
参数的意义:
lpAppName : 配置文件的section名
lpKeyName : 配置文件的key名
lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.
lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.
nSize : 目的缓存器的大小.
lpFileName : 是完整的INI文件名.
例:
config.ini的内容:
[item]
28=精炼石
34=菜鸟布衣(男)
35=丝衣(男)
36=缎衣(男)
38=掩心甲(男)
39=鳞甲(男)
40=金缕甲(男)
41=豹皮战甲(男)
42=狮蛮甲(男)
GetPrivateProfileString& "item", 36, "", name, 35, App.Path & "/config.ini")
在[item]下,找36这项,将值存入变量name,宽度为35,文件地址为App.Path & "/config.ini"