国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
大富翁論壇-富翁筆記-請教MemoryStream的使用方法 (DEMO)



http://www.delphibbs.com/keylife/iblog_show.asp?xid=23218
作者: walimg
標題: 請教MemoryStream的使用方法 (DEMO)
關鍵字:
分類: 個人專區(qū)
密級: 公開
(評分: , 回復: 0, 閱讀: 39) »»
來自: ranjiao, 時間: 2005-08-15 18:45:00, ID: 3167898  
我想用MemoryStream反復讀取文件操作,但是我調(diào)用clear和free想清除內(nèi)存的時候都會報錯。。。
應該怎么弄?
 
來自: chenybin, 時間: 2005-08-15 20:24:58, ID: 3167929  
先看看你的代碼

http://www.delphibbs.com/delphibbs/modifyl.asp?lid=1474545

談Delphi編程中“流”的應用

                                                  陳經(jīng)韜
什么是流?流,簡單來說就是建立在面向?qū)ο蠡A上的一種抽象的處理數(shù)據(jù)的工具。在流中,定義了一些處理數(shù)據(jù)的基本操作,如讀取數(shù)據(jù),寫入數(shù)據(jù)等,程序員是對流進行所有操作的,而不用關心流的另一頭數(shù)據(jù)的真正流向。流不但可以處理文件,還可以處理動態(tài)內(nèi)存、網(wǎng)絡數(shù)據(jù)等多種數(shù)據(jù)形式。如果你對流的操作非常熟練,在程序中利用流的方便性,寫起程序會大大提高效率的。
 下面,筆者通過四個實例:EXE文件加密器、電子賀卡、自制OICQ和網(wǎng)絡屏幕傳輸來說明Delphi編程中“流”的利用。這些例子中的一些技巧曾經(jīng)是很多軟件的秘密而不公開的,現(xiàn)在大家可以無償?shù)闹苯右闷渲械拇a了。
 “萬丈高樓平地起”,在分析實例之前,我們先來了解一下流的基本概念和函數(shù),只有在理解了這些基本的東西后我們才能進行下一步。請務必認真領會這些基本方法。當然,如果你對它們已經(jīng)很熟悉了,則可以跳過這一步。

一、Delphi中流的基本概念及函數(shù)聲明
在Delphi中,所有流對象的基類為TStream類,其中定義了所有流的共同屬性和方法。
TStream類中定義的屬性介紹如下:
1、Size:此屬性以字節(jié)返回流中數(shù)據(jù)大小。
2、Position:此屬性控制流中存取指針的位置。
Tstream中定義的虛方法有四個:
1、Read:此方法實現(xiàn)將數(shù)據(jù)從流中讀出。函數(shù)原形為:
Function Read(var Buffer;Count:Longint):Longint;virtual;abstract;
參數(shù)Buffer為數(shù)據(jù)讀出時放置的緩沖區(qū),Count為需要讀出的數(shù)據(jù)的字節(jié)數(shù),該方法返回值為實際讀出的字節(jié)數(shù),它可以小于或等于Count中指定的值。
2、Write:此方法實現(xiàn)將數(shù)據(jù)寫入流中。函數(shù)原形為:
Function Write(var Buffer;Count:Longint):Longint;virtual;abstract;
參數(shù)Buffer為將要寫入流中的數(shù)據(jù)的緩沖區(qū),Count為數(shù)據(jù)的長度字節(jié)數(shù),該方法返回值為實際寫入流中的字節(jié)數(shù)。
3、Seek:此方法實現(xiàn)流中讀取指針的移動。函數(shù)原形為:
Function Seek(Offset:Longint;Origint:Word):Longint;virtual;abstract;
參數(shù)Offset為偏移字節(jié)數(shù),參數(shù)Origint指出Offset的實際意義,其可能的取值如下:
soFromBeginning:Offset為移動后指針距離數(shù)據(jù)開始的位置。此時Offset必須大于或者等于零。
soFromCurrent:Offset為移動后指針與當前指針的相對位置。
soFromEnd:Offset為移動后指針距離數(shù)據(jù)結束的位置。此時Offset必須小于或者等于零。該方法返回值為移動后指針的位置。
4、Setsize:此方法實現(xiàn)改變數(shù)據(jù)的大小。函數(shù)原形為:
Function Setsize(NewSize:Longint);virtual;
另外,TStream類中還定義了幾個靜態(tài)方法:
1、ReadBuffer:此方法的作用是從流中當前位置讀取數(shù)據(jù)。函數(shù)原形為:
Procedure ReadBuffer(var Buffer;Count:Longint);
參數(shù)的定義跟上面的Read相同。注意:當讀取的數(shù)據(jù)字節(jié)數(shù)與需要讀取的字節(jié)數(shù)不相同時,將產(chǎn)生EReadError異常。
2、WriteBuffer:此方法的作用是在當前位置向流寫入數(shù)據(jù)。函數(shù)原形為:
Procedure WriteBuffer(var Buffer;Count:Longint);
參數(shù)的定義跟上面的Write相同。注意:當寫入的數(shù)據(jù)字節(jié)數(shù)與需要寫入的字節(jié)數(shù)不相同時,將產(chǎn)生EWriteError異常。
3、CopyFrom:此方法的作用是從其它流中拷貝數(shù)據(jù)流。函數(shù)原形為:
Function CopyFrom(Source:TStream;Count:Longint):Longint;
參數(shù)Source為提供數(shù)據(jù)的流,Count為拷貝的數(shù)據(jù)字節(jié)數(shù)。當Count大于0時,CopyFrom從Source參數(shù)的當前位置拷貝Count個字節(jié)的數(shù)據(jù);當Count等于0時,CopyFrom設置Source參數(shù)的Position屬性為0,然后拷貝Source的所有數(shù)據(jù);
TStream還有其它派生類,其中最常用的是TFileStream類。使用TFileStream類來存取文件,首先要建立一個實例。聲明如下:
constructor Create(const Filename:string;Mode:Word);
Filename為文件名(包括路徑),參數(shù)Mode為打開文件的方式,它包括文件的打開模式和共享模式,其可能的取值和意義如下:

打開模式:
fmCreate :用指定的文件名建立文件,如果文件已經(jīng)存在則打開它。
fmOpenRead :以只讀方式打開指定文件
fmOpenWrite :以只寫方式打開指定文件
fmOpenReadWrite:以寫寫方式打開指定文件
共享模式:
fmShareCompat :共享模式與FCBs兼容
fmShareExclusive:不允許別的程序以任何方式打開該文件
fmShareDenyWrite:不允許別的程序以寫方式打開該文件
fmShareDenyRead :不允許別的程序以讀方式打開該文件
fmShareDenyNone :別的程序可以以任何方式打開該文件

TStream還有一個派生類TMemoryStream,實際應用中用的次數(shù)也非常頻繁。它叫內(nèi)存流,就是說在內(nèi)存中建立一個流對象。它的基本方法和函數(shù)跟上面是一樣的。
好了,有了上面的基礎后,我們就可以開始我們的編程之行了。
-----------------------------------------------------------------------
二、實際應用之一:利用流制作EXE文件加密器、捆綁、自解壓文件及安裝程序

 我們先來說一下如何制作一個EXE文件加密器吧。
 EXE文件加密器的原理:建立兩個文件,一個用來添加資源到另外一個EXE文件里面,稱為添加程序。另外一個被添加的EXE文件稱為頭文件。該程序的功能是把添加到自己里面的文件讀出來。Windows下的EXE文件結構比較復雜,有的程序還有校驗和,當發(fā)現(xiàn)自己被改變后會認為自己被病毒感染而拒絕執(zhí)行。所以我們把文件添加到自己的程序里面,這樣就不會改變原來的文件結構了。我們先寫一個添加函數(shù),該函數(shù)的功能是把一個文件當作一個流添加到另外一個文件的尾部。函數(shù)如下:

Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;
var
Target,Source:TFileStream;
MyFileSize:integer;
begin
try
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);
Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);
try
Target.Seek(0,soFromEnd);//往尾部添加資源
Target.CopyFrom(Source,0);
MyFileSize:=Source.Size+Sizeof(MyFileSize);//計算資源大小,并寫入輔程尾部
Target.WriteBuffer(MyFileSize,sizeof(MyFileSize));
finally
Target.Free;
Source.Free;
end;
except
Result:=False;
Exit;
end;
Result:=True;
end;
有了上面的基礎,我們應該很容易看得懂這個函數(shù)。其中參數(shù)SourceFile是要添加的文件,參數(shù)TargetFile是被添加到的目標文件。比如說把a.exe添加到b.exe里面可以:Cjt_AddtoFile('a.exe',b.exe');如果添加成功就返回True否則返回假。
根據(jù)上面的函數(shù)我們可以寫出相反的讀出函數(shù):
Function Cjt_LoadFromFile(SourceFile,TargetFile :string):Boolean;
var
Source:TFileStream;
Target:TMemoryStream;
MyFileSize:integer;
begin
try
Target:=TMemoryStream.Create;
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
try
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//讀出資源大小
Source.Seek(-MyFileSize,soFromEnd);//定位到資源位置
Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出資源
Target.SaveToFile(TargetFile);//存放到文件
finally
Target.Free;
Source.Free;
end;
except
Result:=false;
Exit;
end;
Result:=true;
end;
 其中參數(shù)SourceFile是已經(jīng)添加了文件的文件名稱,參數(shù)TargetFile是取出文件后保存的目標文件名。比如說Cjt_LoadFromFile('b.exe','a.txt');在b.exe中取出文件保存為a.txt。如果取出成功就返回True否則返回假。
打開Delphi,新建一個工程,在窗口上放上一個Edit控件Edit1和兩個Button:Button1和Button2。Button的Caption屬性分別設置為“確定”和“取消”。在Button1的Click事件中寫代碼:
var S:string;
begin
S:=ChangeFileExt(Application.ExeName,'.Cjt');
if Edit1.Text='790617' then
begin
Cjt_LoadFromFile(Application.ExeName,S);
{取出文件保存在當前路徑下并命名"原文件.Cjt"}
Winexec(pchar(S),SW_Show);{運行"原文件.Cjt"}
Application.Terminate;{退出程序}
end
else
Application.MessageBox('密碼不對,請重新輸入!','密碼錯誤',MB_ICONERROR+MB_OK);
 編譯這個程序,并把EXE文件改名為head.exe。新建一個文本文件head.rc,內(nèi)容為: head exefile head.exe,然后把它們拷貝到Delphi的BIN目錄下,執(zhí)行Dos命令Brcc32.exe head.rc,將產(chǎn)生一個head.res的文件,這個文件就是我們要的資源文件,先留著。
 我們的頭文件已經(jīng)建立了,下面我們來建立添加程序。
 新建一個工程,放上以下控件:一個Edit,一個Opendialog,兩個Button1的Caption屬性分別設置為"選擇文件"和"加密"。在源程序中添加一句:{$R head.res}并把head.res文件拷貝到程序當前目錄下。這樣一來就把剛才的head.exe跟程序一起編譯了。
 在Button1的Cilck事件里面寫下代碼:
if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;
 在Button2的Cilck事件里面寫下代碼:
var S:String;
begin
S:=ExtractFilePath(Edit1.Text);
if ExtractRes('exefile','head',S+'head.exe') then
if Cjt_AddtoFile(Edit1.Text,S+'head.exe') then
if DeleteFile(Edit1.Text) then
if RenameFile(S+'head.exe',Edit1.Text) then
Application.MessageBox('文件加密成功!','信息',MB_ICONINFORMATION+MB_OK)
else
begin
if FileExists(S+'head.exe') then DeleteFile(S+'head.exe');
Application.MessageBox('文件加密失敗!','信息',MB_ICONINFORMATION+MB_OK)
end;
end;
其中ExtractRes為自定義函數(shù),它的作用是把head.exe從資源文件中取出來。
Function ExtractRes(ResType, ResName, ResNewName : String):boolean;
var
Res : TResourceStream;
begin
try
Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
try
Res.SavetoFile(ResNewName);
Result:=true;
finally
Res.Free;
end;
except
Result:=false;
end;
end;
  注意:我們上面的函數(shù)只不過是簡單的把一個文件添加到另一個文件的尾部。實際應用中可以改成可以添加多個文件,只要根據(jù)實際大小和個數(shù)定義好偏移地址就可以了。比如說文件捆綁機就是把兩個或者多個程序添加到一個頭文件里面。那些自解壓程序和安裝程序的原理也是一樣的,不過多了壓縮而已。比如說我們可以引用一個LAH單元,把流壓縮后再添加,這樣文件就會變的很小。讀出來時先解壓就可以了。另外,文中EXE加密器的例子還有很多不完善的地方,比如說密碼固定為"790617",取出EXE運行后應該等它運行完畢后刪除等等,讀者可以自行修改。

---------------------------------------------------------------------
三、實際應用之二:利用流制作可執(zhí)行電子賀卡

 我們經(jīng)常看到一些電子賀卡之類的制作軟件,可以讓你自己選擇圖片,然后它會生成一個EXE可執(zhí)行文件給你。打開賀卡時就會一邊放音樂一邊顯示出圖片來。現(xiàn)在學了流操作之后,我們也可以做一個了。
 添加圖片過程我們可以直接用前面的Cjt_AddtoFile,而現(xiàn)在要做的是如何把圖像讀出并顯示。我們用前面的Cjt_LoadFromFile先把圖片讀出來保存為文件再調(diào)入也是可以的,但是還有更簡單的方法,就是直接把文件流讀出來顯示,有了流這個利器,一切都變的簡單了。
 現(xiàn)在的圖片比較流行的是BMP格式和JPG格式。我們現(xiàn)在就針對這兩種圖片寫出讀取并顯示函數(shù)。

Function Cjt_BmpLoad(ImgBmp:TImage;SourceFile:String):Boolean;
var
Source:TFileStream;
MyFileSize:integer;
begin
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
try
try
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//讀出資源
Source.Seek(-MyFileSize,soFromEnd);//定位到資源開始位置
ImgBmp.Picture.Bitmap.LoadFromStream(Source);
finally
Source.Free;
end;
except
Result:=False;
Exit;
end;
Result:=True;
end;
 上面是讀出BMP圖片的,下面的是讀出JPG圖片的函數(shù),因為要用到JPG單元,所以要在程序中添加一句:uses jpeg。

Function Cjt_JpgLoad(JpgImg:Timage;SourceFile:String):Boolean;
var
Source:TFileStream;
MyFileSize:integer;
Myjpg: TJpegImage;
begin
try
Myjpg:= TJpegImage.Create;
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
try
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));
Source.Seek(-MyFileSize,soFromEnd);
Myjpg.LoadFromStream(Source);
JpgImg.Picture.Bitmap.Assign(Myjpg);
finally
Source.Free;
Myjpg.free;
end;
except
Result:=false;
Exit;
end;
Result:=true;
end;
 有了這兩個函數(shù),我們就可以制作讀出程序了。下面我們以BMP圖片為例:
 運行Delphi,新建一個工程,放上一個顯示圖像控件Image1。在窗口的Create事件中寫上一句就可以了:
Cjt_BmpLoad(Image1,Application.ExeName);
 這個就是頭文件了,然后我們用前面的方法生成一個head.res資源文件。
下面就可以開始制作我們的添加程序了。全部代碼如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, ExtDlgs;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
OpenPictureDialog1: TOpenPictureDialog;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
Function ExtractRes(ResType, ResName, ResNewName : String):boolean;
Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
Function TForm1.ExtractRes(ResType, ResName, ResNewName : String):boolean;
var
Res : TResourceStream;
begin
try
Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
try
Res.SavetoFile(ResNewName);
Result:=true;
finally
Res.Free;
end;
except
Result:=false;
end;
end;
Function TForm1.Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;
var
Target,Source:TFileStream;
MyFileSize:integer;
begin
try
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);
Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);
try
Target.Seek(0,soFromEnd);//往尾部添加資源
Target.CopyFrom(Source,0);
MyFileSize:=Source.Size+Sizeof(MyFileSize);//計算資源大小,并寫入輔程尾部
Target.WriteBuffer(MyFileSize,sizeof(MyFileSize));
finally
Target.Free;
Source.Free;
end;
except
Result:=False;
Exit;
end;
Result:=True;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption:='Bmp2Exe演示程序.作者:陳經(jīng)韜';
Edit1.Text:='';
OpenPictureDialog1.DefaultExt := GraphicExtension(TBitmap);
OpenPictureDialog1.Filter := GraphicFilter(TBitmap);

Button1.Caption:='選擇BMP圖片';
Button2.Caption:='生成EXE';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenPictureDialog1.Execute then
Edit1.Text:=OpenPictureDialog1.FileName;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
HeadTemp:String;
begin
if Not FileExists(Edit1.Text) then
begin
Application.MessageBox('BMP圖片文件不存在,請重新選擇!','信息',MB_ICONINFORMATION+MB_OK)
Exit;
end;
HeadTemp:=ChangeFileExt(Edit1.Text,'.exe');
if ExtractRes('exefile','head',HeadTemp) then
if Cjt_AddtoFile(Edit1.Text,HeadTemp) then
Application.MessageBox('EXE文件生成成功!','信息',MB_ICONINFORMATION+MB_OK)
else
begin
if FileExists(HeadTemp) then DeleteFile(HeadTemp);
Application.MessageBox('EXE文件生成失敗!','信息',MB_ICONINFORMATION+MB_OK)
end;
end;
end.
 怎么樣?很神奇吧:)把程序界面弄的漂亮點,再添加一些功能,你會發(fā)現(xiàn)比起那些要注冊的軟件來也不會遜多少吧。
 
來自: ranjiao, 時間: 2005-08-15 19:41:40, ID: 3167931  
free一調(diào)用就會出錯
 
來自: chenybin, 時間: 2005-08-15 20:24:37, ID: 3167954  
把你的代碼貼出來看看
 
來自: ranjiao, 時間: 2005-08-15 21:03:52, ID: 3168004  
begin//download     <<===BUG!!!
 MemoryStream.Position:=0;
 loadfile(list.data[0],MemoryStream,msize);
 memo1.Lines.add('file loaded.');
 socket.SendText(inttostr(msize));
end;
我在遠程控制,其中涉及到的就是這幾行代碼了,下面是整個代碼,有點多
unit server;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ScktComp, StdCtrls, ExtCtrls, Jpeg, unitserver;

type
 TServerForm = class(TForm)
   ServerSocket1: TServerSocket;
   BtnListen: TButton;
   Memo1: TMemo;
   BtnExit: TButton;
   EdtSend: TEdit;
   BtnSend: TButton;
   Timer1: TTimer;
   CbControl: TCheckBox;
   Image: TImage;
   BtnClear: TButton;
   procedure BtnClearClick(Sender: TObject);
   procedure Button1Click(Sender: TObject);
   procedure EdtSendKeyPress(Sender: TObject; var Key: Char);
   procedure ServerSocket1ClientError(Sender: TObject;
     Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
     var ErrorCode: Integer);
   procedure CbControlClick(Sender: TObject);
   procedure ServerSocket1ClientDisconnect(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure Timer1Timer(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure ServerSocket1ClientRead(Sender: TObject;
     Socket: TCustomWinSocket);
   procedure BtnSendClick(Sender: TObject);
   procedure ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
   procedure BtnListenClick(Sender: TObject);
   procedure BtnExitClick(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 ServerForm: TServerForm;
 control,shaking:boolean;
 memoryStream:TMemoryStream;
 size:longint;
 Receiving:integer;
 filepath:string;
implementation

{$R *.dfm}

procedure capture;
var
 BitMap:TBitMap;
 jpg:TJpegImage;
 desk:TCanvas;

begin
 bitmap:=tbitmap.Create;
 jpg:=tjpegimage.Create;
 desk:=tcanvas.Create; //以下代碼為取得當前屏幕圖象
 desk.Handle:=getdc(hwnd_desktop);
 MemoryStream:=tmemorystream.Create; //初始化流m1,在用sendstream(m1)發(fā)送流后,
 with bitmap do
 begin
   width:=screen.Width;
   height:=screen.Height;
   jpg.CompressionQuality:=50; {壓縮質(zhì)量}
   jpg.Compress;
   canvas.CopyRect(canvas.cliprect,desk,desk.cliprect);
 end;
 jpg.Assign(bitmap); //將圖象轉(zhuǎn)成JPG格式
 jpg.SaveToStream(MemoryStream); //將JPG圖象寫入流中
 jpg.free;
 MemoryStream.Position:=0;
end;    

procedure TServerForm.BtnExitClick(Sender: TObject);
begin
 close;
end;

procedure TServerForm.BtnListenClick(Sender: TObject);
begin
 ServerSocket1.active:=NOT ServerSocket1.active;
 if not ServerSocket1.Active then
 begin
    BtnListen.Caption:='Listen';
    memo1.Lines.add('Listen ended.');
 end
 else
 begin
    BtnListen.Caption:='End Listen';
    memo1.Lines.add('Listening...');
 end;
end;

procedure TServerForm.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
begin
 memo1.Lines.Add('Client from '+ServerSocket1.Socket.Connections[0].RemoteAddress+' connected.');
end;

procedure TServerForm.BtnSendClick(Sender: TObject);
begin
 if not ServerSocket1.Socket.Connected then exit;
 ServerSocket1.Socket.Connections[0].SendText(EdtSend.Text);
 memo1.Lines.add('Server :'+EdtSend.text);
end;



procedure TServerForm.ServerSocket1ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
 msize,iscmd:integer;
 cmd,temp:string;

//delcaration of cmdlist
//  maxcount=10;
//  CMDList:array[0..maxcount-1] of string=
//  ('#CLogOff',
//   '#CPowerOff',
//   '#CReboot',
//   '#CShakeMouse',
//   '#CCapture',
//   '#CSendStream',
//   '#CListDrive',
//   '#CListFile',
//   '#CDownload',
//   '#CUpload',
//   '#CExit');

procedure ReceiveStream;
var
 len:integer;
 buffer:array [0..10000] of byte;
begin
 if size=0 then
 begin
   size:=strtoint(Socket.ReceiveText);
   Socket.SendText('#CSendStream'); //ask client to send the stream
 end
 else
 begin
   len:=socket.ReceiveLength; //讀出包長度
   socket.ReceiveBuf(buffer,len); //接收數(shù)據(jù)包并讀入緩沖區(qū)內(nèi)
   memorystream.Write(buffer,len); //追加入流M中
 end;
end;

begin
 if Receiving<>0 then
//  Receiving is the Flag of what socket is going to receive
// 1:Stream of file that client is iploading
 case Receiving of
 1:begin//receive stream
     ReceiveStream;
     if MemoryStream.Size>=size then
     begin
       MemoryStream.SaveToFile(list.data[0]);
       Receiving:=0;
     end;
   end;
 end
 else
 begin
   temp:=Socket.ReceiveText;
   memo1.Lines.Add('Client: '+temp);
   iscmd:=DealWithCMD(temp);
   //check if the message recevied is a command
   //and save the var in list.
   if iscmd<>0 then
   begin
    if control then
     begin
       case iscmd of
       1:begin//log off       //<<=====DEBUGED======>>
           ExitWindowsEx(EWX_Logoff,0);
         end;
       2:begin//Power Off     //<<=====DEBUGED======>>
           ExitWindowsEx(EWX_PowerOff,0);
         end;
       3:begin//Reboot       //<<=====DEBUGED======>>
          ExitWindowsEx(EWX_Reboot,0);
         end;
       4:begin//Shake Mouse   //<<=====DEBUGED======>>
         shaking:=not shaking;
         Timer1.Enabled:=true;
         if shaking then
           memo1.Lines.Add('Your mouse is going mad.')
         else
           memo1.Lines.Add('What''s wrong with your mouse?');
         end;
       5:begin//Capture the Screen<<=====DEBUGED======>>
           capture; //capture the screen and compress it into jpeg
                    //and then save it to MemoryStream
           cmd:=inttostr(MemoryStream.Size);
           socket.SendText(cmd);
         end;
       6:begin//Transport the Stream<<=====DEBUGED======>>
           MemoryStream.Position:=0;
           socket.SendStream(MemoryStream);
         end;
       7:begin//List the drives.<<=====DEBUGED======>>
           ListDrive(cmd);
           socket.SendText(cmd);
         end;
       8:begin//List the files and dirs<<=====DEBUGED======>>
           listFile(list.data[0],'*.*',cmd);
           socket.SendText(cmd);
           init;
         end;
       9:begin//download     <<===BUG!!!
           MemoryStream.Position:=0;
           loadfile(list.data[0],MemoryStream,msize);
           memo1.Lines.add('file loaded.');
           socket.SendText(inttostr(msize));
         end;
       10:begin  //upload
    //        filepath:=list.data[0];
    //        socket.SendText('#CSendStream');
    //        receiving:=1;
          end;
       11:begin
            Application.Terminate;
          end;
       12:begin
            ServerForm.Show;
          end;
       end;//case
    end //eof if control
    else
       socket.SendText('#Server is not controlable.');
   end//eof if iscmd  }
   else
   begin
   //    memo1.Lines.Add('Client: '+temp);
   end;
 end;//eof else receiving
end;

procedure TServerForm.FormCreate(Sender: TObject);
begin
 BtnListen.Click;
 shaking:=false;
 control:=true;
 MemoryStream:=TMemoryStream.Create;
 Receiving:=0;
 size:=0;
 init;//procedure in unit1;
end;

procedure TServerForm.Timer1Timer(Sender: TObject);
const                                 //This procedure change the pos of mouse
 maxn=100;                           //and it make mouse like shaking...
var
 pos:TPoint;
//  x,y:integer;
begin
 if shaking then
 begin
   GetCursorPos(pos);
   randomize;
   pos.X:=pos.X+random(maxn)-(maxn div 2);
   pos.Y:=pos.y+random(maxn)-(maxn div 2);
   SetCursorPos(pos.x,pos.y);
 end
 else
   Timer1.enabled:=false;
end;

procedure TServerForm.ServerSocket1ClientDisconnect(Sender: TObject;
 Socket: TCustomWinSocket);
begin
 memo1.Lines.Add('Client disconected.')
end;

procedure TServerForm.CbControlClick(Sender: TObject);
begin
 if CBControl.Checked then
 begin
   control:=true;
   memo1.Lines.Add('You are able to be controled by client now.')
 end
 else
 begin
   control:=false;
   memo1.lines.add('You are not able to be controled by client now.');
 end;
end;

procedure TServerForm.ServerSocket1ClientError(Sender: TObject;
 Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
 showmessage(ServerSocket1.Socket.Connections[0].RemoteHost+#13#10+'未開機或未安裝服務程序');
 errorcode:=0;
 MemoryStream.Clear;
 receiving:=0;
end;

procedure TServerForm.EdtSendKeyPress(Sender: TObject; var Key: Char);
begin
 if key=#13 then
 begin
   BtnSend.Click;
   EdtSend.Clear;
 end;
end;

procedure TServerForm.Button1Click(Sender: TObject);
begin
 capture;
end;

procedure TServerForm.BtnClearClick(Sender: TObject);
begin
 memo1.Clear;
end;

end.
 
來自: chenybin, 時間: 2005-08-15 21:16:47, ID: 3168018  
TMemoryStream.truncate
或者
TMemoryStream.SetSize(0);看看,明天幫你調(diào)試
 
來自: ranjiao, 時間: 2005-08-15 21:33:39, ID: 3168035  
多謝了樓上的~

剛開始用delphibbs 怎么追加分數(shù)?
 
來自: chenybin, 時間: 2005-08-15 21:36:24, ID: 3168038  
不用追加,追加要重新開帖子,如果答案能滿足你結貼就可以了,記得發(fā)分數(shù)給偶,細細[:D][:D][:D]
 
來自: ranjiao, 時間: 2005-08-19 9:39:08, ID: 3172471  
還是不行啊 MemoryStream沒有truncate 而我用setsize的話并沒有真正清內(nèi)存,還是會出錯
 
來自: chenybin, 時間: 2005-08-20 2:58:49, ID: 3173788  
方便的話留個聯(lián)系方式,把代碼發(fā)給我,我?guī)湍阏{(diào)
 
來自: ranjiao, 時間: 2005-08-22 22:53:12, ID: 3176438  
我的郵箱是ranjiao@gmail.com
這兩天快開學了,可能回的會比較慢
 


本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
WebBrowser顯示字符串內(nèi)容后如何保存的問題
創(chuàng)建異形窗口[5]
Cookies 修改
在DBGrid中進展拖放操作
DELPHI中鼠標的各種操作
通用程序自動更新升級
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服