⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msgs.pas

📁 源代码
💻 PAS
字号:
unit Msgs;

{
  Inno Setup
  Copyright (C) 1997-2004 Jordan Russell
  Portions by Martijn Laan
  For conditions of distribution and use, see LICENSE.TXT.

  Message file handling functions

  $jrsoftware: issrc/Projects/Msgs.pas,v 1.10 2004/02/28 20:48:18 jr Exp $
}

interface

uses
  MsgIDs, Struct;

const
  SNewLine = #13#10;  { line break }
  SNewLine2 = #13#10#13#10;  { double line break }

var
  SetupMessages: array[TSetupMessageID] of String;
  UninstLangOptions: TUninstLangOptions;

function FmtMessage(S: PChar; const Args: array of String): String;
function FmtSetupMessage(const ID: TSetupMessageID; const Args: array of String): String;
function FmtSetupMessage1(const ID: TSetupMessageID; const Arg1: String): String;
procedure AssignSetupMessages(const P; const Size: Cardinal);
procedure LoadSetupMessagesAndOptions(const Filename: String; const Offset: Cardinal);
function IntToHexStr8(I: Integer): String;

const
  { You don't have to translate these. The only time they are used is when an
    error occurs before or while the messages file is loaded. Otherwise, it
    uses the corresponding messages in the messages file. }
  SSetupFileMissing = 'The file %1 is missing from the installation directory. ' +
    'Please correct the problem or obtain a new copy of the program.';
  SSetupFileCorrupt = 'The setup files are corrupted. Please obtain a new ' +
    'copy of the program.';
  SSetupFileCorruptOrWrongVer = 'The setup files are corrupted, or are ' +
    'incompatible with this version of Setup. Please correct the problem or ' +
    'obtain a new copy of the program.';
  SMsgsFileMissing = 'Messages file "%s" is missing. Please correct ' +
    'the problem or obtain a new copy of the program.';

implementation

uses
  Windows, SysUtils, Compress, CmnFunc2, FileClass;

const
  SMsgsFileTooLarge = 'Internal error: Messages file is too large';

function FmtMessage(S: PChar; const Args: array of String): String;
var
  P: PChar;
  Z: String;
begin
  Result := '';
  if S = nil then Exit;
  while True do begin
    P := StrScan(S, '%');
    if P = nil then begin
      Result := Result + S;
      Break;
    end;
    if P <> S then begin
      SetString(Z, S, P - S);
      Result := Result + Z;
      S := P;
    end;
    Inc(P);
    if (P^ >= '1') and (Ord(P^) <= Ord('1') + High(Args)) then begin
      Result := Result + Args[Ord(P^) - Ord('1')];
      Inc(S, 2);
    end
    else begin
      Result := Result + '%';
      Inc(S);
      if P^ = '%' then
        Inc(S);
    end;
  end;
end;

function FmtSetupMessage(const ID: TSetupMessageID; const Args: array of String): String;
begin
  Result := FmtMessage(PChar(SetupMessages[ID]), Args);
end;

function FmtSetupMessage1(const ID: TSetupMessageID; const Arg1: String): String;
begin
  Result := FmtSetupMessage(ID, [Arg1]);
end;

procedure FreeSetupMessages;
var
  I: TSetupMessageID;
begin
  for I := Low(SetupMessages) to High(SetupMessages) do
    SetupMessages[I] := '';
end;

procedure Corrupted;
begin
  raise Exception.Create(SSetupFileCorrupt);
end;

procedure AssignSetupMessages(const P; const Size: Cardinal);
{ Takes message data, and assigns the individual messages to SetupMessages. }
var
  Header: ^TMessagesHeader;
  M, EndP: PChar;
  I: TSetupMessageID;
  L: Integer;
begin
  if (Size <= SizeOf(TMessagesHdrID) + SizeOf(TMessagesHeader)) or
     (TMessagesHdrID(P) <> MessagesHdrID) then
    Corrupted;
  Cardinal(Header) := Cardinal(@P) + SizeOf(TMessagesHdrID);
  if (Header.TotalSize <> not Header.NotTotalSize) or
     (Cardinal(Header.TotalSize) <> Size) or
     (Header.NumMessages <> (Ord(High(SetupMessages)) - Ord(Low(SetupMessages)) + 1)) then
    Corrupted;
  Cardinal(M) := Cardinal(Header) + SizeOf(TMessagesHeader);
  Cardinal(EndP) := Cardinal(@P) + Cardinal(Header.TotalSize);
  if (GetCRC32(M^, EndP - M) <> Header.CRCMessages) or
     (EndP[-1] <> #0) then
    Corrupted;
  for I := Low(SetupMessages) to High(SetupMessages) do begin
    if M >= EndP then
      Corrupted;
    L := StrLen(M);
    SetString(SetupMessages[I], M, L);
    Inc(M, L + 1);
  end;
end;

procedure LoadSetupMessagesAndOptions(const Filename: String; const Offset: Cardinal);
{ Used by Uninst }
var
  F: TFile;
  TestID: TMessagesHdrID;
  Header: TMessagesHeader;
  P: Pointer;
begin
  FreeSetupMessages;
  if not NewFileExists(Filename) then
    raise Exception.CreateFmt(SMsgsFileMissing, [Filename]);
  F := TFile.Create(Filename, fdOpenExisting, faRead, fsRead);
  try
    F.Seek(Offset);
    if F.Read(TestID, SizeOf(TestID)) <> SizeOf(TestID) then
      Corrupted;
    if TestID <> MessagesHdrID then
      Corrupted;
    if F.Read(Header, SizeOf(Header)) <> SizeOf(Header) then
      Corrupted;
    if (Header.TotalSize <> not Header.NotTotalSize) or
       (Header.TotalSize <= SizeOf(TestID) + SizeOf(Header)) or
       (Header.NumMessages <> (Ord(High(SetupMessages)) - Ord(Low(SetupMessages)) + 1)) then
      Corrupted;

    F.Seek(Offset);
    GetMem(P, Header.TotalSize);
    try
      if F.Read(P^, Header.TotalSize) <> Header.TotalSize then
        Corrupted;
      AssignSetupMessages(P^, Header.TotalSize);
    finally
      FreeMem(P);
    end;

    if F.Read(UninstLangOptions, SizeOf(UninstLangOptions)) <> SizeOf(UninstLangOptions) then
      Corrupted;
    if UninstLangOptions.ID <> UninstLangOptionsID then
      Corrupted;
  finally
    F.Free;
  end;
end;

function IntToHexStr8(I: Integer): String;
begin
  FmtStr(Result, '0x%.8x', [I]);
end;

initialization
finalization
  FreeSetupMessages;
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -