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 這兩天快開學了,可能回的會比較慢 |