




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、delphi 高級實例什么是流?流,簡單來說就是建立在面向對象基礎上的一種抽象的處理數據的工具。在流中,定義了一些處理數據的基本操作,如讀取數據,寫入數據等,程序員是對流進行所有操作的,而不用關心流的另一頭數據的真正流向。流不但可以處理文件,還可以處理動態內存、網絡數據等多種數據形式。如果你對流的操作非常熟練,在程序中利用流的方便性,寫起程序會大大提高效率的。下面,筆者通過四個實例:EXE文件加密器、電子賀卡、自制OICQ和網絡屏幕傳輸來說明Delphi編程中“流”的利用。這些例子中的一些技巧曾經是很多軟件的秘密而不公開的,現在大家可以無償的直接引用其中的代碼了。“萬丈高樓平地起”,在分析實例
2、之前,我們先來了解一下流的基本概念和函數,只有在理解了這些基本的東西后我們才能進行下一步。請務必認真領會這些基本方法。當然,如果你對它們已經很熟悉了,則可以跳過這一步。一、Delphi中流的基本概念及函數聲明在Delphi中,所有流對象的基類為TStream類,其中定義了所有流的共同屬性和方法。TStream類中定義的屬性介紹如下:1、Size:此屬性以字節返回流中數據大小。2、Position:此屬性控制流中存取指針的位置。Tstream中定義的虛方法有四個:1、Read:此方法實現將數據從流中讀出。函數原形為:FunctionRead(varBuffer;Count:Longint):Lo
3、ngint;virtual;abstract;參數Buffer為數據讀出時放置的緩沖區,Count為需要讀出的數據的字節數,該方法返回值為實際讀出的字節數,它可以小于或等于Count中指定的值。2、Write:此方法實現將數據寫入流中。函數原形為:FunctionWrite(varBuffer;Count:Longint):Longint;virtual;abstract;參數Buffer為將要寫入流中的數據的緩沖區,Count為數據的長度字節數,該方法返回值為實際寫入流中的字節數。3、Seek:此方法實現流中讀取指針的移動。函數原形為:FunctionSeek(Offset:Longint;
4、Origint:Word):Longint;virtual;abstract;參數Offset為偏移字節數,參數Origint指出Offset的實際意義,其可能的取值如下:soFromBeginning:Offset為移動后指針距離數據開始的位置。此時Offset必須大于或者等于零。soFromCurrent:Offset為移動后指針與當前指針的相對位置。soFromEnd:Offset為移動后指針距離數據結束的位置。此時Offset必須小于或者等于零。該方法返回值為移動后指針的位置。4、Setsize:此方法實現改變數據的大小。函數原形為:FunctionSetsize(NewSize:Lo
5、ngint);virtual;另外,TStream類中還定義了幾個靜態方法:1、ReadBuffer:此方法的作用是從流中當前位置讀取數據。函數原形為:ProcedureReadBuffer(varBuffer;Count:Longint);參數的定義跟上面的Read相同。注意:當讀取的數據字節數與需要讀取的字節數不相同時,將產生EReadError異常。2、WriteBuffer:此方法的作用是在當前位置向流寫入數據。函數原形為:ProcedureWriteBuffer(varBuffer;Count:Longint);參數的定義跟上面的Write相同。注意:當寫入的數據字節數與需要寫入的字
6、節數不相同時,將產生EWriteError異常。3、CopyFrom:此方法的作用是從其它流中拷貝數據流。函數原形為:FunctionCopyFrom(Source:TStream;Count:Longint):Longint;參數Source為提供數據的流,Count為拷貝的數據字節數。當Count大于0時,CopyFrom從Source參數的當前位置拷貝Count個字節的數據;當Count等于0時,CopyFrom設置Source參數的Position屬性為0,然后拷貝Source的所有數據;TStream還有其它派生類,其中最常用的是TFileStream類。使用TFileStream類
7、來存取文件,首先要建立一個實例。聲明如下:constructorCreate(constFilename:string;Mode:Word);Filename為文件名(包括路徑),參數Mode為打開文件的方式,它包括文件的打開模式和共享模式,其可能的取值和意義如下:打開模式:fmCreate:用指定的文件名建立文件,如果文件已經存在則打開它。fmOpenRead:以只讀方式打開指定文件fmOpenWrite:以只寫方式打開指定文件fmOpenReadWrite:以寫寫方式打開指定文件共享模式:fmShareCompat:共享模式與FCBs兼容fmShareExclusive:不允許別的程序以任
8、何方式打開該文件fmShareDenyWrite:不允許別的程序以寫方式打開該文件fmShareDenyRead:不允許別的程序以讀方式打開該文件fmShareDenyNone:別的程序可以以任何方式打開該文件TStream還有一個派生類TMemoryStream,實際應用中用的次數也非常頻繁。它叫內存流,就是說在內存中建立一個流對象。它的基本方法和函數跟上面是一樣的。好了,有了上面的基礎后,我們就可以開始我們的編程之行了。-二、實際應用之一:利用流制作EXE文件加密器、捆綁、自解壓文件及安裝程序我們先來說一下如何制作一個EXE文件加密器吧。EXE文件加密器的原理:建立兩個文件,一個用來添加資
9、源到另外一個EXE文件里面,稱為添加程序。另外一個被添加的EXE文件稱為頭文件。該程序的功能是把添加到自己里面的文件讀出來。Windows下的EXE文件結構比較復雜,有的程序還有校驗和,當發現自己被改變后會認為自己被病毒感染而拒絕執行。所以我們把文件添加到自己的程序里面,這樣就不會改變原來的文件結構了。我們先寫一個添加函數,該函數的功能是把一個文件當作一個流添加到另外一個文件的尾部。函數如下:FunctionCjt_AddtoFile(SourceFile,TargetFile:string):Boolean;varTarget,Source:TFileStream;MyFileSize:in
10、teger;begintrySource:=TFileStream.Create(SourceFile,fmOpenReadorfmShareExclusive);Target:=TFileStream.Create(TargetFile,fmOpenWriteorfmShareExclusive);tryTarget.Seek(0,soFromEnd);/往尾部添加資源Target.CopyFrom(Source,0);MyFileSize:=Source.Size+Sizeof(MyFileSize);/計算資源大小,并寫入輔程尾部Target.WriteBuffer(MyFileSize
11、,sizeof(MyFileSize);finallyTarget.Free;Source.Free;end;exceptResult:=False;Exit;end;Result:=True;end;有了上面的基礎,我們應該很容易看得懂這個函數。其中參數SourceFile是要添加的文件,參數TargetFile是被添加到的目標文件。比如說把a.exe添加到b.exe里面可以:Cjt_AddtoFile(a.exe,b.exe);如果添加成功就返回True否則返回假。根據上面的函數我們可以寫出相反的讀出函數:FunctionCjt_LoadFromFile(SourceFile,Target
12、File:string):Boolean;varSource:TFileStream;Target:TMemoryStream;MyFileSize:integer;begintryTarget:=TMemoryStream.Create;Source:=TFileStream.Create(SourceFile,fmOpenReadorfmShareDenyNone);trySource.Seek(-sizeof(MyFileSize),soFromEnd);Source.ReadBuffer(MyFileSize,sizeof(MyFileSize);/讀出資源大小Source.Seek(
13、-MyFileSize,soFromEnd);/定位到資源位置Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize);/取出資源Target.SaveToFile(TargetFile);/存放到文件finallyTarget.Free;Source.Free;end;exceptResult:=false;Exit;end;Result:=true;end;其中參數SourceFile是已經添加了文件的文件名稱,參數TargetFile是取出文件后保存的目標文件名。比如說Cjt_LoadFromFile(b.exe,a.txt);在b.exe
14、中取出文件保存為a.txt。如果取出成功就返回True否則返回假。打開Delphi,新建一個工程,在窗口上放上一個Edit控件Edit1和兩個Button:Button1和Button2。Button的Caption屬性分別設置為“確定”和“取消”。在Button1的Click事件中寫代碼:varS:string;beginS:=ChangeFileExt(Application.ExeName,.Cjt);ifEdit1.Text=790617thenbeginCjt_LoadFromFile(Application.ExeName,S);取出文件保存在當前路徑下并命名原文件.CjtWine
15、xec(pchar(S),SW_Show);運行原文件.CjtApplication.Terminate;退出程序endelseApplication.MessageBox(密碼不對,請重新輸入!,密碼錯誤,MB_ICONERROR+MB_OK);編譯這個程序,并把EXE文件改名為head.exe。新建一個文本文件head.rc,內容為:headexefilehead.exe,然后把它們拷貝到Delphi的BIN目錄下,執行Dos命令Brcc32.exehead.rc,將產生一個head.res的文件,這個文件就是我們要的資源文件,先留著。我們的頭文件已經建立了,下面我們來建立添加程序。新建一
16、個工程,放上以下控件:一個Edit,一個Opendialog,兩個Button1的Caption屬性分別設置為選擇文件和加密。在源程序中添加一句:$Rhead.res并把head.res文件拷貝到程序當前目錄下。這樣一來就把剛才的head.exe跟程序一起編譯了。在Button1的Cilck事件里面寫下代碼:ifOpenDialog1.ExecutethenEdit1.Text:=OpenDialog1.FileName;在Button2的Cilck事件里面寫下代碼:varS:String;beginS:=ExtractFilePath(Edit1.Text);ifExtractRes(exe
17、file,head,S+head.exe)thenifCjt_AddtoFile(Edit1.Text,S+head.exe)thenifDeleteFile(Edit1.Text)thenifRenameFile(S+head.exe,Edit1.Text)thenApplication.MessageBox(文件加密成功!,信息,MB_ICONINFORMATION+MB_OK)elsebeginifFileExists(S+head.exe)thenDeleteFile(S+head.exe);Application.MessageBox(文件加密失敗!,信息,MB_ICONINFORM
18、ATION+MB_OK)end;end;其中ExtractRes為自定義函數,它的作用是把head.exe從資源文件中取出來。FunctionExtractRes(ResType,ResName,ResNewName:String):boolean;varRes:TResourceStream;begintryRes:=TResourceStream.Create(Hinstance,Resname,Pchar(ResType);tryRes.SavetoFile(ResNewName);Result:=true;finallyRes.Free;end;exceptResult:=false;
19、end;end;注意:我們上面的函數只不過是簡單的把一個文件添加到另一個文件的尾部。實際應用中可以改成可以添加多個文件,只要根據實際大小和個數定義好偏移地址就可以了。比如說文件捆綁機就是把兩個或者多個程序添加到一個頭文件里面。那些自解壓程序和安裝程序的原理也是一樣的,不過多了壓縮而已。比如說我們可以引用一個LAH單元,把流壓縮后再添加,這樣文件就會變的很小。讀出來時先解壓就可以了。另外,文中EXE加密器的例子還有很多不完善的地方,比如說密碼固定為790617,取出EXE運行后應該等它運行完畢后刪除等等,讀者可以自行修改。- 我們經常看到一些電子賀卡之類的制作軟件,可以讓你自己選擇圖片,然后它會
20、生成一個EXE可執行文件給你。打開賀卡時就會一邊放音樂一邊顯示出圖片來。現在學了流操作之后,我們也可以做一個了。 添加圖片過程我們可以直接用前面的Cjt_AddtoFile,而現在要做的是如何把圖像讀出并顯示。我們用前面的Cjt_LoadFromFile先把圖片讀出來保存為文件再調入也是可以的,但是還有更簡單的方法,就是直接把文件流讀出來顯示,有了流這個利器,一切都變的簡單了。 現在的圖片比較流行的是BMP格式和JPG格式。我們現在就針對這兩種圖片寫出讀取并顯示函數。Function Cjt_BmpLoad(ImgBmp:TImage;SourceFile:String):Boolean;va
21、rSource:TFileStream;MyFileSize:integer;beginSource:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);trytrySource.Seek(-sizeof(MyFileSize),soFromEnd);Source.ReadBuffer(MyFileSize,sizeof(MyFileSize);/讀出資源Source.Seek(-MyFileSize,soFromEnd);/定位到資源開始位置ImgBmp.Picture.Bitmap.LoadFromStream(Sou
22、rce);finallySource.Free;end;exceptResult:=False;Exit;end;Result:=True;end; 上面是讀出BMP圖片的,下面的是讀出JPG圖片的函數,因為要用到JPG單元,所以要在程序中添加一句:uses jpeg。Function Cjt_JpgLoad(JpgImg:Timage;SourceFile:String):Boolean;varSource:TFileStream;MyFileSize:integer;Myjpg: TJpegImage;begintryMyjpg:= TJpegImage.Create;Source:=TF
23、ileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);trySource.Seek(-sizeof(MyFileSize),soFromEnd);Source.ReadBuffer(MyFileSize,sizeof(MyFileSize);Source.Seek(-MyFileSize,soFromEnd);Myjpg.LoadFromStream(Source);JpgImg.Picture.Bitmap.Assign(Myjpg);finallySource.Free;Myjpg.free;end;exceptResult:
24、=false;Exit;end;Result:=true;end; 有了這兩個函數,我們就可以制作讀出程序了。下面我們以BMP圖片為例: 運行Delphi,新建一個工程,放上一個顯示圖像控件Image1。在窗口的Create事件中寫上一句就可以了:Cjt_BmpLoad(Image1,Application.ExeName); 這個就是頭文件了,然后我們用前面的方法生成一個head.res資源文件。下面就可以開始制作我們的添加程序了。全部代碼如下:unit Unit1;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Co
25、ntrols, Forms, Dialogs,ExtCtrls, StdCtrls, ExtDlgs;typeTForm1 = class(TForm)Edit1: TEdit;Button1: TButton;Button2: TButton;OpenPictureDialog1: TOpenPictureDialog;procedure FormCreate(Sender: TObject);procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);privateFunction Extr
26、actRes(ResType, ResName, ResNewName : String):boolean;Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean; Private declarations public Public declarations end;varForm1: TForm1;implementation$R *.DFMFunction TForm1.ExtractRes(ResType, ResName, ResNewName : String):boolean;varRes : TResourceS
27、tream;begintryRes := TResourceStream.Create(Hinstance, Resname, Pchar(ResType);tryRes.SavetoFile(ResNewName);Result:=true;finallyRes.Free;end;exceptResult:=false;end;end;Function TForm1.Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;varTarget,Source:TFileStream;MyFileSize:integer;begintrySource
28、:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);tryTarget.Seek(0,soFromEnd);/往尾部添加資源Target.CopyFrom(Source,0);MyFileSize:=Source.Size+Sizeof(MyFileSize);/計算資源大小,并寫入輔程尾部Target.WriteBuffer(MyFileSize,sizeof(MyFileSi
29、ze);finallyTarget.Free;Source.Free;end;exceptResult:=False;Exit;end;Result:=True;end;procedure TForm1.FormCreate(Sender: TObject);beginCaption:=Bmp2Exe演示程序.作者:陳經韜;Edit1.Text:=;OpenPictureDialog1.DefaultExt := GraphicExtension(TBitmap);OpenPictureDialog1.Filter := GraphicFilter(TBitmap);Button1.Capti
30、on:=選擇BMP圖片;Button2.Caption:=生成EXE;end;procedure TForm1.Button1Click(Sender: TObject);beginif OpenPictureDialog1.Execute thenEdit1.Text:=OpenPictureDialog1.FileName;end;procedure TForm1.Button2Click(Sender: TObject);varHeadTemp:String;beginif Not FileExists(Edit1.Text) thenbeginApplication.MessageBo
31、x(BMP圖片文件不存在,請重新選擇!,信息,MB_ICONINFORMATION+MB_OK)Exit;end;HeadTemp:=ChangeFileExt(Edit1.Text,.exe);if ExtractRes(exefile,head,HeadTemp) thenif Cjt_AddtoFile(Edit1.Text,HeadTemp) thenApplication.MessageBox(EXE文件生成成功!,信息,MB_ICONINFORMATION+MB_OK)elsebeginif FileExists(HeadTemp) then DeleteFile(HeadTemp
32、);Application.MessageBox(EXE文件生成失敗!,信息,MB_ICONINFORMATION+MB_OK)end;end;end. 怎么樣?很神奇吧:)把程序界面弄的漂亮點,再添加一些功能,你會發現比起那些要注冊的軟件來也不會遜多少吧。-實際應用之三:利用流制作自己的OICQ OICQ是深圳騰訊公司的一個網絡實時通訊軟件,在國內擁有大量的用戶群。但OICQ必須連接上互聯網登陸到騰訊的服務器才能使用。所以我們可以自己寫一個在局部網里面使用。 OICQ使用的是UDP協議,這是一種無連接協議,即通信雙方不用建立連接就可以發送信息,所以效率比較高。Delphi本身自帶的FastN
33、Et公司的NMUDP控件就是一個UDP協議的用戶數據報控件。不過要注意的是如果你使用了這個控件必須退出程序才能關閉計算機,因為TNMXXX控件有BUG。所有nm控件的基礎 PowerSocket用到的ThreadTimer,用到一個隱藏的窗口(類為TmrWindowClass)處理有硬傷。出問題的地方:Psock:TThreadTimer:WndProc(var msg:TMessage)if msg.message=WM_TIMER then他自己處理msg.result:=0elsemsg.result:=DefWindowProc(0,.)end 問題就出在調用 DefWindowPro
34、c時,傳輸的HWND參數居然是常數0,這樣實際上DefWindowProc是不能工作的,對任何輸入的消息的調用均返回0,包括WM_QUERYENDSESSION,所以不能退出windows。由于DefWindowProc的不正常調用,實際上除WM_TIMER,其他消息由DefWindowProc處理都是無效的。解決的辦法是在 PSock.pas在 TThreadTimer.Wndproc 內Result := DefWindowProc( 0, Msg, WPARAM, LPARAM );改為:Result := DefWindowProc( FWindowHandle, Msg, WPARA
35、M, LPARAM ); 早期低版本的OICQ也有這個問題,如果不關閉OICQ的話,關閉計算機時屏幕閃了一下又返回了。 好了,廢話少說,讓我們編寫我們的OICQ吧,這個實際上是Delphi自帶的例子而已:) 新建一個工程,在FASTNET面版拖一個NMUDP控件到窗口,然后依次放上三個EDIT,名字分別為EditIP、EditPort、EditMyTxt,三個按鈕BtSend、BtClear、BtSave,一個MEMOMemoReceive,一個SaveDialog和一個狀態條StatusBar1。當用戶點擊BtSend時,建立一個內存流對象,把要發送的文字信息寫進內存流,然后NMUDP把流發
36、送出去。當NMUDP有數據接收時,觸發它的DataReceived事件,我們在這里再把接收到的流轉換為字符信息,然后顯示出來。 注意:所有的流對象建立后使用完畢后要記得釋放(Free),其實它的釋構函數應該為Destroy,但如果建立流失敗的話,用Destroy會產生異常,而用Free的話程序會先檢查有沒有成功建立了流,如果建立了才釋放,所以用Free比較安全。 在這個程序中我們用到了NMUDP控件,它有幾個重要的屬性。RemoteHost表示遠程電腦的IP或者計算機名,LocalPort是本地端口,主要監聽有沒有數據傳入。而RemotePort是遠程端口,發送數據時通過這個端口把數據發送出去
37、。理解這些已經可以看懂我們的程序了。全部代碼如下:unit Unit1;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, ComCtrls,NMUDP;typeTForm1 = class(TForm)NMUDP1: TNMUDP;EditIP: TEdit;EditPort: TEdit;EditMyTxt: TEdit;MemoReceive: TMemo;BtSend: TButton;BtClear: TButton;BtSave: TButto
38、n;StatusBar1: TStatusBar;SaveDialog1: TSaveDialog;procedure BtSendClick(Sender: TObject);procedure NMUDP1DataReceived(Sender: TComponent; NumberBytes: Integer;FromIP: String; Port: Integer);procedure NMUDP1InvalidHost(var handled: Boolean);procedure NMUDP1DataSend(Sender: TObject);procedure FormCrea
39、te(Sender: TObject);procedure BtClearClick(Sender: TObject);procedure BtSaveClick(Sender: TObject);procedure EditMyTxtKeyPress(Sender: TObject; var Key: Char);private Private declarations public Public declarations end;varForm1: TForm1;implementation$R *.DFMprocedure TForm1.BtSendClick(Sender: TObje
40、ct);varMyStream: TMemoryStream;MySendTxt: String;Iport,icode:integer;BeginVal(EditPort.Text,Iport,icode);if icode0 thenbeginApplication.MessageBox(端口必須為數字,請重新輸入!,信息,MB_ICONINFORMATION+MB_OK);Exit;end;NMUDP1.RemoteHost := EditIP.Text; 遠程主機NMUDP1.LocalPort:=Iport; 本地端口NMUDP1.RemotePort := Iport; 遠程端口M
41、ySendTxt := EditMyTxt.Text;MyStream := TMemoryStream.Create; 建立流tryMyStream.Write(MySendTxt1, Length(EditMyTxt.Text);寫數據NMUDP1.SendStream(MyStream); 發送流finallyMyStream.Free; 釋放流end;end;procedure TForm1.NMUDP1DataReceived(Sender: TComponent;NumberBytes: Integer; FromIP: String; Port: Integer);varMySt
42、ream: TMemoryStream;MyReciveTxt: String;beginMyStream := TMemoryStream.Create; 建立流tryNMUDP1.ReadStream(MyStream);接收流SetLength(MyReciveTxt,NumberBytes);NumberBytes為接收到的字節數MyStream.Read(MyReciveTxt1,NumberBytes);讀數據MemoReceive.Lines.Add(接收到來自主機+FromIP+的信息:+MyReciveTxt);finallyMyStream.Free; 釋放流end;end
43、;procedure TForm1.NMUDP1InvalidHost(var handled: Boolean);beginApplication.MessageBox(對方IP地址不正確,請重新輸入!,信息,MB_ICONINFORMATION+MB_OK);end;procedure TForm1.NMUDP1DataSend(Sender: TObject);beginStatusBar1.SimpleText:=信息成功發出!;end;procedure TForm1.FormCreate(Sender: TObject);beginEditIP.Text:=;Ed
44、itPort.Text:=8868;BtSend.Caption:=發送;BtClear.Caption:=清除聊天記錄;BtSave.Caption:=保存聊天記錄;MemoReceive.ScrollBars:=ssBoth;MemoReceive.Clear;EditMyTxt.Text:=在這里輸入信息,然后點擊發送.;StatusBar1.SimplePanel:=true;end;procedure TForm1.BtClearClick(Sender: TObject);beginMemoReceive.Clear;end;procedure TForm1.BtSaveClick
45、(Sender: TObject);beginif SaveDialog1.Execute then MemoReceive.Lines.SaveToFile(SaveDialog1.FileName);end;procedure TForm1.EditMyTxtKeyPress(Sender: TObject; var Key: Char);beginif Key=#13 then BtSend.Click;end;end. 上面的程序跟OICQ相比當然差之甚遠,因為OICQ利用的是Socket5通信方式。它上線時先從服務器取回好友信息和在線狀態,發送超時還會將信息先保存在服務器,等對方下次
46、上線后再發送然后把服務器的備份刪除。你可以根據前面學的概念來完善這個程序,比如說再添加一個NMUDP控件來管理在線狀態,發送的信息先轉換成ASCII碼進行與或運行并加上一個頭信息,接收方接收信息后先判斷信息頭正確與否,如果正確才把信息解密顯示出來,這樣就提高了安全保密性。 另外,UDP協議還有一個很大的好處就是可以廣播,就是說處于一個網段的都可以接收到信息而不必指定具體的IP地址。網段一般分A、B、C三類,1126.XXX.XXX.XXX (A類網) :廣播地址為XXX.255.255.255128191.XXX.XXX.XXX(B類網):廣播地址為XXX.XXX.255.255192254.
47、XXX.XXX.XXX(C類網):廣播地址為XXX.XXX.XXX.255 比如說三臺計算機、0、8,發送信息時只要指定IP地址為55就可以實現廣播了。下面給出一個轉換IP為廣播IP的函數,快拿去完善自己的OICQ吧-.Function Trun_ip(S:string):string;var s1,s2,s3,ss,sss,Head:string;n,m:integer;beginsss:=S;n:=pos(.,s);s1:=copy(s,1,n);m:=length(s1);delete(s,1,m);
48、Head:=copy(s1,1,(length(s1)-1);n:=pos(.,s);s2:=copy(s,1,n);m:=length(s2);delete(s,1,m);n:=pos(.,s);s3:=copy(s,1,n);m:=length(s3);delete(s,1,m);ss:=sss;if strtoint(Head) in 1.126 then ss:=s1+255.255.255; /155 (A類網)if strtoint(Head) in 128.191 then ss:=s1+s2+255.255;/128191.XXX.255.255(B類
49、網)if strtoint(Head) in 192.254 then ss:=s1+s2+s3+255; /192254.XXX.XXX.255(C類網)Result:=ss;end;-五、實際應用之四:利用流實現網絡傳輸屏幕圖像 大家應該見過很多網管程序,這類程序其中有一個功能就是監控遠程電腦的屏幕。實際上,這也是利用流操作來實現的。下面我們給出一個例子,這個例子分兩個程序,一個服務端,一個是客戶端。程序編譯后可以直接在單機、局部網或者互聯網上使用。程序中已經給出相應注釋。后面我們再來作具體分析。 新建一個工程,在Internet面版上拖一個ServerSocket控件到窗口,該控件主要用
50、于監聽客戶端,用來與客戶端建立連接和通訊。設置好監聽端口后調用方法Open或者Active:=True即開始工作。注意:跟前面的NMUDP不同,當Socket開始監聽后就不能再改變它的端口,要改變的話必須先調用Close或設置Active為False,否則將會產生異常。另外,如果該端口已經打開的話,就不能再用這個端口了。所以程序運行尚未退出就不能再運行這個程序,否則也會產生異常,即彈出出錯窗口。實際應用中可以通過判斷程序是否已經運行,如果已經運行就退出的方法來避免出錯。 當客戶端有數據傳入,將觸發ServerSocket1ClientRead事件,我們可以在這里對接收的數據進行處理。在本程序中
51、,主要是接收客戶端發送過來的字符信息并根據事先的約定來進行相應操作。程序全部代碼如下:unit Unit1;服務端程序interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, JPEG,ExtCtrls, ScktComp;typeTForm1 = class(TForm)ServerSocket1: TServerSocket;procedure ServerSocket1ClientRead(Sender: TObject;Socket: TCustomWinSocket);
52、procedure FormCreate(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);privateprocedure Cjt_GetScreen(var Mybmp: TBitmap; DrawCur: Boolean);自定義抓屏函數,DrawCur表示抓鼠標圖像與否 Private declarations public Public declarations end;varForm1: TForm1;MyStream: TMemorystream;內存流對象impleme
53、ntation$R *.DFMprocedure TForm1.Cjt_GetScreen(var Mybmp: TBitmap; DrawCur: Boolean);varCursorx, Cursory: integer;dc: hdc;Mycan: Tcanvas;R: TRect;DrawPos: TPoint;MyCursor: TIcon;hld: hwnd;Threadld: dword;mp: tpoint;pIconInfo: TIconInfo;beginMybmp := Tbitmap.Create; 建立BMPMAP Mycan := TCanvas.Create; 屏
54、幕截取dc := GetWindowDC(0);tryMycan.Handle := dc;R := Rect(0, 0, screen.Width, screen.Height);Mybmp.Width := R.Right;Mybmp.Height := R.Bottom;Mybmp.Canvas.CopyRect(R, Mycan, R);finallyreleaseDC(0, DC);end;Mycan.Handle := 0;Mycan.Free;if DrawCur then 畫上鼠標圖象beginGetCursorPos(DrawPos);MyCursor := TIcon.Create;getcursorpos(mp);hld := WindowFromPoint(mp);Threadld := GetWindowThreadProcessId(hld, nil);AttachThreadInput(GetCurrentTh
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 鋼板合同協議書樣板圖
- 中國染布行業市場前景預測及投資價值評估分析報告
- 商務包車運營方案范文
- 麻辣燙創業計劃書例文
- 中國橡膠及橡膠制品項目投資計劃書
- 噴頭維修合同協議書
- 外賣超時計劃書
- 校園桌游創業計劃書模板
- 經紀合同合作協議書
- 馬病復習資料
- 乳腺癌手術的整體治療
- 2023年陜西省普通高校職業教育單獨招生考試英語試題及答案
- 工程師轉正工作總結
- 8 推翻帝制 民族覺醒 說課稿 -2023-2024學年道德與法治五年級下冊統編版
- 麗聲北極星分級繪本第二級下-
- 變電站數字孿生框架構建與關鍵技術研究
- 2025-2030年中國報廢汽車回收行業市場十三五發展規劃及投資戰略研究報告新版
- DIP支付下的病案首頁填寫
- 兩癌防治知識培訓
- KCA試題庫完整版
- 2025屆湖南省高考化學第一輪復習模擬選擇題-化學與生活43道(附答案)
評論
0/150
提交評論