在使用SPComm接收数据时,要用到指针,函数原型为:
procedure TForm1.commReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
end;
其收到数据时,它提供了一个指针Buffer,指向这个存放数据的缓冲区的首地址,长度为BufferLength,这样就知道收到的是什么东东了,可以有两种方法取出其中内容:
var
pc:PChar;
begin
pc:=PChar(Buffer);
Memo1.Lines.Add(String(pc));
end;
一种是把Buff缓冲区的内容Copy出来
var
sbuf:String;
begin
sbuf:=Copy(PChar(buffer),1,BufferLength);
Memo1.Lines.Add(sbuf);
end;
或是
var
sbuf:PChar;
begin
StrCopy(sbuf,PChar(Buffer));
Memo1.Lines.Add(sbuf);
end;
或是直接了当的显示出来:
Memo1.Lines.Add('COM接收:' + Copy(string(buffer^),1,BufferLength));
还有一种利用数组,定义一个固定大小的缓冲区,但需要判断接收的长度是否大于定义的大小,如果大于,则要循环存放取出的内容:
var
Len:integer;
cbuf: array[0..511] of char;
begin
if BufferLength <= 511 then
begin
Move(buffer^, cbuf, BufferLength);
cbuf[BufferLength] := Char(0);
rstr:=rstr+String(cbuf);
end
else
begin
Len:=BufferLength div 511;
for i:=0 to len-1 do
begin
Move(Pointer(Integer(Buffer)+i*511)^,cBuf,511);
cbuf[511]:=Char(0);
rstr:=rstr+String(cbuf);
end;
Move(Pointer((Integer(Buffer)+len*511))^,cbuf,BufferLength-len*511);
cbuf[BufferLength-len*511]:=Char(0);
rstr:=rstr+String(cbuf);
end;
end;
当接收十六进制字符串时:
Sleep(100);//等待100ms,保证接收到所有数据
if bShow then
begin
for i:=0 to BufferLength-1 do
begin
rstr:=rstr+IntToHex(Byte(Pointer(Integer(Buffer)+i)^),2)+' ';
end; //Pointer(Integer(Buffer)+i)^
if cbShowLine.Checked then
begin
memRec.Lines.Add(rstr);
end
else
begin
//memRec.Text := memRec.Text + hexstr;
memRec.SelStart := memRec.GetTextLen;
memRec.SelLength := 0;
//memRec.Perform(EM_SCROLLCARET, 0, 0);
memRec.SelText := rstr;
end;
end;
这里在Memo里显示字符时,当字符多于显示Memo大于小时,始终显示最后一行有两种方法:
memRec.Text := memRec.Text + hexstr;
memRec.SelStart := memRec.GetTextLen;
memRec.Perform(EM_SCROLLCARET, 0, 0);
或者用:
memRec.SelStart := memRec.GetTextLen;
memRec.SelLength := 0;
memRec.SelText := rstr;