我用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
引起了内存不能读
VB SendMessage引起内存不能读
答案:2 悬赏:30 手机版
解决时间 2021-04-29 15:15
- 提问者网友:记得曾经
- 2021-04-29 09:41
最佳答案
- 五星知识达人网友:十年萤火照君眠
- 2021-04-29 10:43
你缓冲区的长度是256,怎么能读取257字节呢?
rtn = SendMessage(b, WM_GETTEXT, 256, tempstr)
或者用GetWindowText
全部回答
- 1楼网友:狂恋
- 2021-04-29 11:59
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有点了解的话,我相信对于理解这个问题会有改善的。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯