Gobal Application Wide Variable

I have a variable in a projects DPR that I need access to from the main form.  This variable contains a build number assigned when a tagged build from CVS is done.  How do I get access to this variable, or, is there a better way of doing it?

Thanks,

Stuart.
LVL 1
SJohnsonAsked:
Who is Participating?
 
Lee_NoverCommented:
have a unit like uVersion.pas and in it this global variable
0
 
SJohnsonAuthor Commented:
Cheers Lee!  You're a legend!
0
 
Wim ten BrinkSelf-employed developerCommented:
Alternate solution for build numbers: create a version resource and store it in there...
Delphi is able to compile *.rc files into *.res files if you add the *.rc file to your project thus you could create a project1.rc file, put a version resource in it like this:
-----------------------------
LANGUAGE LANG_DUTCH,SUBLANG_DUTCH
PROJECT1 VERSIONINFO LOADONCALL MOVEABLE DISCARDABLE IMPURE
FILEVERSION 1, 0, 0, 1
PRODUCTVERSION 1, 0, 0, 1
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{ BLOCK "StringFileInfo"
  { BLOCK "041304E4"
    { VALUE "CompanyName", "\000"
      VALUE "FileDescription", "\000"
      VALUE "FileVersion", "5.0.0.129\000"
      VALUE "InternalName", "Project1\000"
      VALUE "LegalCopyright", "\000"
      VALUE "LegalTrademarks", "\000"
      VALUE "OriginalFilename", "\000"
      VALUE "ProductName", "\000"
      VALUE "ProductVersion", "1.0.0.1\000"
      VALUE "Comments", "\000"
    }
  }
  BLOCK "VarFileInfo" { VALUE "Translation", 1043, 1252 }
}
-----------------------------
And add this file to your project. Since it's just a text file, you can use notepad or the Delphi editor to open it, modify it and do whatever else you like to do with it.
From the menu, select "Project/Add to project" and just add the *.rc file... (Set 'File of Type' to *.rc)
0
 
SJohnsonAuthor Commented:
Hi Workshop Alex

The resource idea is a good one.  However, all we need is a single tag.  What I was thinking of doing is:

;Add String Table Defines

#define   BUILDTAG     1

;Add String Table

STRINGTABLE DISCARDABLE
BEGIN
    BUILDTAG     "$Name: $"
END

which works very nicely.  However, what we'd ideally like is something like:

BUILDTAG RC_STRING "$Name: $" (or something similar).

Is there any way of doing this?

Cheers.

Stu.
0
 
Wim ten BrinkSelf-employed developerCommented:
Just use:

PROJECT1 VERSIONINFO LOADONCALL MOVEABLE DISCARDABLE IMPURE
FILEVERSION 1, 0, 0, 1
PRODUCTVERSION 1, 0, 0, 1
{ }

As a result, there's a very small version resource now in your project. All it contains is a file version and project version. But if you want more information, you could use the version resource dialog that Delphi offers. It's a bit more useful.

What you actually want, i think, is to read this version information from your executable. Here's a unit that can help you to read it from your application:

unit untVersionInfo;
interface
uses SysUtils, Windows, Dialogs, Classes;
type
  { define a generic exception class for version info, and an exception to indicate that no version info is available. }
  EVerInfoError = class(Exception);
  ENoVerInfoError = class(Exception);
  eNoFixeVerInfo = class(Exception);
  // define enum type representing different types of version info
  TVerInfoType = (viCompanyName, viFileDescription, viFileVersion, viInternalName, viLegalCopyright, viLegalTrademarks, viOriginalFilename, viProductName, viProductVersion, viComments);
const
  // define an array constant of strings representing the pre-defined version information keys.
  VerNameArray: array[TVerInfoType] of string[20] = ('CompanyName', 'FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright', 'LegalTrademarks', 'OriginalFilename', 'ProductName', 'ProductVersion', 'Comments');
type
  TS_VerLangCharSet = record
    Lang: Word;
    CharSet: Word;
  end;
  PS_VerTranslationTable = ^TS_VerTranslationTable;
  TS_VerTranslationTable = array[0..MaxListSize] of TS_VerLangCharSet;
  TVerInfoResource = class
  private
    Handle: DWord;
    Size: Integer;
    RezBuffer: string;
    FTransTable: PInteger;
    FixedFileInfoBuf: PVSFixedFileInfo;
    FFileFlags: TStringList;
    FFileName: TFilename;
    FSucces: Boolean;
    FVerError: string;
    FTransCount: Integer;
    function GetFileType: string;
    function GetTranslations(Index: Integer): string;
  protected
    function GetFileVersion: string;
    function GetProductVersion: string;
    function GetFileOS: string;
  public
    constructor Create(AFileName: TFilename);
    destructor Destroy; override;
    function GetPreDefKeyString(AVerKind: TVerInfoType): string;
    function GetUserDefKeyString(AKey: string): string;
    property Filename: TFilename read FFilename;
    property Succes: Boolean read FSucces;
    property VerError: string read FVerError;
    property FileVersion: string read GetFileVersion;
    property ProductVersion: string read GetProductVersion;
    property FileOS: string read GetFileOS;
    property FileType: string read GetFileType;
    property FileFlags: TStringList read FFileFlags;
    property TransCount: Integer read FTransCount;
    property Translations[Index: Integer]: string read GetTranslations;
  end;
implementation
const
  // strings that must be fed to VerQueryValue() function
  SFInfo = '\StringFileInfo\';
  VerTranslation: PChar = '\VarFileInfo\Translation';
  FormatStr = '%s%.4x%.4x\%s%s';
constructor TVerInfoResource.Create(AFileName: TFilename);
var
  SBSize: UInt;
  ASize: Cardinal;
begin
  FSucces := True;
  FVerError := '';
  FFileName := aFileName;
  FFileFlags := TStringList.Create;
  try
    Size := GetFileVersionInfoSize(PChar(FFileName), Handle);
    if (Size <= 0) then raise ENoVerInfoError.Create('No Version Info Available.');
    SetLength(RezBuffer, Size);
    if not GetFileVersionInfo(PChar(FFileName), Handle, Size, PChar(RezBuffer)) then raise EVerInfoError.Create('Cannot obtain version info.');
    if not VerQueryValue(PChar(RezBuffer), VerTranslation, pointer(FTransTable), SBSize) then raise EVerInfoError.Create('No language info.');
    FTransCount := SBSize div SizeOf(TS_VerLangCharSet);
    if VerQueryValue(PChar(RezBuffer), '\', Pointer(FixedFileInfoBuf), ASize) then begin
      if (ASize < SizeOf(TVSFixedFileInfo)) then raise eNoFixeVerInfo.Create('No fixed file info');
    end
    else begin
      raise eNoFixeVerInfo.Create('No fixed file info');
    end;
    with FixedFileInfoBuf^ do begin
      if (dwFileFlagsMask and dwFileFlags and VS_FF_PRERELEASE) <> 0 then FFileFlags.Add('Pre-release');
      if (dwFileFlagsMask and dwFileFlags and VS_FF_PRIVATEBUILD) <> 0 then FFileFlags.Add('Private build');
      if (dwFileFlagsMask and dwFileFlags and VS_FF_SPECIALBUILD) <> 0 then FFileFlags.Add('Special build');
      if (dwFileFlagsMask and dwFileFlags and VS_FF_DEBUG) <> 0 then FFileFlags.Add('Debug');
    end;
  except
    on E: Exception do begin
      FSucces := False;
      FVerError := E.Message;
    end;
  end;
end;
destructor TVerInfoResource.Destroy;
begin
  FFileFlags.Free;
end;
function TVerInfoResource.GetPreDefKeyString(AVerKind: TVerInfoType): string;
var
  P: PChar;
  S: UInt;
begin
  Result := Format(FormatStr, [SfInfo, LoWord(FTransTable^), HiWord(FTransTable^), VerNameArray[aVerKind], #0]);
  if VerQueryValue(PChar(RezBuffer), @Result[1], Pointer(P), S) then begin
    Result := StrPas(P);
  end
  else begin
    Result := '';
  end;
end;
function TVerInfoResource.GetUserDefKeyString(AKey: string): string;
var
  P: Pchar;
  S: UInt;
begin
  Result := Format(FormatStr, [SfInfo, LoWord(FTransTable^), HiWord(FTransTable^), aKey, #0]);
  if VerQueryValue(PChar(RezBuffer), @Result[1], Pointer(P), S) then begin
    Result := StrPas(P);
  end
  else begin
    Result := '';
  end;
end;
function VersionString(Ms, Ls: Longint): string;
begin
  Result := Format('%d.%d.%d.%d', [HIWORD(Ms), LOWORD(Ms), HIWORD(Ls), LOWORD(Ls)]);
end;
function TVerInfoResource.GetFileVersion: string;
begin
  with FixedFileInfoBuf^ do begin
    Result := VersionString(dwFileVersionMS, dwFileVersionLS);
  end;
end;
function TVerInfoResource.GetProductVersion: string;
begin
  with FixedFileInfoBuf^ do begin
    Result := VersionString(dwProductVersionMS, dwProductVersionLS);
  end;
end;
function TVerInfoResource.GetFileOS: string;
begin
  with FixedFileInfoBuf^ do begin
    case dwFileOS of
      VOS_UNKNOWN: Result := 'Unknown';
      VOS_DOS: Result := 'Designed for MS-DOS';
      VOS_OS216: Result := 'Designed for 16-bit OS/2';
      VOS_OS232: Result := 'Designed for 32-bit OS/2';
      VOS_NT: Result := 'Designed for Windows NT';
      VOS__WINDOWS16: Result := 'Designed for 16-bit Windows';
      VOS__PM16: Result := 'Designed for 16-bit PM';
      VOS__PM32: Result := 'Designed for 32-bit PM';
      VOS__WINDOWS32: Result := 'Designed for 32-bit Windows';
      VOS_DOS_WINDOWS16: Result := 'Designed for 16-bit Windows, running on MS-DOS';
      VOS_DOS_WINDOWS32: Result := 'Designed for Win32 API, running on MS-DOS';
      VOS_OS216_PM16: Result := 'Designed for 16-bit PM, running on 16-bit OS/2';
      VOS_OS232_PM32: Result := 'Designed for 32-bit PM, running on 32-bit OS/2';
      VOS_NT_WINDOWS32: Result := 'Designed for Win32 API, running on Windows/NT';
      else
        Result := 'Unknown';
    end;
  end;
end;
function TVerInfoResource.GetFileType: string;
begin
  with FixedFileInfoBuf^ do begin
    case dwFileType of
      VFT_UNKNOWN: Result := 'Unknown';
      VFT_APP: Result := 'application';
      VFT_DLL: Result := 'dynamic link library';
      VFT_DRV: Result := 'device driver';
      VFT_Font: Result := 'font';
      VFT_VxD: Result := 'virtual device';
      VFT_STATIC_LIB: Result := 'static-link library';
      else
        Result := 'strange filetype';
    end;
  end;
end;
function TVerInfoResource.GetTranslations(Index: Integer): string;
begin
  with PS_VerTranslationTable(FTransTable)[Index] do
    Result := Format('%4.4x%4.4x', [Lang, CharSet]);
end;
end.

But above code gives you a lot more than just version information, of course. Still, it is very useful if you want to display the build number in your application.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.