服务端 (截取屏幕) 客户端(显示屏幕)
 程序能够正常截屏 并传输  但是 传输过程中 如果在服务端窗口进行鼠标移动 或单击 即会触发异常错误:“存储空间不足,无法处理此类命令”  服务端代码如下:截屏幕类:
unit UnitTScreen;interfaceuses
   Windows, Classes, Graphics, Forms, jpeg;type
  TScreen = class
  private
    bmp: TBitmap;
    jpeg: TJpegimage;
    imgstm: TMemoryStream;
  public
    procedure ScreenMap(str: string);
    function GetImgstm: Tmemorystream;
    constructor Create; overload;
    destructor Destroy; override;
  end;implementation{ TScreen }constructor TScreen.Create;
begin
  bmp := TBitmap.Create;
  jpeg := Tjpegimage.Create;
  imgstm := TMemorystream.Create;end;destructor TScreen.Destroy;
begin
  bmp.Free;
  jpeg.Free;
  imgstm.Free;
  inherited;
end;function TScreen.GetImgstm: Tmemorystream;
begin
  result := imgstm;
end;procedure TScreen.ScreenMap(str: string);
var
  Cursorx, Cursory: integer;
  DC: hdc;
  Mycan: Tcanvas;
  R: TRect;
  DrawPos: TPoint;
  MyCursor: TIcon;
  hld: hwnd;
  Threadld: dword;
  mp: tpoint;
  pIconInfo: TIconInfo;
begin
  Mycan := TCanvas.Create; {屏幕截取}
  DC := GetWindowDC(0);
  try
    Mycan.Handle := dc;
    R := Rect(0, 0, Screen.Width, Screen.Height);
    bmp.Width := R.Right;
    bmp.Height := R.Bottom;
    bmp.Canvas.CopyRect(R, Mycan, R);
  finally
    releaseDC(0, DC);
    Mycan.Free;
  end;
  {画上鼠标图象}
  if str[2] = '1' then
  begin
    GetCursorPos(DrawPos);
    MyCursor := TIcon.Create;
    getcursorpos(mp);
    hld := WindowFromPoint(mp);
    Threadld := GetWindowThreadProcessId(hld, nil);
    AttachThreadInput(GetCurrentThreadId, Threadld, True);
    MyCursor.Handle := Getcursor();
    AttachThreadInput(GetCurrentThreadId, threadld, False);
    GetIconInfo(Mycursor.Handle, pIconInfo);
    cursorx := DrawPos.x - round(pIconInfo.xHotspot);
    cursory := DrawPos.y - round(pIconInfo.yHotspot);
    bmp.Canvas.Draw(cursorx, cursory, MyCursor); {画上鼠标}
    DeleteObject(pIconInfo.hbmColor);{GetIconInfo 使用时创建了两个bitmap对象. 需要手工释放这两个对象}
    DeleteObject(pIconInfo.hbmMask);{否则,调用他后,他会创建一个bitmap,多次调用会产生多个,直至资源耗尽}
    Mycursor.ReleaseHandle; {释放数组内存}
    MyCursor.Free; {释放鼠标指针}
  end;
  Application.ProcessMessages;
  {图象处理}
  if str[1] = '0' then
    bmp.PixelFormat := pf16Bit
  else if str[1] = '1' then
    bmp.PixelFormat := pf8Bit
  else if str[1] = '2' then
     bmp.PixelFormat := pf4Bit;
  {压缩成JPG}
  Application.ProcessMessages;
  jpeg.Assign(bmp);
  bmp.FreeImage;
  imgstm.Clear;
  jpeg.SaveToStream(imgstm);
end;end.传输线程:
unit UnitTServerThread;interfaceuses
  ScktComp, SysUtils, UnitConst, Classes, UnitTScreen;type
  TServerThread = class(TServerClientThread)
  private
    ProcessID: Cardinal;  //结束进程ID
    stm: TMemorystream;
    scn: Tscreen;
    { Private declarations }
  protected
    {TServerClientThread的执行过程,相当于普通现成的Thread.Execute}
    procedure ClientExecute; override;
  public
    {重载构造函数}
    constructor Create(CreateSuspended: Boolean;
      Asocket: TServerClientWinSocket);overload;
    destructor Destroy; override;
  end;implementation
uses
  unitmain;
{ TServerThread }procedure TServerThread.ClientExecute;
var
  Len,  //收到的数据长度
  Order: integer;    //指令
  DataSize,          //发送的数据大小
  SendSize: integer; //已发送数据大小
  SendBuffer: pchar;  //发送缓冲
  Pstream: TWinsocketStream;
  Buffer: pointer; //接收数据缓冲区
  Revstr: string;  //接收的数据
const
  BufferSize = 1024;
  SendBufferSize = 4096;
begin
  try
    Pstream := TWinsocketStream.Create(ClientSocket,60000);
    ClientSocket.SendText(inttostr(XF_IAMREADY));
    while (not Terminated) and ClientSocket.Connected do
    if Pstream.WaitForData(6000)  then       {等待数据到来 }
      begin
        try
        Buffer := AllocMem(BufferSize+1);
        len := PStream.Read(Buffer^, BufferSize);
        if Len = 0 then
        begin
          sleep(5);
          continue;
        end;
        Revstr := Pchar(buffer);
        setlength(Revstr,len);//frmmain.mmo.Lines.Add('thread rev msg:'+copy(Revstr,1,len));
        if not trystrtoint(copy(Revstr,1,4), Order) then
        begin
          sleep(5);
          continue;
        end;
        case Order of
        XF_TERMINATE:
            begin
              ClientSocket.Close;
              Terminate;
            end;
        XF_SCREENSTART:
            begin
              scn := TScreen.Create;
              Clientsocket.SendText(inttostr(XF_SCREENREADY));
            end;
        XF_GETIMGSIZE:
            begin
              scn.ScreenMap(copy(Revstr,5,6));
              stm := scn.GetImgstm;
              Datasize := stm.Size;
              Clientsocket.SendText(inttostr(XF_IMGSIZEINFO)+inttostr(Datasize));
              SendSize := 0;
            end;
        XF_SENDIMGDATA:
            begin
              SendBuffer := AllocMem(SendBufferSize+4);
              stm.Position := SendSize;
              if (SendSize + SendBufferSize) < Datasize then
              begin
                stm.ReadBuffer(SendBuffer[4],SendBufferSize);
                move(pchar(inttostr(XF_IMGDATAINFO))^,SendBuffer^,4);
                pstream.WriteBuffer(SendBuffer[0],SendBufferSize+4);
                SendSize := SendSize + SendBufferSize;
              end
              else begin     {最后一个包}
                stm.ReadBuffer(SendBuffer[4],Datasize-SendSize);
                move(pchar(inttostr(XF_IMGDATAINFO))^,SendBuffer^,4);
                pstream.WriteBuffer(SendBuffer[0],Datasize-SendSize+4);
                SendSize := Datasize;
              end;
              FreeMem(SendBuffer);
            end;          
        end;
        finally
          FreeMem(Buffer);
          Sleep(5);
        end;
      end;
  finally 
    Pstream.Free;
  end;
end;constructor TServerThread.Create(CreateSuspended: Boolean;
  Asocket: TServerClientWinSocket);
begin
  inherited create(CreateSuspended,Asocket);
  stm := TMemorystream.Create;
end;destructor TServerThread.Destroy;
begin
  if assigned(scn) and (scn <> nil) then
    scn.Free;
  inherited;
end;end.常量定义:
  XF_IAMREADY     = 2000;    //连接就续消息
  XF_TERMINATE    = 2001;    //线程结束指令
  XF_SCREENSTART  = 3000;    //开始发送图象指令
  XF_SCREENREADY  = 3001;    //准备好信息
  XF_GETIMGSIZE   = 3002;    //获取图象大小指令
  XF_IMGSIZEINFO  = 3003;    //图象大小信息
  XF_SENDIMGDATA  = 3004;    //发送图片数据指令
  XF_IMGDATAINFO  = 3005;    //图片数据信息 

解决方案 »

  1.   

    没人么 在线等啊 哎 困扰了好几天了 CSDN救我啊
      

  2.   

    csdn 高手何在啊  顶顶
      

  3.   

    用try捕捉一下,不然写个简单的日志跟踪一下你点击或者移动鼠标是在那里出错,这样比较好处理,code有点长又不能调试,看不清除。
      

  4.   

    bmp.Canvas.CopyRect(R, Mycan, R);  出错在这句 不知道为何
      

  5.   


    VC++.delphi
    VB C# .NET远程屏幕监视
    局域网屏幕监视
    局域网桌面监视
    屏幕监控
    屏幕抓取
    屏幕传输
    屏幕截图
    QQ交流群:33367148