Solved

Gobal Application Wide Variable

Posted on 2004-09-29
5
293 Views
Last Modified: 2010-04-05
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.
0
Comment
Question by:SJohnson
  • 2
  • 2
5 Comments
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 125 total points
ID: 12186917
have a unit like uVersion.pas and in it this global variable
0
 
LVL 1

Author Comment

by:SJohnson
ID: 12186967
Cheers Lee!  You're a legend!
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12189393
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
 
LVL 1

Author Comment

by:SJohnson
ID: 12197577
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
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12212794
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

Featured Post

Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
QRReport  TQrmemo vertical stretching 1 46
Delphi: Connect to running MS Outlook 4 84
SUM 2 INTEGER ARRAYS INTO 1 10 100
How to convert memory stream to PDF file 6 55
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question