zoukankan      html  css  js  c++  java
  • 实用控件:将任意文件打包进dfm(zlib压缩)的控件 [转]

    来源:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3263037

    该控件可以将任意文件打包进.dfm(使用zlib压缩),可以用该控件编写只有一个exe的绿色软件,或者用于自己编写安装程序。
    使用非常简单,设计期将该控件放入form, 指定FileName属性即可将该文件内容打包进dfm中。运行时可以调用FileRes1.ResToFile解压到指定的文件内或通过FileRes1.ResToStream解压到一个stream中(比如图片文件,接下去可以用Bitmap.LoadFromStream读入),这两个函数的Keep参数指定是否在操作的同时释放FileRes中占用的内存(如果只需要在程序运行时解压一次则建议使用Keep := False; 这样可以降低程序占用的内存)
    unit FileRes;
    interface
    uses
      SysUtils, Classes, Windows, ZLib;
    type
      TBufferStream = class(TStream)
      private
        FLen: Cardinal;
        FBuffer: Pointer;
        FPosition: Cardinal;
      protected
        procedure SetSize(NewSize: Longint); override;
      public
        destructor Destroy; override;
        function Read(var Buffer; Count: Longint): Longint; override;
        function Seek(Offset: Longint; Origin: Word): Longint; override;
        function Write(const Buffer; Count: Longint): Longint; override;
        procedure SaveToFile(FileName: string);
        procedure LoadFromFile(FileName: string);
        function SaveToStream(Stm: TStream): Integer;
        procedure LoadFromStream(Stm: TStream);
        function ReadString: string;
        procedure Writestring(const Str: string);
        procedure ExchangeBuffer(var ABuffer: Pointer; var ALen: Integer);
        property Buffer: Pointer read FBuffer;
      end;
      TFileRes = class(TComponent)
      private
        { Private declarations }
        FStream: TBufferStream;
        FFileName: TFileName;
        procedure WriteFileData(Stm: TStream);
        procedure ReadFileData(Stm: TStream);
        procedure SetFileName(const Value: TFileName);
      protected
        { Protected declarations }
        procedure DefineProperties(Filer: TFiler); override;
      public
        { Public declarations }
        destructor Destroy; override;
        function ResToFile(AFileName: string; Keep: Boolean = false): Boolean;
        function ResToStream(var Stm: TStream; Keep: Boolean = false): Boolean;
        property Stream: TBufferStream read FStream;
      published
        { Published declarations }
        property FileName: TFileName read FFileName write SetFileName;
      end;
    procedure Register;
    implementation
    procedure Register;
    begin
      RegisterComponents('Standard', [TFileRes]);
    end;
    { TBufferStream }
    destructor TBufferStream.Destroy;
    begin
      reallocmem(fbuffer, 0);
      inherited;
    end;
    procedure TBufferStream.ExchangeBuffer(var ABuffer: Pointer;
      var ALen: Integer);
    var
      tmp: Integer;
    begin
      tmp := Integer(ABuffer);
      ABuffer := FBuffer;
      FBuffer := Pointer(tmp);
      tmp := ALen;
      ALen := FLen;
      FLen := tmp;
      if FPosition > FLen then FPosition := FLen;
    end;
    procedure TBufferStream.LoadFromFile(FileName: string);
    var
      fid: Integer;
    begin
      reallocmem(fbuffer, 0);
      flen := 0;
      fid := fileopen(filename, fmOpenRead or fmShareDenyNone);
      if fid < 0 then exit;
      flen := getfilesize(fid, nil);
      reallocmem(fbuffer, flen);
      fileread(fid, fbuffer^, flen);
      fileclose(fid);
      position := 0;
    end;
    procedure TBufferStream.LoadFromStream(Stm: TStream);
    var
      buf: Pointer;
      l: Integer;
    begin
      reallocmem(fbuffer, 0);
      flen := 0;
      fposition := 0;
      stm.Read(l, 4);
      if l > 0 then
      begin
        getmem(buf, l);
        stm.Read(buf^, l);
        try
          decompressbuf(buf, l, l, fbuffer, Integer(flen));
        except
          fbuffer := nil;
        end;
        freemem(buf);
      end;
    end;
    function TBufferStream.Read(var Buffer; Count: Integer): Longint;
    begin
      if fposition+count>flen then result := flen-fposition
      else result := count;
      if result > 0 then
      begin
        move(PByteArray(fbuffer)[fposition], buffer, result);
        inc(fposition, result);
      end;
    end;
    function TBufferStream.ReadString: string;
    var
      l: Integer;
    begin
      read(l, 4);
      setlength(result, l);
      if l > 0 then
        read(result[1], l);
    end;
    procedure TBufferStream.SaveToFile(FileName: string);
    var
      fid: Integer;
    begin
      fid := filecreate(filename);
      if fid < 0 then exit;
      if flen > 0 then
        filewrite(fid, fbuffer^, flen);
      fileclose(fid);
    end;
    function TBufferStream.SaveToStream(Stm: TStream): Integer;
    var
      buf: Pointer;
    begin
      try
        compressbuf(fbuffer, flen, buf, result);
      except
        result := 0;
      end;
      stm.Write(result, 4);
      if result > 0 then
      begin
        stm.Write(buf^, result);
        freemem(buf);
      end;
      inc(result, 4);
    end;
    function TBufferStream.Seek(Offset: Integer; Origin: Word): Longint;
    begin
      case origin of
        0: if offset >= 0 then fposition := offset;
        1: inc(fposition, offset);
        2: fposition := flen + offset;
      end;
      result := fposition;
    end;
    procedure TBufferStream.SetSize(NewSize: Integer);
    begin
      if flen <> newsize then
      begin
        flen := newsize;
        reallocmem(fbuffer, newsize);
        if fposition > flen then fposition := flen;
      end;
    end;
    function TBufferStream.Write(const Buffer; Count: Integer): Longint;
    begin
      try
        if fposition + count > flen then
          setsize(fposition + count);
        result := count;
        move(buffer, PByteArray(fbuffer)[fposition], count);
        inc(fposition, count);
      except
        result := 0;
      end;
    end;
    procedure TBufferStream.Writestring(const Str: string);
    var
      l: Integer;
    begin
      l := Length(str);
      write(l, 4);
      if l > 0 then
        write(str[1], l);
    end;
    { TFileRes }
    destructor TFileRes.Destroy;
    begin
      if assigned(FStream) then
        fstream.Free;
      inherited;
    end;
    procedure TFileRes.DefineProperties(Filer: TFiler);
    begin
      inherited;
      filer.DefineBinaryProperty('FileStreamData', ReadFileData, WriteFileData, assigned(fstream));
    end;
    procedure TFileRes.ReadFileData(Stm: TStream);
    begin
      if not assigned(fstream) then
        fstream := TBufferStream.Create;
      fstream.LoadFromStream(stm);
    end;
    procedure TFileRes.WriteFileData(Stm: TStream);
    begin
      if assigned(fstream) then
        fstream.SaveToStream(stm);
    end;
    function TFileRes.ResToFile(AFileName: string; Keep: Boolean): Boolean;
    var
      fid: Integer;
    begin
      result := false;
      if not assigned(fstream) then exit;
      fid := filecreate(afilename);
      if fid < 0 then exit;
      if fstream.FLen > 0 then
        filewrite(fid, fstream.fbuffer^, fstream.FLen);
      fileclose(fid);
      result := true;
      if not keep then
        freeandnil(fstream);
    end;
    function TFileRes.ResToStream(var Stm: TStream; Keep: Boolean): Boolean;
    begin
      result := assigned(fstream);
      if result then
      begin
        stm := fstream;
        if not keep then
          fstream := nil;
      end;
    end;
    procedure TFileRes.SetFileName(const Value: TFileName);
    begin
      if (csDesigning in ComponentState) {and (value <> ffilename)} then
      begin
        FFileName := Value;
        if not (csLoading in ComponentState) then
          if value <> '' then
          begin
            if not assigned(fstream) then
              fstream := TBufferStream.Create;
            fstream.LoadFromFile(value);
            if fstream.FLen = 0 then
              freeandnil(fstream);
          end
          else freeandnil(fstream);
      end;
    end;
    end. 

  • 相关阅读:
    Leetcode 538. Convert BST to Greater Tree
    Leetcode 530. Minimum Absolute Difference in BST
    Leetcode 501. Find Mode in Binary Search Tree
    Leetcode 437. Path Sum III
    Leetcode 404. Sum of Left Leaves
    Leetcode 257. Binary Tree Paths
    Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
    Leetcode 226. Invert Binary Tree
    Leetcode 112. Path Sum
    Leetcode 111. Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/railgunman/p/1885967.html
Copyright © 2011-2022 走看看