永发信息网

VB SendMessage引起内存不能读

答案:2  悬赏:30  手机版
解决时间 2021-04-29 15:15
我用SendMessage怎么引起内存不能读呢?
下面是我的源码:
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
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 Const WM_GETTEXT = &HD
Public a, b As Long

Private Sub Command1_Click()
a = FindWindow(vbNullString, "Form1")
End Sub

Private Sub Command2_Click()
b = FindWindowEx(a, 0, "ThunderRT6TextBox", vbNullString)
  Dim tempstr As String * 256
   
  Dim rtn As Long
   
  rtn = SendMessage(b, WM_GETTEXT, 257, tempstr)
   
  tempstr = Trim(tempstr)

MsgBox tempstr
End Sub

引起了内存不能读
最佳答案

你缓冲区的长度是256,怎么能读取257字节呢?


rtn = SendMessage(b, WM_GETTEXT, 256, tempstr)


或者用GetWindowText

全部回答
1. 对于Win32标准类型来说,并没有String这个类型,Win32API中对于字符串只有以下类型(C语言)LPSTR == char *LPCSTR == const char *LPWSTR == wchar_t *LPCWSTR == const wchar_t *对于VB来说,String类型相对于OLE中VC是BSTR,不是通用的Win32API类型。看看API中的定义SendMessage是用的 lParam As Any,没有ByVal,即是按地址传递的,就是Str(0)这个变量的内存地址,如果你知道有一个隐藏函数ValPtr也可以这样写:SendMessage Text1.hwnd, EM_GETLINE, 2, ByVal ValPtr(Str(0))定义一个Byte的数组而不是String,是因为在Win32Api中,所有的字符串都是的字符数组,标准的C语言是没有字符串类型的。SendMessage Text1.hwnd, EM_GETLINE, 2, Str(0)这句话的意思就是,给Text1发送一个EM_GETLINE消息,从第2行(最上面一行是第0行)开始读取字符串,并把数据存放到地址为Str(0)的空间中。所以在这个地方不能使用String类型,必须使用Byte数组,如果你NB,也可以这样写Dim s As StringS = Space(128)S(0) = Chr(&100H)SendMessage Text1.hwnd, EM_GETLINE, 2, ByVal StrPtr(S)我没有实验,不过理论上可以用StrPtr这个函数的2. 在Win32API中找到了对于EM_GETLINE第二个参数的定义:lParamA pointer to the buffer that receives a copy of the line. Before sending the message, set the first word of this buffer to the size, in TCHARs, of the buffer. For ANSI text, this is the number of bytes; for Unicode text, this is the number of characters. The size in the first word is overwritten by the copied line.加粗的地方看懂了吗?意思就是说这个数组的第一个字表示的是可以容纳缓冲区的大小。也就是说Str(0)和Str(1)表示的是缓冲区里面的大小,因为Byte是一个字节,Word是两个字节,内存中0001字节反转之后就是&0100H就是256,表示这个缓冲区的最大字符容量为256个字节。3. 默认的情况下,数组的其实部分是从0开始的,定义的时候是定义的长度,而不是上下标。例如 Str(256)对于Str(0)到Str(255)都是有效的。Str(1)在已经解答了,因为要让第一个字第数值为256,所以就必须设置Str(1)=1,而不出Str(0)=1。这个事因为对于x86架构的处理器中是Little-Endian的字节序,高字节在后低字节在前。这个是在《计算机组成原理》中需要重点讨论的。4. 你仔细看看API定义使用的是SendMessageA,而不是SendMessageW,这说明定义的函数使用的是ANSI的字符编码,而不出Unicode,而VB内部使用的都是Unicode,所以对于这个问题,最后返回的字符串都是ANSI的,对于这个字符串数组,我们需要同过StrConv对其进行转化为Unicode。当然你也可以使用SendMessageW,这样最后可以直接Text2.Text=CStr(Str)这个语句直接赋值了。PS: 如果要弄懂里面的东西,还是需要对于Win32API有所了解,这里面已经涉及到比较高级的VB技术了,如果你对VC有点了解的话,我相信对于理解这个问题会有改善的。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
诺基亚5320XM现在多少钱?
精油丰胸有没有副作用,为什么要避开乳头呢
音速最BT呢歌 不论单机还是WL
怎么样的男人是成功的男人
棉花糖組和的資料
如何隐藏C盘文件
电氧焊工证
有没有让脸部毛孔变小的简单办法??要容易实
请问网友跟朋友有区别吗?区别又在哪里?
栗庙人家在哪里啊,我有事要去这个地方
漯河有手工艺品加工么?
台风是高气压还是低气压?
成为问问达人一般要多长时间
求一篇“谈论该不该当老师”的英语作文
8.9-8.13下午有没有经验翻倍
推荐资讯
用360浏览器的时候链接用左键直接点击都打不
为什么我的空间有黄钻就不能添加模块了,没黄
关于拍拍购物
请问、螺旋测微记怎么读数的额
好尴尬的用英语怎么说,此时此刻我很尴尬用英
还是老天的罪孽?“人的命,天注定”吗!
谜语:猜一个字
反恐中怎么查询战斗成绩
电脑重装系统后网速不如以前?
普宁市大坪国税局这个地址在什么地方,我要处
松绿村我想知道这个在什么地方
磨山港湾生鲜市场怎么去啊,有知道地址的么
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?