Delphi XE的IDE有个Bug,因此IdUDPServer控件及OnUDPRead事件只好在运行时生成。请不要见怪。我是想通过UDP将Img1中修改的部分发送到服务端,并重画在Img2上。现在能做的是,可以获得需要发送的最小矩形,使用SendBuffer命令以TMemoryStream方式将其划分成最大1024个字节大小进行发送。客户端以'_STARTIMG_'为表示开始,‘_END__IMG_'表示发送结束;服务端接收到“_STARTIMG_”之后开始接收数据,每次直接通过MemRec.Write(Adata, size)写入全局变量MemRec(TMemoryStream)。当服务端收到‘_END__IMG_'之后结束结果,将MemRec内容画到IMG2上。现在,的问题是MemRec无法画到IMG2上,而MemOld则可以。但通过CompareMem命令发现,两者的内容是相同的。这一点实在就想不通了。由于这是一个还没理清头绪的程序,我的表述可能很不清楚。如有需要,请跟贴,我再做详细说明。
//发送程序
procedure TForm1.btn1Click(Sender: TObject);
var
  mem: TMemoryStream;
  Buf: array [0..1023] of Char;
  pos, len: Integer;
  RecStr: String;
  TmpImg1, TmpImg2: TImage;
  BitBuf: TBytes;
begin
  RectNew.Top:=0; RectNew.Left:=0;
  RectNew.Bottom:=rect.Bottom-rect.Top;
  RectNew.Right:=rect.Right-rect.Left;
  form1.Caption:='';  mem:= TMemoryStream.Create;
  TmpImg1:=TImage.Create(self);
  TmpImg1.Picture.Bitmap.Width:=RectNew.Right;
  TmpImg1.Picture.Bitmap.Height:=RectNew.Bottom;  TmpImg1.Canvas.CopyRect(RectNew, img1.Canvas, rect);
  TmpImg1.Picture.Bitmap.SaveToStream(mem);              MemOld.Free;
  MemOld:=TMemoryStream.Create;
  TmpImg2:=TImage.Create(self);
  TmpImg1.Picture.Bitmap.SaveToStream(MemOld);            //mem 和 MemOld的内容均正确//  MemOld.Position:=0;                                   //通过下面三句可以把画正确地画到IMG2中
//  TmpImg2.Picture.Bitmap.LoadFromStream(MemOld);        //为了与传输结果比较,此处的MemOld为一全局变量
//  img2.Canvas.CopyRect(rect, TmpImg2.Canvas,  rectnew);  if mem.Size>0 then begin
    idpclnt1.Send('_STARTIMG_');
    pos:=0;
    while pos<mem.Size do begin
      len:=1024;
      if mem.Size-pos<1024 then len:=mem.Size-pos;
      mem.Read(buf, len);
      SetLength(BitBuf, len);
      Move(buf[1], BitBuf[0], Len);
      idpclnt1.SendBuffer(BitBuf);
      inc(pos, len);
    end;
    idpclnt1.Send('_END__IMG_');
  end;  Form1.Caption:=Form1.Caption+' end';
  mem.Free;
  TmpImg1.Free;
  TmpImg2.Free;
end;//接收程序
procedure Tform1.UDPRead(AThread: TIdUDPListenerThread; AData: TArray<Byte>; ABinding: TIdSocketHandle);
var
  str, str1, str2: string;
  size, i, flag: Integer;
  tmp: TImage;
  NewRect: TRect;
  just: Boolean;
begin
  NewRect.Top:=0;
  NewRect.Left:=0;
  NewRect.Bottom:=rect.Bottom-rect.Top;
  NewRect.Right:=rect.Right-rect.Left;  Flag:=1;
  Size:=Length(AData);
  if size=10 then begin
    SetLength(str, 10);
    for i := 1 to 10 do str[i]:=Char(AData[i-1]);
    if str='_STARTIMG_' then begin
      flag:=0;
      form1.Tag:=1;
    end;
    if str='_END__IMG_' then begin
      flag:=2;
      form1.Tag:=0;
    end;
  end;  case flag of
    0: begin
        form1.Caption:=Form1.Caption+'S_';
        MemRec:=TMemoryStream.Create;
        form1.Caption:=Form1.Caption+'S_';
      end;
    2: begin
        form1.Caption:=Form1.Caption+'_E';
        tmp:=TImage.Create(self);
        try
            MemRec.Position:=0;
            Form1.mmo1.Lines.Add(IntToStr(MemRec.Size)+ '  '+inttostr(MemOld.Size)) ;            MemOld.Position:=0;             //用MemOld可以正确地将需要的部分画到IMG2中
            tmp.Picture.Bitmap.LoadFromStream(MemOld);
            img2.Canvas.CopyRect(rect, tmp.Canvas, NewRect);//            MemRec.Position:=0;       //用MemRec 不能 需要的部分画到IMG2中
//            tmp.Picture.Bitmap.LoadFromStream(MemRec);
//            img2.Canvas.CopyRect(rect, tmp.Canvas, NewRect);            just:=CompareMem(MemRec.Memory,MemOld.Memory, MemOld.Size);                                       //但内存比较的结果是MemOld与MemRec的内容完全相同            if just then form1.mmo1.Lines.Add(IntToStr(1))
            else form1.mmo1.Lines.Add(IntToStr(0));
        finally
          tmp.Free;
          MemRec.Free;
        end;
        form1.img2.Canvas.MoveTo(0, 0);
        form1.img2.Canvas.LineTo(30, 30);
      end;
    1: if form1.tag=1 then begin
          MemRec.Write(Adata, size);
          form1.Caption:=Form1.Caption+' - '+inttostr(MemRec.Size);
      end;
  end;end;