?
Solved

Gobal Application Wide Variable

Posted on 2004-09-29
5
Medium Priority
?
306 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 500 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

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

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

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses

762 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