急!急!急!请教高手(远程截屏)(135分)

  • 主题发起人 主题发起人 dddk
  • 开始时间 开始时间
D

dddk

Unregistered / Unconfirmed
GUEST, unregistred user!
急!急!急!请教高手
最近本人看了由 山东巨力股份有限公司CAD中心 檀革勤 编的一个用Delphi实现远程屏幕抓取的程序,然后在
自己的机子上也成功的编译了此程序,由于网络中讲究的是速度,截过来的图片是bmp格式,在网络中传送比较
慢,于是我研究了他的代码,并参考了其它的资料,自己编了一个远程全屏截取屏幕,从远程机传送过来的图
片格式为JPG。
客户端和服务端编译都通过了,可是在客户端一按按钮就出错,后来对客户端和服务端同时进行单步调试,发现服务端能正常工件,而在客户端一接收数据就出错。
以下是源程序,希望各位高手帮小弟一把。
客户端
unit client;
interface
uses
Windows,jpeg,Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
NMUDP, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
Button1: TButton;
Edit1: TEdit;
NMUDP1: TNMUDP;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const bufsize=2048;
var
rsltstream,tmpstream:Tmemorystream;
jpegpic:Tjpegimage;
procedure TForm1.FormCreate(Sender: TObject);
begin
jpegpic:=Tjpegimage.create;
rsltstream:=Tmemorystream.Create;
tmpstream:=Tmemorystream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
jpegpic.free;
rsltstream.Free;
tmpstream.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
reqcode:array [0..3] of char;
begin
strpcopy(reqcode,'show');
tmpstream.Clear;
rsltstream.Clear;
nmudp1.RemoteHost:=edit1.Text;
nmudp1.SendBuffer(reqcode,4);
end;

procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
var
reqcode:array[0..3]of char;
begin
strpcopy(reqcode,'show');
nmudp1.ReadStream(Tmpstream);
rsltstream.CopyFrom(Tmpstream,NumberBytes);
form1.Caption:='正在接收数据';
if NumberBytes<bufsize then
//数据已读完
begin
rsltstream.Position:=0;
jpegpic.LoadFromStream(rsltstream);
form1.caption:='显示图片';
image1.Picture.Graphic:=jpegpic;
tmpstream.Clear;
rsltstream.Clear;
end
else
tmpstream.Clear;
reqcode:='show';
nmudp1.RemoteHost:=edit1.text;
nmudp1.SendBuffer(reqcode,4);
end;

end.

服务端
unit server;
interface
uses
Windows, Messages,jpeg,SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
NMUDP;
type
TForm1 = class(TForm)
NMUDP1: TNMUDP;
procedure NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
jpegstream:Tmemorystream;
leftsize:integer;
bitmap:Tbitmap;
desktopcanvas:Tcanvas;
jpegpic:Tjpegimage;
implementation
{$R *.DFM}
const bufsize=2048;
procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer;
FromIP: String;
Port: Integer);
var
sendsize:integer;
ctrlcode:array[0..3] of char;
buf:array[0..bufsize-1] of char;
begin
nmudp1.ReadBuffer(ctrlcode,NumberBytes);
if ctrlcode='show' then
begin
if jpegstream.size=0 then
begin
desktopcanvas.handle:=getdc(hwnd_desktop);//得到桌面的句柄
bitmap.width:=screen.width;//得到桌面的宽度
bitmap.Height:=screen.Height;//得到桌面的长度
bitmap.canvas.copyrect(bitmap.canvas.cliprect,desktopcanvas,bitmap.canvas.cliprect);//截取桌面 的图片。
jpegpic.assign(bitmap);//存为jpg格式
jpegpic.SaveToStream(jpegstream);
jpegstream.Position:=0;
leftsize:=jpegstream.Size;
releasedc(handle,hwnd_desktop);
end;
if leftsize>bufsize then
sendsize:=bufsize
else
sendsize:=leftsize;
jpegstream.ReadBuffer(buf,sendsize);
leftsize:=leftsize-sendsize;
if leftsize=0 then
jpegstream.Clear;
nmudp1.RemoteHost:=fromip;
nmudp1.SendBuffer(buf,sendsize)
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
bitmap:=Tbitmap.create;
desktopcanvas:=TCanvas.create;
jpegpic:=Tjpegimage.create;
jpegstream:=Tmemorystream.create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
bitmap.free;
desktopcanvas.Free;
jpegpic.free;
jpegstream.free;
end;

end.
 
不知《版主答疑》那本书,可否帮你。
 
strpcopy(reqcode,'show');
很有问题,strpcopy除了copy “show”4个字符,
在后面还要加一个“0”结束字符串,实际写入5个字符。
strpcopy并不检查缓冲区长度,
你的reqcode仅有4个字符长度,因此,缓冲区溢出,
破坏了堆栈。
 
接受答案了.
 

Similar threads

后退
顶部