How to correctly declare StreamLn [closed]

北城余情 提交于 2019-12-02 23:26:21

问题


I am trying to compile my program but I am getting this error:

Undeclared indentifier 'StreamLn'

i even tried to download PSock.dcu and put it into the library but it doesnt compile, it looks like its compactible with delphi 5,

unit ResourceInfo;

interface

uses
  Classes, SysUtils, Windows;

type
  TResourceInfo = class;

  TDfmMode = ( dfmData, dfmResource, dfmASCII, dfmBinary);

  TDfm = class
  private
    FOwner: TResourceInfo;
    FName: string;
    FData: TStream;

    procedure SetName(const Value: string);
    procedure SetOwner(const Value: TResourceInfo);

  public
    constructor Create(AOwner: TResourceInfo);
    destructor Destroy; override;

    function SaveToFile(FileName: TFileName; Mode: TDfmMode): Boolean;

    property Data: TStream read FData;
    property Name: string read FName write SetName;
    property Owner: TResourceInfo read FOwner write FOwner;
  end; {TDfm}

  TResourceInfo = class(TComponent)
  private
    FActive: Boolean;
    FDfms: TList;
    FExeFileName: TFileName;
    FModule: THandle;
    FOnActivate: TNotifyEvent;
    FOnDeactivate: TNotifyEvent;

    procedure SetExeFileName(const Value: TFileName);
    procedure SetActive(const Value: Boolean);
    function  GetDfms(Index: Cardinal): TDfm;
    function  GetDfmCount: Cardinal;

  protected
    procedure Clear;

  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;

    function  AddDfm(const Name: string; AData: TMemoryStream): Integer;
    procedure DeleteDfm(const Name: string);
    property  DfmCount: Cardinal read GetDfmCount;
    property  Dfms[Index: Cardinal]: TDfm read GetDfms;
    procedure EnumDfmNames;
    property  Module: THandle read FModule;

  published
    property Active: Boolean read FActive write SetActive;
    property ExeFileName: TFileName read FExeFileName write SetExeFileName;

    property OnActivate: TNotifyEvent read FOnActivate write FOnActivate;
    property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate;
  end; {TResourceInfo}

procedure Register;

implementation

uses
 Winsock;

resourcestring
  rsErrorLoadingExeFile = 'An error ocurred loading file %s, it may not be an executable module';

procedure Register;
begin
  RegisterComponents('+HCU', [TResourceInfo]);
end; {Register}

{ TResourceInfo }

function TResourceInfo.AddDfm(const Name: string; AData: TMemoryStream): Integer;
var
  FDfm: TDfm;
begin
  FDfm := TDfm.Create(Self);
  FDfm.Name := Name;
  FDfm.Data.Size := AData.Size;
  FDfm.Data.Seek(0, 0);
  AData.Seek(0, 0);
  FDfm.Data.CopyFrom(AData, AData.Size);
  Result := FDfms.Add(FDfm);
end; {TResourceInfo.AddDfm}

constructor TResourceInfo.Create(AOwner: TComponent);
begin
  inherited;

  FActive := False;
  FDfms := TList.Create;
  FModule := 0;
end; {TResourceInfo.Create}

destructor TResourceInfo.Destroy;
begin
  Clear;
  FDfms.Free;

  inherited;
end; {TResourceInfo.Destroy}

function CB_EnumDfmNameProc(hModule: THandle; lpszType, lpszName: PChar; lParam: Integer): Boolean; stdcall;
var
  ms: TMemoryStream;
  rs: TResourceStream;
  Buffer: array of Byte;
begin
  with TResourceInfo(lParam) do
    begin
      rs := TResourceStream.Create(TResourceInfo(lParam).Module, lpszname, lpszType);
      try
        ms := TMemoryStream.Create;
        try
          try
            SetLength(Buffer, 4);
            rs.Read(Buffer[0], SizeOf(Buffer));
            if string(Buffer) = 'TPF0' then
              begin
                rs.Seek(0, 0);
                ObjectBinaryToText(rs, ms);
                ms.Seek(0, 0);
                AddDfm(StrPas(lpszName), ms);
              end;
          except
            raise;
          end;
        finally
          ms.Free;
        end;
      finally
        rs.free;
      end;
    end;

  Result := True;
end; {CB_EnumDfmNameProc}

procedure TResourceInfo.EnumDfmNames;
begin
  if FModule > 0 then
    EnumResourceNames(FModule, RT_RCDATA, @CB_EnumDfmNameProc, Integer(Self));
end; {TResourceInfo.EnumDfmNames}

procedure TResourceInfo.DeleteDfm(const Name: string);
var
  i: Cardinal;
begin
  if FDfms.Count > 0 then
    for i := Pred(FDfms.Count) downto 0 do
      if UpperCase(TDfm(FDfms[i]).Name) = UpperCase(Name) then
        begin
          FDfms.Delete(i);
          Break;
        end;
end; {TResourceInfo.DeleteDfm}

procedure TResourceInfo.SetActive(const Value: Boolean);
begin
  if FActive <> Value then
    begin
      if Value then
        begin
          if FModule > 0 then
            FreeLibrary(FModule);

            (* LOAD_LIBRARY_AS_DATAFILE
               If this value is given, the function does a simple mapping of the file into the
               address space. Nothing is done relative to executing or preparing to execute the
               code in the mapped file. The function loads the module as if it were a data file.
               You can use the module handle that the function returns in this case with the Win32
               functions that operate on resources. Use this flag when you want to load a DLL in
               order to extract messages or resources from it, and have no intention of executing
               its code.If this value is not given, the function maps the file into the address
               space in the manner that is normal for an executable module. The behavior of the
               function is then identical to that of LoadLibrary in this regard. *)

          FModule := LoadLibraryEx(PChar(FExeFileName), 0, LOAD_LIBRARY_AS_DATAFILE);
          if not (FModule >= 32) then
            raise Exception.CreateFmt(rsErrorLoadingExeFile, [FExeFileName]);
          if Assigned(FOnActivate) then
            FOnActivate(Self);
        end
      else
        begin
          Clear;
          if FModule > 0 then
            begin
              FreeLibrary(FModule);
              FModule := 0;
            end;
          if Assigned(FOnDeactivate) then
            FOnDeactivate(Self);
        end;
      FActive := Value;
    end;
end; {TResourceInfo.SetActive}

procedure TResourceInfo.SetExeFileName(const Value: TFileName);
begin
  if FExeFileName <> Value then
    FExeFileName := Value;
end; {TResourceInfo.SetExeFileName}

function TResourceInfo.GetDfms(Index: Cardinal): TDfm;
begin
  Result := TDfm(FDfms[Index]);
end; {TResourceInfo.GetDfms}

function TResourceInfo.GetDfmCount: Cardinal;
begin
  Result := FDfms.Count;
end; {TResourceInfo.GetDfmCount}

procedure TResourceInfo.Clear;
begin
  if FDfms.Count > 0 then
    while FDfms.Count > 0 do
      FDfms.Delete(0);
end; {TResourceInfo.Clear}

{ TDfm }

constructor TDfm.Create(AOwner: TResourceInfo);
begin
  inherited Create;

  FData := TMemoryStream.Create;
  FName := '';
  SetOwner(AOwner);
end; {TDfm.Create}

destructor TDfm.Destroy;
begin
  FData.Free;
  inherited;
end; {TDfm.Destroy}


function TDfm.SaveToFile(FileName: TFileName; Mode: TDfmMode): Boolean;

  function EndOfStream(Stream: TStream): Boolean;
  begin
    with Stream do
      Result := Position = Size;
  end; {EndOfStream}

var
  fs: TFileStream;
  ms: TMemoryStream;
  s: string;
  i, j: Byte;
begin
  fs := TFileStream.Create(FileName, fmCreate or fmShareExclusive);
  try
    FData.Seek(0, 0);

    case Mode of
      dfmASCII:
        begin
          ms := TMemoryStream.Create;
          try
            s := FName + ' RCDATA' + #13#10 + '{';
            StreamLN(fs, s);

            ObjectTextToBinary(FData, ms);
            ms.Seek(0, 0);

            while not EndOfStream(ms) do
              begin
                s := '''';

                for i := 0 to 15 do
                  begin
                    if ms.Read(j, SizeOf(j)) = 0 then
                      Break;
                    s := Concat(s, Format('%2.2x', [j]));
                    if (i = 15) or EndOfStream(ms) then
                      s := Concat(s, '''')
                    else
                      s := Concat(s, ' ');
                  end;

                if EndOfStream(ms) then
                  s := Concat(s, #13#10 + '}');
                StreamLN(fs, s);
              end;

          finally
            ms.Free;
          end;
        end;

      dfmBinary:
        ObjectTextToBinary(FData, fs);
    end;

  finally
    fs.Free;
  end;
end; {TDfm.SaveToFile}

procedure TDfm.SetName(const Value: string);
begin
  if FName <> Value then
    FName := Value;
end; {TDfm.SetName}

procedure TDfm.SetOwner(const Value: TResourceInfo);
begin
  FOwner := Value;
end; {TDfm.SetOwner}

end.

How can I declare it successfully?


回答1:


Appears to me that WinSock unit does not have an StreamLn function (as PowerSock's PSock.pas unit uses Winsock as imported unit).

The StreamLn function in PSock.pas just adds an CRLF sequence to the string passed as parameter before calling the TStream.WriteBuffer method of the passed TStream parameter.

Here's the google cache snapshot from the Powersock's source code of PSock.pas




回答2:


You need to either implement this function, or add a unit where this function is declared to your uses section.



来源:https://stackoverflow.com/questions/32788374/how-to-correctly-declare-streamln

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!