开发工具:
文件大小: 298kb
下载次数: 0
上传时间: 2019-07-16
详细说明:Delphi_流操作的语法.pdfTarget. Copy From(Source, 0)
My Filesize:= Source sizetsizeof( MyFileSize);/计算资源人小,并写入辅程尾部
Targct. Write Buffcr(MyFilc Sizc, sizeof(My FilcSizc)
finally
Target. Free
F1
end
exce
Result: False
Exit
end
Result =True
有了上面的基础,我们应该很容易看得懂这个函数。其中参数 Sourcefile是要添加的文件,参数
TargetFile是被添加到的目标文件。比如说把aexe添加到bexe里面可以
Cjt AddtoFile(a.exe'b.exe);如果添加成功就返回True否则返回假。
根据上面的函数我们可以写出相反的读出函数:
Function Cjt LoadFrom File(Source File, Target File: string): Boolean;
Source TFileStream
Target: TMemory Stream
MyFllesize: integer
begin
Target: =TMemory Stream Create;
Source: TFlleStream Create(Source File, fmOpenRead or fm ShareDenyNone)
tr
of( My Filc Sizc), so FromEnd)
Source. ReadBuffer( My FileSize, sizeof( MyFilesize)/)出资源人小
Source seek( My Filesize, soFromEnd;/定位到资源位置
arget Copy Fron( Source, My Filesize- sizeof( MyFilesize);/取出资源
Target. Save ToFile( TargetFile);放到文件
finall
ource.free
Result: false
Exit
Result
其中参数 SourceFile是已经添加了文件的文件名称参数 TargetFile是取出文件后保存的目标文
件名。比如说 Cjt LoadFromFile( b. exe.a. txt);在bexe屮取出文件保存为atxt。如果取出成功就
返回True否则返回假。
打开 Delphi,新建一个工程,在窗口上放上一个Edit控件 Edit和个 Button: Button1和
Button2。Butn的 Caption属性分别设置为“确定”和“取消”。在 Button1的 Click事件中写代码:
r S: string;
beg
S: ChangeFileExt(Application. ExeName, Cjt );
if Edit1. Text 790617'then
begin
Cjt LoadFrom File(Application. ExeName, S)
取出文件保存在当前路径下并命名"原文件Cjt"}
Winexec( chart(S), SW Show);{运行"原文件Cjt"}
n Application. Terminate:{退出程序
AT
. pplication
MessageBox(密码不对请重新输入!;密码错误" MB ICONERROR+MBOK)
编译这个程序,并把EXE文件改名为 head. exe新建一个文本文件 head. rc,内容为:head
exefile head. exe,然后把它们拷贝到 Delph的BIN目录下,执行Dos命令Brcc32. exe head. rc,将产
生个 head. res的文件,这个文件就是我们要的资源文件,先留着。
我们的头文件已经建立了,下面我们来建立添加程序。
新建一个工程,放:以下控件:一个Ed,一个 Opendialog,两个 Button1的 Caption属性分别
设置为"选择文件"和"加密"。在源程序中添加一饣:{$ R head, rcs}并把 head. res文件拷贝到程序
当前目录下。这样一来就把刚才的 head. exe跟程序一起编译了,
在 Button 1的Cilk事件里面写下代码
if Open Dialog l Execute then Editl Text: =Open Dialog l FileName
在 Button2的Cilk事件里面写下代码:
var S: String
b
egin
S: ExtractFllePath(EditlText)
if ExtractResd'exefile, head, S+head. exe )then
if Cjt Addto File(editIText, S+head. exe")then
if Delete File(Editl. Text)then
if RenameFile(shead. exe, EditI Text)then
Application Message BoxI(文件加密成功!"信息, MB ICONINFORMATION+MBOK)
begin
if FilcExists(S+head cxc )then DclctcFilc(S-hcad cxc")
Application Message Box(文件加密失败!信息∵ MB ICONⅠ NFORMATION+MBOK)
ent
其中 ExtractRes为自定义函数,它的作用是把 head. exe从资源文件中取出米。
Function ExtractRes( Res Type, Res Name, ResNew Name: String): boolean
var
Res: TResourceStream:
egin
Res: =TResource Stream. Create(Hinstance, Resname, Pchar(Res Type))
try
Res. SavetoFlle(resnewName
Result =true
finally
Res Free
exce
Result: false
end
注意:我们上面的函数只不过是简单的把一个文件添加到另一个文件的尾部。实际应用中
可以改成可以添加多个文件,只要根据实际大小和个数定义好偏移地址就可以了。比如说文件
捆绑机就是把两个或者多个程序添加到个头文件里面。那些自解压程序和安装程序的原理也
是一样的,不过多了压缩而凵。比如说我们可以引用一个LAH单元,把流压缩后再添加,这
样文件就会变的很小。读出来时先解压就可以了。另外,文中EXE加密器的例子还有很多不
完善的地方,比如说密码固定为"79061",取出EΣE运行后应该等它运行完毕后删除等等,读
者可以自行修改
三、实际应用之二:利用流制作可执行电」贺卡
我们经常看到一些电子贺卡之类的制作软件,可以让你自己选择图片,然后它会生成
EXE可执行文件给你。打开贺卡时就会一边放音乐一边显示出图片来。现在学了流操作之后
我们也可以做一个了。
添加图片过程我们可以直接用前面的 Cjt AddtoFile,而现在要做的是如何把图像读出并显
示。我们用前面的 Cjt loadFrom File先把图片读出来保存为文件再调入也是可以的,但是还有
吏简单的方法,就是直接把文件流读出来显示,有∫流这个利器,一切都变的简单∫。
现在的图片比较流行的是BMP格式和JPG格式。我们现在就针对这两种图片写出读取并显
小函数
Function Cjt BmpLoad(Img Bmp: TImage; Source File: String): Boolean
val
Source TFileStream:
MyFllesize: integer
gin
Source: -TFileStream Create( SourceFile, foPen Read or fm ShareDeny None)
try
Source. Seek(-sizeof(MyFlleSize), so FromEnd)
Source. Read Buffer(( My Filesize, sizeof(My Filesize);/读出资源
Source.seek( My Filesize, soFromEnd;/定位到资源开始位置
Ing Bmp Picture Bitmap. LoadFromStream(Source)
finall
ource.free
xcept
Result =false.
Exit
Result=true
上面是读出BMP图片的,下面的是读出JPG图片的函数,因为要用到JPG单元,所以要在
程序中添加一句: uses Jpeg
Function Cjt JpgLoadOpgImg: Timage; SourceFile: String): Boolean
var
Source: TFileStream
MyFllesize: integer;
Myjpg: TJpeglmage;
begin
tr
Myjpg: =TJpeglmage Create
Source: TFileStream Create(Source File, fmOpen Read or fm ShareDenyNone)
try
Source. Seek(-sizeof(MyFileSize), soFromEnd)
Source. ReadBuffer(My FileSize, sizeof (MyFlleSize))
Source. Scck(-MyFilcSize, so FromEnd
Myjpg. LoadFromStream(Source
Jpglmg Picture Bitmap. Assign (Myjpg);
fi
nally
Source. Free
Myjpg. free
except
Result=false.
Exit;
Result = true
有了这两个函数,我们就可以制作读出程序了。下面我们以BMP图片为例
运行 Delphi,新建一个工程,放上一个显示图像控件 Imagel在窗口的 Create事件中写上
句就可以了
Cit Bmpload(Imagel, Application. ExeName);
这个就是头文件了,然后我们用前面的方法牛成一个head.res资源文件
下面就可以开始制作我们的添加程序了。全部代码如下:
unit unit 1
interface
uses
Windows Messages, SysUtils, Classes, Graphics, Controls, Forms, dialogs
Extctrls, StdCtrls, ExtDIgs
typc
TForm1=class(TForm)
Edit tedit.
Button l: TButton:
Button2 TButton
OpenPictureDialogl: TOpen PictureDialog
procedure Form Create(Sender: TObject)
procedure Button 1 Click(Sender: TObject)
procedure Button2 Click(Sender: TObject)
Function ExtractRes(res Type, ResName, ResNew Name String): boolean
Function Cjt AddtoFile( SourceFile, TargetFile: String): Boolean;
i Private declarations 3
pl
pubLIc
i Public declarations 1
end
var
Forml: TForm1
Implementation
ISR*DFM)
Function TForml ExtractRes(Res Type, ResName, ResNew Name: String): boolean;
var
Res: TResourceStream:
Res: TResource Stream. Create(Hinstance, Resname, Pchar(Res Type)
try
Res. Savelo File(resNewName)
Result true
finall
Res free.
except
Result: = false
Function TForml Cit Addto File( Source File, TargetFile: tring): Boolean
van
Target, Source: TFilestream
MyFllesize: integer
g
tr
Source:TFile Stream. Create(Source File, fmOpen Read or fm ShareExclusive
Target: TFile Stream. CreateTargetFile, fmOpen Write or fm Shareexclusive)
Target.Sek(0, soFromEnd);/往尾部添加资源
Target. Copy From(Source, 0)
MyFilcsizc:= Source sizc+Sizκeof( MyFllcsizc);计算资源大小,并写入辅程尾部
Target. Write Buffer(My FileSize, sizeof(My Filesize))
finall
ource.上ree
Result:=False
Exit
Result: True
procedure TForm1. Form Create( Sender: TObject
egin
Caption:=Bmp2Exe演示程序作者:陈经韬
Edit, Text
OpenPictureDialogl. DefaultExt: =Graphic Extension(TBitmap)
Open PictureDialogl Filter:=GraphicFilter(TBitmap)
Buttonl. Caption=选择BMP图片
Butn2 Caption:=生成EXE
end
procedure TForm1. Button1 Click(Sender: TObject
b
if Open PictureDialog l Execute then
Editl.Text: =OpenPicture Dialog1. FileName
proccdurc TForm1. Button2 Click(Scndcr: TObjcct
HeadTemp: String
bc
gin
if Not FileExists(Editl. Text) then
begi
Application Mcssagc BoX(BMP图片文件不存在,请重新选择!!信息
MB ICONINFORMATION+MB OK)
Exit
Head Temp: =Change FileExt(Edit1. Text, exe);
if ExtractRes(exefile, head, Head Temp)then
if Cit AddtoFile( editl. Text, Head Temp)then
application MessageBox(EXE文件生成成功,信息 MB ICONINFORMATION+MBOK)
SC
begin
if FileExists(Head Temp)then DeleteFile(HeadTemp
Application MessageBox(EXE文件生成失败!信息, MB ICONINFORMATION+MBOK)
end
怎么样?很神奇吧:)把程序界面弄的漂亮点,再添加一些功能,你会发现比起那些要注册的
软件来也不会逊多少吧。
实际应用之三:利用流制作自己的OCQ
OCQ是深圳腾讯公司的一个网络实时通讯软件,在国内拥有大量的用户群。但OICQ必须
连接上互联网登陆到腾讯的服务器才能使用。所以我们可以自己写一个在局部网里面使用。
OICQ使用的是UDP协议,这是一种无连接协议,即通信双方不用建立连接就可以发送信
息,所以效率比较高。 Delphi本身自带的 FastNet公司的 NMUDP控件就是一个UDP协议的用
户数据报控件。不过要注意的是如果你使用了这个控件必须退出程序才能关闭计算机,因为
TNMXXX控件有BUG。所有nm控件的基础 Power Socket用到的 Thread Timer,用到一个隐藏
的窗口(类为 Tmr Window class)处理有硬伤。
出问题的地方
Psock: TThreadTimer: WndProc(var msg: TMessage
if msg message=WM TIMER then
他自己处理
msg. rcsult: =0
else
msg.result: =Def Window Proc(o
问题就出在调用 Defwindow Proc时,传输的HWND参数居然是常数0,这样实际上
Defwindow proc是不能工作的,对任何输入的消息的调用均返回0,包括
WM QUERYENDSESSION,所以不能退出 windows。由于 Defwindowproc的不正常调用,实
际上除 WM TIMER,其他消息由 Defwindow Proc处理都是无效的。
解决的办法是在 SOck. pas
在 TThread Timer Wndproc内
Result:=DcfWindow Proc(O, Msg, WPARAM, LPARAM )
改为:
Result: DefWindowProc( FWindow Handle, MSg, WPARAM, LPARAM
早期低版本的OCQ也有这个问题,如果不关闭OICQ的话,关闭计算机时屏幕闪了一下又
返回了
好了,废话少说,计我们编写我们的OCQ吧,这个实际上是 Delphi自带的例子而口:)
建一个工程,在 FASTNET面版拖一个 NMUDP控什到窗口,然后依次放上三个EDIT,名字
分别为 EditIO、 Edit Port、 EditMyTxt,三个按钮 BtSend、 Btclear、 BtSave,一个
MEMOMemoReceive,个 SaveDialog和个状态条 Status Bar1。当用户点击 BtSend时,建立
个内存流对象,把要发送的文字信息写进内存流,然后 NMUDP把流发送出去。当 NMUDP
有数据接收时,触发它的 DataReceived事件,我们在这里再把接收到的流转换为字符信息,然
后显示出来。
注意:所有的流对象建立后使用完毕后要记得释(Free),其实它的释构函数应该为
Destroy,但如果建立流失败的话,用 Destroy会产生异常,而用Free的话程序会先检查有没有
成功建立∫流,如果建立∫才释放,所以用Free比较安仝。
在这个程序中我们用到了 NMUDP控件,它有几个重要的属性。 Remote host表示远程电脑的
I或者计算机名, Localport是本地端口,主要监听冇没有数据传入。而 Remote port是远程端
,发送数据时通过这个端口把薮据发送岀去。理解这些已经可以看懂我们的程序了。
全部代码如下:
unit unitl
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls
ComCtrls NMudP
type
TForml=class(tForm)
NMUDPI: TNMUDP
EditIP: TEdit
EditPort: tedit
Editmy txt tedit
Memo Receive: Tmemo
BtSend: TButton
BtClear: TButton
BtSave. TButton
Status Bar]: TStatus Bar.
SavcDialog l: TSavcDialog
procedure BtSendClick(Sender: TObject)
procedure NMUDP I DataReceived( Sender: TComponent; Number Bytes: Integer;
FromP: String; Port: Integer)
procedure NMUDPlInvalidHost(var handled: Boolean)
procedure NMUDPlDataSend(Sender: TObject)
procedure Form Create( Sender: TObject
procedure BtClear Click(s
procedure BtSaveClick(Sender TObject)
procedure EditMyTxtKey Press(Sender: TObject; var Key: Char)
private
Private declarations j
lbic
i Public declarations i
Forml: TForm1
implementation
ISR.DFM
procedure TForm1. BLSendClick(Sender: TObject)
var
My Stream: TMemory Stream;
My SendTxt: String
Iport, icode: integer
Begin
Val(Editport. Text, Iport, icode)
if icode>o then
g
Application. MessageBox(端口必须为数字,请重新输入"信息
MB ICONINFORMATION+MB OK)
Exit.
enc
NMUDPL Remote Host:= EditIP. Text;{远程主机}
NMUDPlLocalport:= lport;{本地端口
NMUDPL. Remote Port:- Iport;{远程端口}
MySendTxt: Editmy txt Text
MyStream:= TMemory Stream Create;{建立流}
MyStream. Write( MySendTxt[1 Length( Editmy Txt Text);{写数据}
NMUDPL Sendstream( MyStream);{发送流}
finall
MyStream. Free;{释放流}
procedure TForm1.NMUDPlDataReceived(Sender: TComponent
Number Bytes: Integer; FromIP: String: Port: Integer)
var
MyStream: TMemory Stream
MyReciveTxl: String
MyStream:= TMemory Stream Create;{建立流}
NMUDPLRcadStrcam( My Strcam);{接收流}
SetLength( My ReciveTX, NumberBytes);{ Numberbytes为接收到的字节数
My Stream Read( MyReciveTxt[] NumberBytes;{读数据}
Memo Receive. Lines. ado(接收到来自主机+ FromE.+的信息 MyRecivetxt);
finall
MyStream Free,
释放流}
(系统自动生成,下载前可以参看下载内容)
下载文件列表
相关说明
- 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
- 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度。
- 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
- 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
- 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
- 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.