Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | daniel-mar | 1 | { ## |
2 | @FILE PJVersionInfo.pas |
||
3 | @COMMENTS Version Information Component (32 bit) source code |
||
4 | (development split from 16 bit version after v1.0). |
||
5 | @PROJECT_NAME Version Information Component |
||
6 | @PROJECT_DESC Component that reads version information from files. |
||
7 | @OTHER_NAMES + Original unit name was VerInfo.pas |
||
8 | + Changed to VInfo.pas at v2.1 |
||
9 | + Changed to PJVersionInfo.pas at v3.0 |
||
10 | @AUTHOR Peter Johnson, LLANARTH, Ceredigion, Wales, UK |
||
11 | @EMAIL peter.johnson@openlink.org |
||
12 | @WEBSITE http://www.pjsoft.contactbox.co.uk/ |
||
13 | @COPYRIGHT © 1998-2002, Peter D Johnson. |
||
14 | @LEGAL_NOTICE This component is placed in the public domain. It |
||
15 | may be freely copied and circulated on a not for |
||
16 | profit basis providing that the code is unmodified |
||
17 | and this notice and information about the author and |
||
18 | his copyright remains attached to the source code. |
||
19 | @CREDITS In producing this component some techniques were |
||
20 | used which were learned from FVersion by PJ Veger, |
||
21 | Best, The Netherlands (Feb/96). In particular the |
||
22 | method of accessing language and char-set tables was |
||
23 | taken from PJ Veger's code. |
||
24 | @HISTORY( |
||
25 | @REVISION( |
||
26 | @VERSION 1.0 |
||
27 | @DATE 25/04/1998 |
||
28 | @COMMENTS Original version - 16 bit only. |
||
29 | ) |
||
30 | @REVISION( |
||
31 | @VERSION 2.0 |
||
32 | @DATE 06/12/1998 |
||
33 | @COMMENTS Revised for use with 32 bit Windows. Not compatible |
||
34 | with v1. |
||
35 | ) |
||
36 | @REVISION( |
||
37 | @VERSION 2.0.1 |
||
38 | @DATE 09/04/1999 |
||
39 | @COMMENTS Changed installation palette from "Own" to "PJ |
||
40 | Stuff". |
||
41 | ) |
||
42 | @REVISION( |
||
43 | @VERSION 2.1 |
||
44 | @DATE 28/11/1999 |
||
45 | @COMMENTS + Changed unit name to VInfo from VerInfo to allow |
||
46 | component to install under Delphi 3 & 4 (VerInfo |
||
47 | clashes with an existing unit in these versions). |
||
48 | + Removed superfluous conditional compilation |
||
49 | directives. |
||
50 | ) |
||
51 | @REVISION( |
||
52 | @VERSION 3.0 |
||
53 | @DATE 17/02/2002 |
||
54 | @COMMENTS Major update: |
||
55 | + Added ability to access all "translations" stored |
||
56 | in a file's version information, rather than just |
||
57 | first one. This has been done so that code using |
||
58 | earlier versions of this component should continue |
||
59 | to work unchanged. |
||
60 | + Added new property to expose fixed file |
||
61 | information record. |
||
62 | + Added new "string array" property to give access |
||
63 | to string information by name: this property can |
||
64 | access any custom string information if the name |
||
65 | is known. |
||
66 | + Added properties to return number of |
||
67 | "translations" and to select index of |
||
68 | "translation" to be used. |
||
69 | + Added properites to return language and character |
||
70 | set codes in addition to descriptive strings. |
||
71 | + All string info, language and character set |
||
72 | properties now return values from the currently |
||
73 | selected translation (which defaults to the first |
||
74 | translation maintaining backward compatibilty). |
||
75 | + Empty file name string now accesses name of host |
||
76 | application per command line rather than using |
||
77 | Application.ExeName. This enables this code to |
||
78 | work correctly even if user changes name of |
||
79 | executable file. |
||
80 | + CharSet property now returns '' for unknown value |
||
81 | rather than 'Unknown' |
||
82 | + Renamed unit to PJVersionInfo from VInfo. |
||
83 | + Renamed TVersionNumber record to TPJVersionNumber |
||
84 | + Replaced Tvs_FixedFileInfo record with use of |
||
85 | Windows unit defined type TVSFixedFileInfo. |
||
86 | + Changed component palette from PJ Stuff to PJSoft |
||
87 | ) |
||
88 | ) |
||
89 | } |
||
90 | |||
91 | |||
92 | unit PJVersionInfo; |
||
93 | |||
94 | interface |
||
95 | |||
96 | uses |
||
97 | // Delphi |
||
98 | Windows, Classes; |
||
99 | |||
100 | type |
||
101 | |||
102 | { |
||
103 | TPJVersionNumber: |
||
104 | Record holding version numbers. |
||
105 | } |
||
106 | TPJVersionNumber = record |
||
107 | V1, V2, V3, V4: WORD; |
||
108 | end; |
||
109 | |||
110 | { |
||
111 | TPJVersionInfo: |
||
112 | Component that exposes the version information embedded in an executable |
||
113 | file and exposed the detail as properties. |
||
114 | } |
||
115 | TPJVersionInfo = class(TComponent) |
||
116 | private // properties |
||
117 | fFileName: string; |
||
118 | fHaveInfo: Boolean; |
||
119 | fNumTranslations: Integer; |
||
120 | fCurrentTranslation: Integer; |
||
121 | fFixedFileInfo: TVSFixedFileInfo; |
||
122 | procedure SetFileName(AName: string); |
||
123 | function GetProductVersionNumber: TPJVersionNumber; |
||
124 | function GetFileVersionNumber: TPJVersionNumber; |
||
125 | function GetLanguage: string; |
||
126 | function GetCharSet: string; |
||
127 | function GetCharSetCode: WORD; |
||
128 | function GetLanguageCode: WORD; |
||
129 | function GetCurrentTranslation: Integer; |
||
130 | procedure SetCurrentTranslation(const Value: Integer); |
||
131 | function GetStringFileInfo(const Name: string): string; |
||
132 | function GetStringFileInfoByIdx(Index: Integer): string; |
||
133 | private |
||
134 | fPInfoBuffer: PChar; |
||
135 | {Pointer to info buffer} |
||
136 | fPTransBuffer: Pointer; |
||
137 | {Pointer to translation buffer} |
||
138 | procedure GetInfoBuffer(Len: DWORD); |
||
139 | {Creates an info buffer of required size} |
||
140 | procedure GetTransBuffer(Len: UINT); |
||
141 | {Creates a translation table buffer of required size} |
||
142 | function GetTransStr: string; |
||
143 | {Translation info encoded in string: takes into account current |
||
144 | translation} |
||
145 | protected |
||
146 | procedure ClearProperties; virtual; |
||
147 | {Forces properties to return cleared values} |
||
148 | procedure ReadVersionInfo; virtual; |
||
149 | {Reads version info from file} |
||
150 | public |
||
151 | constructor Create(AOwner: TComponent); override; |
||
152 | {Class constructor: sets default values} |
||
153 | destructor Destroy; override; |
||
154 | {Class destructor: frees allocated memory} |
||
155 | {Properties} |
||
156 | property HaveInfo: Boolean |
||
157 | read fHaveInfo; |
||
158 | {Property true if file version info for the file per FileName property has |
||
159 | been successfully read} |
||
160 | property FixedFileInfo: TVSFixedFileInfo |
||
161 | read fFixedFileInfo; |
||
162 | {Exposes the whole fixed file info record: following properties expose |
||
163 | the various fields of it} |
||
164 | property FileVersionNumber: TPJVersionNumber read |
||
165 | GetFileVersionNumber; |
||
166 | {Version number of file, in numeric format, from fixed file info} |
||
167 | property ProductVersionNumber: TPJVersionNumber |
||
168 | read GetProductVersionNumber; |
||
169 | {Version number of product, in numeric format, from fixed file info} |
||
170 | property FileOS: DWORD |
||
171 | read fFixedFileInfo.dwFileOS; |
||
172 | {Code describing operating system to be used by file} |
||
173 | property FileType: DWORD |
||
174 | read fFixedFileInfo.dwFileType; |
||
175 | {Code descibing type of file} |
||
176 | property FileSubType: DWORD |
||
177 | read fFixedFileInfo.dwFileSubType; |
||
178 | {Code describing sub-type of file - only used for certain values of |
||
179 | FileType property} |
||
180 | property FileFlagsMask: DWORD |
||
181 | read fFixedFileInfo.dwFileFlagsMask; |
||
182 | {Code describing which FileFlags are valid} |
||
183 | property FileFlags: DWORD |
||
184 | read fFixedFileInfo.dwFileFlags; |
||
185 | {Flags describing file state} |
||
186 | property Comments: string index 0 |
||
187 | read GetStringFileInfoByIdx; |
||
188 | {String file info property giving user defined comments for current |
||
189 | translation} |
||
190 | property CompanyName: string index 1 |
||
191 | read GetStringFileInfoByIdx; |
||
192 | {String file info property giving name of company for current translation} |
||
193 | property FileDescription: string index 2 |
||
194 | read GetStringFileInfoByIdx; |
||
195 | {String file info property giving description of file for current |
||
196 | translation} |
||
197 | property FileVersion: string index 3 |
||
198 | read GetStringFileInfoByIdx; |
||
199 | {String file info property giving version number of file in string format |
||
200 | for current translation} |
||
201 | property InternalName: string index 4 |
||
202 | read GetStringFileInfoByIdx; |
||
203 | {String file info property giving internal name of file for current |
||
204 | translation} |
||
205 | property LegalCopyright: string index 5 |
||
206 | read GetStringFileInfoByIdx; |
||
207 | {String file info property giving copyright message for current |
||
208 | translation} |
||
209 | property LegalTrademarks: string index 6 |
||
210 | read GetStringFileInfoByIdx; |
||
211 | {String file info property giving trademark info for current translation} |
||
212 | property OriginalFileName: string index 7 |
||
213 | read GetStringFileInfoByIdx; |
||
214 | {String file info property giving original name of file for current |
||
215 | translation} |
||
216 | property PrivateBuild: string index 8 |
||
217 | read GetStringFileInfoByIdx; |
||
218 | {String file info property giving information about a private build of |
||
219 | file for current translation} |
||
220 | property ProductName: string index 9 |
||
221 | read GetStringFileInfoByIdx; |
||
222 | {String file info property giving name of product for current translation} |
||
223 | property ProductVersion: string index 10 |
||
224 | read GetStringFileInfoByIdx; |
||
225 | {String file info property giving version number of product in string |
||
226 | format for current translation} |
||
227 | property SpecialBuild: string index 11 |
||
228 | read GetStringFileInfoByIdx; |
||
229 | {String file info property giving information about a special build of |
||
230 | file for current translation} |
||
231 | property StringFileInfo[const Name: string]: string |
||
232 | read GetStringFileInfo; |
||
233 | {Returns the value for string file info with given name for current |
||
234 | translation. This property can return both standard and custom string |
||
235 | info} |
||
236 | property Language: string |
||
237 | read GetLanguage; |
||
238 | {Name of language in use in current translation} |
||
239 | property CharSet: string |
||
240 | read GetCharSet; |
||
241 | {Name of character set in use in current translation} |
||
242 | property LanguageCode: WORD |
||
243 | read GetLanguageCode; |
||
244 | {Code of laguage in use in current translation} |
||
245 | property CharSetCode: WORD |
||
246 | read GetCharSetCode; |
||
247 | {Character set code in use in current translation} |
||
248 | property NumTranslations: Integer |
||
249 | read fNumTranslations; |
||
250 | {The number of difference translations (ie languages and char sets) in |
||
251 | the version information} |
||
252 | property CurrentTranslation: Integer |
||
253 | read GetCurrentTranslation write SetCurrentTranslation; |
||
254 | {Zero-based index of the current translation: this is 0 when a file is |
||
255 | first accessed. Set to a value in range 0..NumTranslations-1 to access |
||
256 | other translations. All string info, language and char set properties |
||
257 | return information for the current translation} |
||
258 | published |
||
259 | property FileName: string read fFileName write SetFileName; |
||
260 | {Name of file to which version information relates} |
||
261 | end; |
||
262 | |||
263 | procedure Register; |
||
264 | {Register this component} |
||
265 | |||
266 | implementation |
||
267 | |||
268 | uses |
||
269 | // Delphi |
||
270 | SysUtils; |
||
271 | |||
272 | { Component registration routine } |
||
273 | |||
274 | procedure Register; |
||
275 | {Register this component} |
||
276 | begin |
||
277 | RegisterComponents('PJSoft', [TPJVersionInfo]); |
||
278 | end; |
||
279 | |||
280 | { TPJVersionInfo } |
||
281 | |||
282 | type |
||
283 | { |
||
284 | TTransRec: |
||
285 | Record of language code and char set codes that are returned from version |
||
286 | information. |
||
287 | } |
||
288 | TTransRec = packed record // record to hold translation information |
||
289 | Lang, CharSet: Word; |
||
290 | end; |
||
291 | { |
||
292 | TTransRecs: |
||
293 | Type used to type cast translation data into an array of translation |
||
294 | records. |
||
295 | } |
||
296 | TTransRecs = array[0..1000] of TTransRec; |
||
297 | { |
||
298 | PTransRecs: |
||
299 | Pointer to an array of translation records. |
||
300 | } |
||
301 | PTransRecs = ^TTransRecs; |
||
302 | |||
303 | procedure TPJVersionInfo.ClearProperties; |
||
304 | {Forces properties to return cleared values} |
||
305 | begin |
||
306 | // Record that we haven't read ver info: this effectively clears properties |
||
307 | // since each property read access method checks this flag before returning |
||
308 | // result |
||
309 | fHaveInfo := False; |
||
310 | end; |
||
311 | |||
312 | constructor TPJVersionInfo.Create(AOwner: TComponent); |
||
313 | {Class constructor: sets default values} |
||
314 | begin |
||
315 | inherited Create(AOwner); |
||
316 | // Default is no file name - refers to executable file for application |
||
317 | FileName := ''; |
||
318 | end; |
||
319 | |||
320 | destructor TPJVersionInfo.Destroy; |
||
321 | {Class destructor: frees allocated memory} |
||
322 | begin |
||
323 | // Ensure that info buffer is freed if allocated |
||
324 | if fPInfoBuffer <> nil then |
||
325 | StrDispose(fPInfoBuffer); |
||
326 | // Ensure that translation buffer is free if allocated |
||
327 | if fPTransBuffer <> nil then |
||
328 | FreeMem(fPTransBuffer); |
||
329 | inherited Destroy; |
||
330 | end; |
||
331 | |||
332 | function TPJVersionInfo.GetCharSet: string; |
||
333 | {Read access method for CharSet property: return string describing character |
||
334 | set if we have some version info and empty string if we haven't} |
||
335 | const |
||
336 | // Map code numbers to char-set names |
||
337 | cCharSets: array[0..11] of record |
||
338 | Code: Word; // char set code |
||
339 | Str: string; // associated name of char set |
||
340 | end = ( |
||
341 | ( Code: 0; Str: '7-bit ASCII' ), |
||
342 | ( Code: 932; Str: 'Windows, Japan (Shift - JIS X-0208)'), |
||
343 | ( Code: 949; Str: 'Windows, Korea (Shift - KSC 5601)' ), |
||
344 | ( Code: 950; Str: 'Windows, Taiwan (GB5)' ), |
||
345 | ( Code: 1200; Str: 'Unicode' ), |
||
346 | ( Code: 1250; Str: 'Windows, Latin-2 (Eastern European)'), |
||
347 | ( Code: 1251; Str: 'Windows, Cyrillic' ), |
||
348 | ( Code: 1252; Str: 'Windows, Multilingual' ), |
||
349 | ( Code: 1253; Str: 'Windows, Greek' ), |
||
350 | ( Code: 1254; Str: 'Windows, Turkish' ), |
||
351 | ( Code: 1255; Str: 'Windows, Hebrew' ), |
||
352 | ( Code: 1256; Str: 'Windows, Arabic' ) |
||
353 | ); |
||
354 | var |
||
355 | I: Integer; // loop control |
||
356 | begin |
||
357 | Result := ''; |
||
358 | if fHaveInfo then |
||
359 | begin |
||
360 | // We've have ver info: scan table of codes looking for required entry |
||
361 | for I := Low(cCharSets) to High(cCharSets) do |
||
362 | if GetCharSetCode = cCharSets[I].Code then |
||
363 | begin |
||
364 | // found one - record its name |
||
365 | Result := cCharSets[I].Str; |
||
366 | Exit; |
||
367 | end; |
||
368 | end; |
||
369 | end; |
||
370 | |||
371 | function TPJVersionInfo.GetCharSetCode: WORD; |
||
372 | {Read access for CharSetCode property: returns char set code for current |
||
373 | translation or 0 if there is no translation or we have no version info} |
||
374 | begin |
||
375 | if fHaveInfo and (GetCurrentTranslation >= 0) then |
||
376 | Result := PTransRecs(fPTransBuffer)^[GetCurrentTranslation].CharSet |
||
377 | else |
||
378 | Result := 0; |
||
379 | end; |
||
380 | |||
381 | function TPJVersionInfo.GetCurrentTranslation: Integer; |
||
382 | {Read access method for CurrentTranslation property: returns index to current |
||
383 | translation if we have version info or -1 if no version info} |
||
384 | begin |
||
385 | if fHaveInfo then |
||
386 | Result := fCurrentTranslation |
||
387 | else |
||
388 | Result := -1; |
||
389 | end; |
||
390 | |||
391 | function TPJVersionInfo.GetFileVersionNumber: TPJVersionNumber; |
||
392 | {Read access method for FileVersionNumber property: fill version info |
||
393 | structure and return it - if there's no version info all values will be zero} |
||
394 | begin |
||
395 | Result.V1 := HiWord(fFixedFileInfo.dwFileVersionMS); |
||
396 | Result.V2 := LoWord(fFixedFileInfo.dwFileVersionMS); |
||
397 | Result.V3 := HiWord(fFixedFileInfo.dwFileVersionLS); |
||
398 | Result.V4 := LoWord(fFixedFileInfo.dwFileVersionLS); |
||
399 | end; |
||
400 | |||
401 | procedure TPJVersionInfo.GetInfoBuffer(Len: DWORD); |
||
402 | {Creates an info buffer of required size} |
||
403 | begin |
||
404 | // Clear any existing buffer |
||
405 | if fPInfoBuffer <> nil then |
||
406 | StrDispose(fPInfoBuffer); |
||
407 | // Create the new one |
||
408 | fPInfoBuffer := StrAlloc(Len); |
||
409 | end; |
||
410 | |||
411 | function TPJVersionInfo.GetLanguage: string; |
||
412 | {Read access method for Language property: return string describing language |
||
413 | if we have some version info and empty string if we haven't} |
||
414 | var |
||
415 | Buf: array[0..255] of char; // stores langauge string from API call |
||
416 | begin |
||
417 | // Assume failure |
||
418 | Result := ''; |
||
419 | // Try to get language name from Win API if we have ver info |
||
420 | if fHaveInfo and (VerLanguageName(GetLanguageCode, Buf, 255) > 0) then |
||
421 | Result := Buf; |
||
422 | end; |
||
423 | |||
424 | function TPJVersionInfo.GetLanguageCode: WORD; |
||
425 | {Read access for LanguageCode property: returns language code for current |
||
426 | translation or 0 if there is no translation or we have no version info} |
||
427 | begin |
||
428 | if fHaveInfo and (GetCurrentTranslation >= 0) then |
||
429 | Result := PTransRecs(fPTransBuffer)^[GetCurrentTranslation].Lang |
||
430 | else |
||
431 | Result := 0; |
||
432 | end; |
||
433 | |||
434 | function TPJVersionInfo.GetProductVersionNumber: TPJVersionNumber; |
||
435 | {Read access method for ProductVersionNumber property: fill version info |
||
436 | structure and return it - if there's no version info all values will be zero} |
||
437 | begin |
||
438 | Result.V1 := HiWord(fFixedFileInfo.dwProductVersionMS); |
||
439 | Result.V2 := LoWord(fFixedFileInfo.dwProductVersionMS); |
||
440 | Result.V3 := HiWord(fFixedFileInfo.dwProductVersionLS); |
||
441 | Result.V4 := LoWord(fFixedFileInfo.dwProductVersionLS); |
||
442 | end; |
||
443 | |||
444 | function TPJVersionInfo.GetStringFileInfo(const Name: string): string; |
||
445 | {Read access method for StringFileInfo array property: returns string |
||
446 | associated with given name or empty string if we have no version info} |
||
447 | var |
||
448 | CommandBuf: array[0..255] of char; // buffer to build API call command str |
||
449 | Ptr: Pointer; // pointer to result of API call |
||
450 | Len: UINT; // length of structure returned from API |
||
451 | begin |
||
452 | // Set default failure result to empty string |
||
453 | Result := ''; |
||
454 | // Check if we have valid information recorded in info buffer - exit if not |
||
455 | if fHaveInfo then |
||
456 | begin |
||
457 | // Build API call command string for reading string file info: |
||
458 | // this uses info string + language and character set |
||
459 | StrPCopy(CommandBuf, '\StringFileInfo\' + GetTransStr + '\' + Name); |
||
460 | // Call API to get required string and return it if successful |
||
461 | if VerQueryValue(fPInfoBuffer, CommandBuf, Ptr, Len) then |
||
462 | Result := PChar(Ptr); |
||
463 | end; |
||
464 | end; |
||
465 | |||
466 | function TPJVersionInfo.GetStringFileInfoByIdx(Index: Integer): string; |
||
467 | {Read access method for all string file info properties: returns appropriate |
||
468 | string for the given property or empty string if we have no version info} |
||
469 | const |
||
470 | cNames: array[0..11] of string = |
||
471 | ('Comments', 'CompanyName', 'FileDescription', 'FileVersion', |
||
472 | 'InternalName', 'LegalCopyright', 'LegalTrademarks', 'OriginalFileName', |
||
473 | 'PrivateBuild', 'ProductName', 'ProductVersion', 'SpecialBuild'); |
||
474 | {names of predefined string file info strings} |
||
475 | begin |
||
476 | Result := GetStringFileInfo(cNames[Index]); |
||
477 | end; |
||
478 | |||
479 | procedure TPJVersionInfo.GetTransBuffer(Len: UINT); |
||
480 | {Creates a translation table buffer of required size} |
||
481 | begin |
||
482 | // Clear any existing buffer |
||
483 | if fPTransBuffer <> nil then |
||
484 | FreeMem(fPTransBuffer); |
||
485 | // Create the new one |
||
486 | GetMem(fPTransBuffer, Len); |
||
487 | end; |
||
488 | |||
489 | function TPJVersionInfo.GetTransStr: string; |
||
490 | {Translation info encoded in string: takes into account current translation} |
||
491 | var |
||
492 | TransRec: TTransRec; // translation record in array of translations |
||
493 | begin |
||
494 | if GetCurrentTranslation >= 0 then |
||
495 | begin |
||
496 | // There is a valid current translation: return hex string related to it |
||
497 | TransRec := PTransRecs(fPTransBuffer)^[GetCurrentTranslation]; |
||
498 | Result := Format('%4.4x%4.4x', [TransRec.Lang, TransRec.CharSet]); |
||
499 | end |
||
500 | else |
||
501 | // No valid translation string: return empty string |
||
502 | Result := ''; |
||
503 | end; |
||
504 | |||
505 | procedure TPJVersionInfo.ReadVersionInfo; |
||
506 | {Reads version info from file} |
||
507 | var |
||
508 | Len: UINT; // length of structs returned from API calls |
||
509 | Ptr: Pointer; // points to version info structures |
||
510 | InfoSize: DWORD; // size of info buffer |
||
511 | Dummy: DWORD; // stores 0 in call to GetFileVersionInfoSize |
||
512 | begin |
||
513 | // Record default value of HaveInfo property - no info read |
||
514 | fHaveInfo := False; |
||
515 | // Store zeros in fixed file info structure: this is used when no info |
||
516 | FillChar(fFixedFileInfo, SizeOf(fFixedFileInfo), 0); |
||
517 | // Set NumTranslations property to 0: this is value if no info |
||
518 | fNumTranslations := 0; |
||
519 | // Record required size of version info buffer |
||
520 | InfoSize := GetFileVersionInfoSize(PChar(fFileName), Dummy); |
||
521 | // Check that there was no error |
||
522 | if InfoSize > 0 then |
||
523 | begin |
||
524 | // Found info size OK |
||
525 | // Ensure we have a sufficiently large buffer allocated |
||
526 | GetInfoBuffer(InfoSize); |
||
527 | // Read file version info into storage and check success |
||
528 | if GetFileVersionInfo(PChar(fFileName), Dummy, InfoSize, fPInfoBuffer) then |
||
529 | begin |
||
530 | // Success: we've read file version info to storage OK |
||
531 | fHaveInfo := True; |
||
532 | // Get fixed file info & copy to own storage |
||
533 | VerQueryValue(fPInfoBuffer, '\', Ptr, Len); |
||
534 | fFixedFileInfo := PVSFixedFileInfo(Ptr)^; |
||
535 | // Get first translation table info from API |
||
536 | VerQueryValue(fPInfoBuffer, '\VarFileInfo\Translation', Ptr, Len); |
||
537 | // Ptr is to block of translation records each of size Len: |
||
538 | // work out number of translations |
||
539 | fNumTranslations := Len div SizeOf(TTransRec); |
||
540 | // store translation array in a buffer |
||
541 | GetTransBuffer(Len); |
||
542 | Move(Ptr^, fPTransBuffer^, Len); |
||
543 | // make first translation in block current one (-1 if no translations) |
||
544 | SetCurrentTranslation(0); // adjusts value to -1 if no translations |
||
545 | end; |
||
546 | end; |
||
547 | end; |
||
548 | |||
549 | procedure TPJVersionInfo.SetCurrentTranslation(const Value: Integer); |
||
550 | {Write accees method for CurrentTranslation property: if value is out of |
||
551 | translation range then it is set to -1 to indicate no translation} |
||
552 | begin |
||
553 | if (Value >= 0) and (Value < NumTranslations) then |
||
554 | fCurrentTranslation := Value |
||
555 | else |
||
556 | fCurrentTranslation := -1 |
||
557 | end; |
||
558 | |||
559 | procedure TPJVersionInfo.SetFileName(AName: string); |
||
560 | {Write access method for FileName property: action at design time is different |
||
561 | to run time. At design time we simply record value while at run time we store |
||
562 | value - using actual name of program for '' string - and read the version |
||
563 | information} |
||
564 | begin |
||
565 | if csDesigning in ComponentState then |
||
566 | // We are designing, simply record the required name |
||
567 | fFileName := AName |
||
568 | else |
||
569 | begin |
||
570 | // It's run-time |
||
571 | // use Application exec file name if name is '' |
||
572 | if AName = '' then |
||
573 | fFileName := ParamStr(0) |
||
574 | else |
||
575 | fFileName := AName; |
||
576 | // clear all properties and read file version info for new file |
||
577 | ClearProperties; |
||
578 | ReadVersionInfo; |
||
579 | end; |
||
580 | end; |
||
581 | |||
582 | end. |