├── Src
├── VERSION
├── HTMLRes.rc
├── HTMLRes.dpr
├── HTMLRes.manifest
├── VHTMLRes.vi
├── UVerInfo.pas
├── UErrors.pas
├── Install.iss
├── UParams.pas
├── UMain.pas
├── HTMLRes.dproj
└── Vendor
│ └── PJVersionInfo.pas
├── Demo
├── arrow.gif
├── Demo.hmfst
├── Demo.utf8-hmfst
├── HTMLLib.dpr
├── page2.html
├── style.css
├── index.html
├── DemoReadMe.txt
└── HTMLLib.dproj
├── .gitignore
├── LICENSE.md
├── README.md
├── Docs
├── License.rtf
├── ReadMe.txt
├── UserGuide.md
├── PreSVNHistory.txt
└── MPL-2.0.txt
├── CHANGELOG.md
├── Deploy.bat
└── Build.md
/Src/VERSION:
--------------------------------------------------------------------------------
1 | release=1.3.1
2 | suffix=
3 | build=7
4 |
--------------------------------------------------------------------------------
/Demo/arrow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/delphidabbler/htmlres/HEAD/Demo/arrow.gif
--------------------------------------------------------------------------------
/Demo/Demo.hmfst:
--------------------------------------------------------------------------------
1 | # Files required for demo project
2 | index.html
3 | page2.html
4 | arrow.gif
5 | style.css
--------------------------------------------------------------------------------
/Demo/Demo.utf8-hmfst:
--------------------------------------------------------------------------------
1 | # Files required for demo project
2 | index.html
3 | page2.html
4 | arrow.gif
5 | style.css
--------------------------------------------------------------------------------
/Demo/HTMLLib.dpr:
--------------------------------------------------------------------------------
1 | library HTMLLib;
2 |
3 | uses
4 | Windows; // used to keep IDE happy
5 |
6 | {$R HTML.res}
7 |
8 | begin
9 | end.
10 |
--------------------------------------------------------------------------------
/Demo/page2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | HTMLRes Test: Page 2
5 |
6 |
7 |
8 | HTMLRes Test Page 2
9 | Click here to return to the main page.
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Demo/style.css:
--------------------------------------------------------------------------------
1 | /* Demo code style sheet */
2 |
3 | body {
4 | font-family: "Arial" sans-serif;
5 | font-size: 9pt;
6 | background-color: white;
7 | }
8 |
9 | h1 {
10 | font-size: 14pt;
11 | color: #666699;
12 | background-color: #FFFFCC;
13 | }
14 |
15 | p {
16 | font-size: 9pt;
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/Demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | HTMLRes Test: Index
5 |
6 |
7 |
8 | HTMLRes Test Home Page
9 |
This HTML file
10 | is used as a test for the "HTML Resourcer" program (HTMLRes).
11 | Click here for page 2.
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Src/HTMLRes.rc:
--------------------------------------------------------------------------------
1 | /*
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at https://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 2008-2021, Peter Johnson (gravatar.com/delphidabbler).
7 | *
8 | * Resource file for HTML Resource Compiler. Includes all required resources
9 | * except version information.
10 | */
11 |
12 |
13 | /* Manifest file */
14 | 1 24 "HTMLRes.manifest"
15 |
--------------------------------------------------------------------------------
/Demo/DemoReadMe.txt:
--------------------------------------------------------------------------------
1 | DELPHIDABBLER HTML RESOURCE COMPILER DEMO README
2 | ================================================================================
3 |
4 | For information about how to use the demo code see UserGuide.md installed with
5 | HTML Resource Compiler in the Docs sub-directory. Alternatively see
6 | https://github.com/delphidabbler/htmlres/blob/master/Docs/UserGuide.md
7 |
8 | All the files in the HTML Resource Compiler's Demo folder (and only the Demo
9 | folder) have any copyright dedicated to the Public Domain. See
10 | https://creativecommons.org/publicdomain/zero/1.0/
11 |
12 | The demo code is provided as-is with all faults. Use the code at your own risk.
13 | The author makes no warranty of any kind as to the suitability of the code for
14 | any purpose and accepts no liability for any damages caused in using the code.
15 |
16 | --------------------------------------------------------------------------------
17 |
18 |
--------------------------------------------------------------------------------
/Src/HTMLRes.dpr:
--------------------------------------------------------------------------------
1 | {
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at https://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 2004-2021, Peter Johnson (gravatar.com/delphidabbler).
7 | *
8 | * Project file for HTML Resource Compiler.
9 | }
10 |
11 |
12 | program HTMLRes;
13 |
14 |
15 | {$APPTYPE CONSOLE} // this is a console application
16 |
17 | {$RESOURCE VHTMLRes.res} // version information
18 |
19 |
20 | uses
21 | UErrors in 'UErrors.pas',
22 | UMain in 'UMain.pas',
23 | UParams in 'UParams.pas',
24 | UVerInfo in 'UVerInfo.pas',
25 | PJResFile in 'Vendor\PJResFile.pas',
26 | PJVersionInfo in 'Vendor\PJVersionInfo.pas';
27 |
28 | begin
29 | // TMain provides main functionality and swallows any exceptions
30 | with TMain.Create do
31 | try
32 | Execute;
33 | finally
34 | Free;
35 | end;
36 | end.
37 |
38 |
--------------------------------------------------------------------------------
/Src/HTMLRes.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Src/VHTMLRes.vi:
--------------------------------------------------------------------------------
1 | ; ------------------------------------------------------------------------------
2 | ; This Source Code Form is subject to the terms of the Mozilla Public License,
3 | ; v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | ; obtain one at https://mozilla.org/MPL/2.0/
5 | ;
6 | ; Copyright (C) 2004-2024, Peter Johnson (gravatar.com/delphidabbler).
7 | ;
8 | ; Version information description file used to create VHTMLRes.res resource
9 | ; file.
10 | ; ------------------------------------------------------------------------------
11 |
12 | [Macros]
13 | Import:version=VERSION
14 |
15 | [Fixed File Info]
16 | File Version #=<%version.release>.<%version.build>
17 | Product Version #=<%version.release>
18 | File Sub-Type=0
19 | File OS=4
20 | File Type=1
21 | File Flags=0
22 | File Flags Mask=0
23 |
24 | [Variable File Info]
25 | Character Set=1252
26 | Language=2057
27 |
28 | [String File Info]
29 | File Description=HTML Resource Compiler.
30 | Product Version=<#P1>.<#P2>.<#P3><%version.suffix>
31 | Comments=
32 | Legal Copyright=Copyright © 2004- P D Johnson (https://delphidabbler.com).
33 | Internal Name=
34 | Company Name=DelphiDabbler
35 | Original File Name=HTMLRes.exe
36 | Private Build=
37 | Product Name=DelphiDabbler HTML Resource Compiler.
38 | Special Build=
39 | Legal Trademark=
40 | File Version=v<#F1>.<#F2>.<#F3> build <#F4>
41 |
42 | [Configuration Details]
43 | ResOutputDir=
44 | NumRCComments=0
45 | Identifier=VERINFO
46 | FileVersion=2
47 |
--------------------------------------------------------------------------------
/Src/UVerInfo.pas:
--------------------------------------------------------------------------------
1 | {
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at https://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 2008-2024, Peter Johnson (gravatar.com/delphidabbler).
7 | *
8 | * Provides routines that can return information from the program's version
9 | * information.
10 | }
11 |
12 |
13 | unit UVerInfo;
14 |
15 |
16 | interface
17 |
18 |
19 | function GetProductVersionStr: string;
20 | {Get program's product version number from version information resource.
21 | @return Version number as a dotted quad.
22 | }
23 |
24 | function GetCopyrightStr: string;
25 | {Gets program's copyright information from version informationr resource.
26 | @return Required copyright information.
27 | }
28 |
29 |
30 | implementation
31 |
32 |
33 | uses
34 | // Delphi
35 | System.SysUtils,
36 | // DelphiDabbler component
37 | PJVersionInfo;
38 |
39 |
40 | function GetProductVersionStr: string;
41 | {Get program's product version number from version information resource.
42 | @return Version number as a dotted quad.
43 | }
44 | begin
45 | with TPJVersionInfo.Create(nil) do
46 | try
47 | Result := Format(
48 | '%d.%d.%d',
49 | [
50 | ProductVersionNumber.V1,
51 | ProductVersionNumber.V2,
52 | ProductVersionNumber.V3
53 | ]
54 | );
55 | finally
56 | Free;
57 | end;
58 | end;
59 |
60 | function GetCopyrightStr: string;
61 | {Gets program's copyright information from version informationr resource.
62 | @return Required copyright information.
63 | }
64 | begin
65 | with TPJVersionInfo.Create(nil) do
66 | try
67 | Result := LegalCopyright;
68 | finally
69 | Free;
70 | end;
71 | end;
72 |
73 | end.
74 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Based on Delphi.gitignore from https://github.com/github/gitignore
2 | # MIT license Copyright (c) 2014 GitHub, Inc
3 |
4 | # Uncomment these types if you want even more clean repository. But be careful.
5 | # It can make harm to an existing project source. Read explanations below.
6 | #
7 | # Resource files are binaries containing manifest, project icon and version info.
8 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
9 | *.res
10 | #
11 | # Type library file (binary). In old Delphi versions it should be stored.
12 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
13 | #*.tlb
14 | #
15 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
16 | # Uncomment this if you are not using diagrams or use newer Delphi version.
17 | *.ddp
18 | #
19 | # Visual LiveBindings file. Added in Delphi XE2.
20 | # Uncomment this if you are not using LiveBindings Designer.
21 | *.vlb
22 | #
23 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
24 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
25 | *.deployproj
26 | #
27 |
28 | # Delphi compiler-generated binaries (safe to delete)
29 | *.exe
30 | *.dll
31 | *.bpl
32 | *.bpi
33 | *.dcp
34 | *.so
35 | *.apk
36 | *.drc
37 | *.map
38 | *.dres
39 | *.rsm
40 | *.tds
41 |
42 | # Delphi autogenerated files (duplicated info)
43 | #*.cfg
44 | #*Resource.rc
45 |
46 | # Delphi local files (user-specific info)
47 | *.local
48 | *.identcache
49 | *.projdata
50 | *.tvsconfig
51 | *.dsk
52 |
53 | # Delphi history and backups
54 | __history/
55 | *.~*
56 |
57 | # Project specific files added by DelphiDabbler:
58 |
59 | # unit files
60 | *.dcu
61 |
62 | # project option files for Delphi 7
63 | # (we create them as required from .tplt files)
64 | *.dof
65 | *.cfg
66 | # Build directories (Exe not actually needed since it is covered by *.exe above
67 | _build
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # License
2 |
3 | _HTML Resource Compiler_ is copyright © 2004-2024 by [Peter D Johnson][1].
4 |
5 | ## Executable Program
6 |
7 | The executable program, `HTMLRes.exe`, is made available under the terms of the [Mozilla Public License v2.0][2].
8 |
9 | ## Source Code
10 |
11 | Source code is available from the [`delphidabbler/htmlres`][3] repository on GitHub.
12 |
13 | Most of the source code is licensed under the [Mozilla Public License v2.0][2]. Many files carry license information and a copyright statement. Those that do not have such information are copyright © 2024 by [Peter D Johnson][1].
14 |
15 | The full text of the Mozilla Public License can found in [`MPL-2.0.txt`][4].
16 |
17 | Exceptions are:
18 |
19 | * All files in the repository's `Demo` folder are public domain [CC0 1.0][5]. See `DemoReadme.txt` in the same folder for details.
20 | * `.gitignore` is covered by the [MIT license][6], copyright © 2014 GitHub, Inc.
21 |
22 | ## Documentation
23 |
24 | All documentation, with the exception of this file (`LICENSE.md`) and `Docs/License.rtf` is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License [(CC BY-SA 4.0)][7], copyright © 2024 by [Peter D Johnson][1].
25 |
26 | Sufficient attribution will be to note the copyright date, the name of the copyright holder and to provide a link to the GitHub repository at [https://github.com/delphidabbler/htmlres][3].
27 |
28 | Documentation files are files in the repository that have `.md`, `.txt` or `.rtf` extensions.
29 |
30 | This file and `Docs/License.rtf` must not be modified and must be redistributed as-is unless explicit permission of the copyright holder is given.
31 |
32 | ## Disclaimer & Limitation Of Liability
33 |
34 | The Disclaimer Of Warranty and Limitations Of Liability sections of the [Mozilla Public License v2.0][2] apply to this whole project.
35 |
36 | ## Governing Law
37 |
38 | The law of England and Wales applies to all licenses & disclaimers unless they specifically state otherwise. Where Welsh Law varies from English Law then Welsh Law takes precedence.
39 |
40 | [1]: https://gravatar.com/delphidabbler
41 | [2]: https://mozilla.org/MPL/2.0/
42 | [3]: https://github.com/delphidabbler/htmlres
43 | [4]: https://github.com/delphidabbler/htmlres/blob/master/Docs/MPL-2.0.txt
44 | [5]: https://creativecommons.org/publicdomain/zero/1.0/
45 | [6]: https://opensource.org/licenses/MIT
46 | [7]: https://creativecommons.org/licenses/by-sa/4.0/
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HTML Resource Compiler (htmlres)
2 |
3 | ## Scope
4 |
5 | This document relates to _HTMLRes_ v1.3.1 and later.
6 |
7 | ## Description
8 |
9 | _HTML Resource Compiler_ is a simple Windows command line application for creating or updating Windows 32 bit binary resource files that contain HTML code that can be displayed using Internet Explorer's `res://` protocol.
10 |
11 | > For details on how to use the protocol see the article [How to create and use HTML resource files](https://delphidabbler.com/articles/article-10).
12 |
13 | _HTMLRes_ takes a list of HTML and related support files and copies the content of each file into a separate HTML resource within a binary resource file. Each resource has the same name as the source file. This makes porting standard HTML files to embedded resources very easy – and it is something that the Embarcadero (née Borland) BRCC32 resource compiler won't allow!
14 |
15 | _HTMLRes_ is particularly useful for embedding HTML files in the executable file of programs that display information using the Microsoft web browser control. Including HTML files in the program's resources means that is is not necessary to distribute the HTML files separately.
16 |
17 | ## Source Code
18 |
19 | _HTMLRes_ is written in Object Pascal and targeted at Delphi 12.1. Other Delphi compilers may work but have not been tested.
20 |
21 | See `Build.md` in the repo root for information about how to build the program from code.
22 |
23 | Each release from v1.2.0 is has a tag in the form `vX.X.X` where `X.X.X` is the release version number.
24 |
25 | ## Releases
26 |
27 | Each release of _HTMLRes_ from v1.2.1 is available from the program's GitHub repository's [Releases section](https://github.com/delphidabbler/htmlres/releases).
28 |
29 | The program is distributed in a zip archive which contains two files:
30 |
31 | 1. `ReadMe.txt` -- contains an explanation about how to install the program
32 | 2. `HTMLRes-Setup-x.x.x.exe` (where `x.x.x` is the program's version number) -- the program's Windows installer.
33 |
34 | ### System Requirements
35 |
36 | _HTMLRes_ and its install program require Windows 7 SP1 or later.
37 |
38 | ## Documentation
39 |
40 | User guide: `Docs/UserGuide.md`.
41 |
42 | Installation notes etc.: `Docs/ReadMe.txt`.
43 |
44 | Change log: `CHANGELOG.md`.
45 |
46 | ## Bugs and Feature Requests
47 |
48 | An bug reports and feature requests via the [GitHub issue tracker](https://github.com/delphidabbler/htmlres/issues) please.
49 |
50 | ## License
51 |
52 | See `LICENSE.md` for details.
53 |
54 | ## A Little History
55 |
56 | Up to and including the release of v1.2.0, _HTMLRes_ was not under version control. Known changes up until then are logged in the file `PreSVNHistory.txt` in the `Docs` sub-directory.
57 |
58 | On 1st August 2009 the v1.2.0 development tree was moved into a Subversion repository. Some development work took place in that repo, but no releases were made from it.
59 |
60 | Finally, the Subversion repo was converted to Git on 18th February 2014 and the repo was made public on GitHub.
61 |
62 | Release 1.2.1 was the first release from the Git repo on 20th February 2014.
63 |
--------------------------------------------------------------------------------
/Src/UErrors.pas:
--------------------------------------------------------------------------------
1 | {
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at https://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 2004-2024, Peter Johnson (gravatar.com/delphidabbler).
7 | *
8 | * Implements a custom exception class that incorporates an error code number
9 | * that HTMLRes uses as its exit code. Defines error code constants.
10 | }
11 |
12 |
13 | unit UErrors;
14 |
15 |
16 | interface
17 |
18 |
19 | uses
20 | // Delphi
21 | System.SysUtils;
22 |
23 |
24 | const
25 | // Error codes used in EError exceptions.
26 | cErrCommandLine = 1; // command line error
27 | cErrMissingManifest = 2; // expected manifest file doesn't exist
28 | cErrMissingSourceFile = 3; // >=1 source files missing
29 | cErrDuplicateResource = 4; // >=1 duplicate file (resource) names
30 | cErrOutFileExists = 5; // output file exists (and can't be modified)
31 | cErrBadOutFile = 6; // output file is not a valid resource file
32 | cErrResourceExists = 7; // named resource already exists in res file
33 | cErrUnexpected = 255; // unexpected error
34 |
35 |
36 | type
37 |
38 | {
39 | EError:
40 | Exception class with associated error code that is used as program exit
41 | code.
42 | }
43 | EError = class(Exception)
44 | private
45 | fErrorCode: Integer;
46 | {Error code associated with the extension}
47 | public
48 | constructor Create(const Msg: string; const ErrCode: Integer);
49 | {Creates EError exception object containing message and associated error
50 | code.
51 | @param Msg [in] Error message.
52 | @param ErrCode [in] Error code of the exception.
53 | }
54 | constructor CreateFmt(const Fmt: string; const Args: array of const;
55 | const ErrCode: Integer);
56 | {Creates EError exception object containing message created from a format
57 | string and associated error code.
58 | @param Fmt [in] Message format string.
59 | @param Args [in] Arguments that replace placeholders in format string.
60 | @param ErrCode [in] Error code of the exception.
61 | }
62 | property ErrorCode: Integer read fErrorCode;
63 | {Error code associated with exception}
64 | end;
65 |
66 |
67 | implementation
68 |
69 |
70 | { EError }
71 |
72 | constructor EError.Create(const Msg: string; const ErrCode: Integer);
73 | {Creates EError exception object containing message and associated error code.
74 | @param Msg [in] Error message.
75 | @param ErrCode [in] Error code of the exception.
76 | }
77 | begin
78 | inherited Create(Msg);
79 | fErrorCode := ErrCode;
80 | end;
81 |
82 | constructor EError.CreateFmt(const Fmt: string; const Args: array of const;
83 | const ErrCode: Integer);
84 | {Creates EError exception object containing message created from a format
85 | string and associated error code.
86 | @param Fmt [in] Message format string.
87 | @param Args [in] Arguments that replace placeholders in format string.
88 | @param ErrCode [in] Error code of the exception.
89 | }
90 | begin
91 | Create(Format(Fmt, Args), ErrCode);
92 | end;
93 |
94 | end.
95 |
96 |
--------------------------------------------------------------------------------
/Docs/License.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deftab709{\fonttbl{\f0\fnil\fcharset0 Arial;}}
2 | {\colortbl ;\red0\green0\blue255;}
3 | {\*\generator Riched20 10.0.22621}\viewkind4\uc1
4 | \pard\sa180\b\fs28\lang9 License\par
5 | \b0\i\fs20 HTML Resource Compiler\i0 is copyright \'a9 2004-2024 by {{\field{\*\fldinst{HYPERLINK "https://gravatar.com/delphidabbler"}}{\fldrslt{\ul\cf1\cf1\ul Peter D Johnson}}}}\f0\fs20 .\par
6 | \b\fs24 Executable Program\par
7 | \b0\fs20 The executable program, HTMLRes.exe, is made available under the terms of the {{\field{\*\fldinst{HYPERLINK "https://mozilla.org/MPL/2.0/"}}{\fldrslt{\ul\cf1\cf1\ul Mozilla Public License v2.0}}}}\f0\fs20 .\par
8 | \b\fs24 Source Code\par
9 | \b0\fs20 Source code is available from the {{\field{\*\fldinst{HYPERLINK "https://github.com/delphidabbler/htmlres"}}{\fldrslt{\ul\cf1\cf1\ul delphidabbler/htmlres}}}}\f0\fs20 repository on GitHub.\par
10 | Most of the source code is licensed under the {{\field{\*\fldinst{HYPERLINK "https://mozilla.org/MPL/2.0/"}}{\fldrslt{\ul\cf1\cf1\ul Mozilla Public License v2.0}}}}\f0\fs20 . Many files carry license information and a copyright statement. Those that do not have such information are copyright \'a9 2024 by {{\field{\*\fldinst{HYPERLINK "https://gravatar.com/delphidabbler"}}{\fldrslt{\ul\cf1\cf1\ul Peter D Johnson}}}}\f0\fs20 .\par
11 | The full text of the Mozilla Public License can found in {{\field{\*\fldinst{HYPERLINK "https://github.com/delphidabbler/htmlres/blob/master/Docs/MPL-2.0.txt"}}{\fldrslt{\ul\cf1\cf1\ul MPL-2.0.txt}}}}\f0\fs20 .\par
12 | Exceptions are:\par
13 |
14 | \pard\fi-360\li360\tx360\bullet\tab All files in the repository's Demo folder are public domain {{\field{\*\fldinst{HYPERLINK "https://creativecommons.org/publicdomain/zero/1.0/"}}{\fldrslt{\ul\cf1\cf1\ul CC0 1.0}}}}\f0\fs20 . See DemoReadme.txt in the same folder for details.\line\par
15 |
16 | \pard\fi-360\li360\sa180\tx360\bullet\tab .gitignore is covered by the {{\field{\*\fldinst{HYPERLINK "https://opensource.org/licenses/MIT"}}{\fldrslt{\ul\cf1\cf1\ul MIT license}}}}\f0\fs20 , copyright \'a9 2014 GitHub, Inc.\par
17 |
18 | \pard\sa180\b\fs24 Documentation\par
19 | \b0\fs20 All documentation, with the exception of this file (Docs/License.rtf) and LICENSE.md are licensed under the Creative Commons Attribution-ShareAlike 4.0 International License {{\field{\*\fldinst{HYPERLINK "https://creativecommons.org/licenses/by-sa/4.0/"}}{\fldrslt{\ul\cf1\cf1\ul (CC BY-SA 4.0)}}}}\f0\fs20 , copyright \'a9 2024 by {{\field{\*\fldinst{HYPERLINK "https://gravatar.com/delphidabbler"}}{\fldrslt{\ul\cf1\cf1\ul Peter D Johnson}}}}\f0\fs20 .\par
20 | Sufficient attribution will be to note the copyright date, the name of the copyright holder and to provide a link to the GitHub repository at {{\field{\*\fldinst{HYPERLINK https://github.com/delphidabbler/htmlres }}{\fldrslt{https://github.com/delphidabbler/htmlres\ul0\cf0}}}}\f0\fs20 .\par
21 | Documentation files are files in the repository that have .md, .txt, or .rtf extensions.\par
22 | This file (Docs/License.rtf) and LICENSE.md must not be modified and must be redistributed as-is unless explicit permission of the copyright holder is given.\par
23 | \b\fs24 Disclaimer & Limitation Of Liability\par
24 | \b0\fs20 The Disclaimer Of Warranty and Limitations Of Liability sections of the {{\field{\*\fldinst{HYPERLINK "https://mozilla.org/MPL/2.0/"}}{\fldrslt{\ul\cf1\cf1\ul Mozilla Public License v2.0}}}}\f0\fs20 apply to this whole project.\par
25 | \b\fs24 Governing Law\par
26 | \b0\fs20 The law of England and Wales applies to all licenses & disclaimers unless they specifically state otherwise. Where Welsh Law varies from English Law then Welsh Law takes precedence.\par
27 | }
28 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | This is the change log for [DelphiDabbler HTML Resource Compiler][1].
4 |
5 | All notable changes to this project are documented in this file.
6 |
7 | This change log begins with v1.0.0. There were no pre-release v0.x.x releases. Releases are listed in reverse version number order.
8 |
9 | ## v1.3.1 - 2024-09-03
10 |
11 | + Changed to compile with Delphi 12.1 instead of Delphi XE [issue #16]. The were no functional changes other than:
12 | - The program will no longer run on Windows versions prior to Windows 7 SP1.
13 | - The product version information string was reformated to be compatible with the new automated release process.
14 | + Refactored the version information definition file to get data that changes at every release from a new `VERSION` file.
15 | + Completely revised the build and release process [issue #18]:
16 | - Added new `Deploy.bat` script to automate the release process.
17 | - Added ability to build all required resources from within the IDE.
18 | - Removed the redundant make and config file.
19 | + Documentation:
20 | - Updated re changes to the build and release process, including re-writing and replacing `Build.html` with `Build.md`.
21 | - Minor corrections and edits [including issue #14].
22 |
23 | ## v1.3.0 - 2021-10-16
24 |
25 | + Implemented a minimum of Unicode support:
26 | - Modified to enable compilation with a Unicode compatible compiler.
27 | - UTF-8 and UTF-16 encoded manifest files are now supported providing such files have a suitable BOM or prefix, otherwise the system default encoding is assumed:
28 | - `FE FF` for UTF-16 big endian;
29 | - `FF FE` for UTF-16 little endian;
30 | - `EF BB BF` for UTF-8.
31 | - A UTF-8 encoded manifest was added to the demo project.
32 | + Recompiled with Delphi XE and revised `Makefile` & `Build.html` accordingly.
33 | + Major overhaul and update of documentation, including:
34 | - User guide converted to Markdown - `UserGuide.md` replaces `UserGuide.pdf` and `UserGuide.odt`.
35 | - This change log converted from plain text to Markdown and renamed `CHANGELOG.md`.
36 | - Many URLs updated.
37 | + License extensively changed and simplified:
38 | - Executable program EULA greatly simplified: it now simply uses [MPL 2.0][3].
39 | - Source code that was [MPL 1.1][4] licensed changed to [MPL 2.0][3].
40 | - Documentation changed to [CC BY-SA 4.0][5].
41 | - Demos public domain dedication clarified by use of [CC-0][6] license.
42 |
43 | ## v1.2.1 - 2014-02-20
44 |
45 | + Fixed non-standard bullet characters in help screen.
46 | + Compiled against latest versions of PJResourceFile and PJVersionInfo library units.
47 | + Installer now requires Windows 2000 or later to run.
48 | + Minor correction to EULA.
49 | + Updated documentation.
50 |
51 | ## v1.2.0 - 2008-08-23
52 |
53 | + Added new -u command that enables resources to be inserted and updated in pre-existing resource files.
54 | + Replaced command line installer with a Windows GUI installer built with Inno Setup.
55 |
56 | ## v1.1.0 - 2006-05-29
57 |
58 | + Added new -r command that enables file names to be relative to directory containing manifest instead of program execution directory.
59 | + Changed message displayed when program starts.
60 | + Changed to new open source EULA for executable code (source still available under MPL).
61 |
62 | ## v1.0.1 - 2004-09-18
63 |
64 | + Rebuilt using [PJResFile][2] resource file library unit rather than custom resource file handling code.
65 | + Updated documentation, including new PAD file.
66 |
67 | ## v1.0.0 - 2004-06-26
68 |
69 | + Original version including demo code and documentation, licensed under Mozilla Public License v1.1.
70 |
71 | [1]: https://delphidabbler.com/software/htmlres
72 | [2]: https://delphidabbler.com/software/resfile
73 | [3]: https://mozilla.org/MPL/2.0/
74 | [4]: https://mozilla.org/MPL/1.1/
75 | [5]: https://creativecommons.org/licenses/by-sa/4.0/
76 | [6]: https://creativecommons.org/publicdomain/zero/1.0/
77 |
--------------------------------------------------------------------------------
/Demo/HTMLLib.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {D102C645-797E-407B-85E8-5DFA21B4DD5D}
4 | HTMLLib.dpr
5 | True
6 | Debug
7 | Win32
8 | Library
9 | None
10 | DCC32
11 | 12.3
12 |
13 |
14 | true
15 |
16 |
17 | true
18 | Base
19 | true
20 |
21 |
22 | true
23 | Base
24 | true
25 |
26 |
27 | false
28 | false
29 | WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)
30 | 00400000
31 | false
32 | true
33 | false
34 | false
35 |
36 |
37 | false
38 | RELEASE;$(DCC_Define)
39 | 0
40 | false
41 |
42 |
43 | DEBUG;$(DCC_Define)
44 | false
45 | true
46 |
47 |
48 |
49 | MainSource
50 |
51 |
52 | Cfg_2
53 | Base
54 |
55 |
56 | Base
57 |
58 |
59 | Cfg_1
60 | Base
61 |
62 |
63 |
64 |
65 |
66 | Delphi.Personality.12
67 | VCLApplication
68 |
69 |
70 |
71 | HTMLLib.dpr
72 |
73 |
74 | False
75 | False
76 | 1
77 | 0
78 | 0
79 | 0
80 | False
81 | False
82 | False
83 | False
84 | False
85 | 2057
86 | 1252
87 |
88 |
89 |
90 |
91 | 1.0.0.0
92 |
93 |
94 |
95 |
96 |
97 | 1.0.0.0
98 |
99 |
100 |
101 |
102 | True
103 |
104 |
105 | 12
106 |
107 |
108 |
--------------------------------------------------------------------------------
/Deploy.bat:
--------------------------------------------------------------------------------
1 | :: Deploy script for HTMLRes.
2 | ::
3 | :: This script compiles creates a setup file containing HTMLRes and places it
4 | :: in a zip file. Both the setup file and zip file are labelled with the release
5 | :: version number.
6 | ::
7 | :: This script has the following dependencies:
8 | ::
9 | :: 1) MSBuild & Delphi.
10 | :: 2) InfoZip's zip.exe. See https://delphidabbler.com/extras/info-zip
11 | :: 3) Inno Setup v5.6.1 or later Unicode version (not v6). See
12 | :: https://www.innosetup.com/
13 | :: 4) DelphiDabbler Version Information Editor v2.15.1 or later. See
14 | :: https://delphidabbler.com/software/vied
15 | :: 5) PowerShell.
16 | ::
17 | :: To use the script:
18 |
19 | :: 1) Start the Embarcadero RAD Studio Command Prompt to set the required
20 | :: environment variables for MSBuild.
21 | :: 2) Set the ZipRoot environment variable to the directory where zip.exe is
22 | :: installed.
23 | :: 3) Set the VIEdRoot environment variable to the directory where VIEd.exe is
24 | :: installed.
25 | :: 4) Set the InnoSetup environment variable to the directoty where Inno Setup
26 | :: is installed.
27 | :: 5) Change directory to that where this script is located.
28 | :: 6) Run the script by entering Deploy with no parameters
29 | ::
30 | :: The script does the following:
31 | ::
32 | :: 1) Builds the HTMLRes executable using MSBuild, Delphi and Version
33 | :: Information Editor
34 | :: 2) Uses PowerShell to extract the release version from version information
35 | :: embedded in the HTMLRes executable. This is used to set the version of
36 | :: the setup program and to name the setup program and zip file.
37 | :: 3) Builds the setup file using Inno Setup.
38 | :: 4) Creates the release zip file using Zip.exe.
39 |
40 |
41 | @echo off
42 |
43 | echo -------------------------
44 | echo Deploying HTMLRes Release
45 | echo -------------------------
46 |
47 | :: Check for required environment variables
48 |
49 | if "%ZipRoot%"=="" goto envvarerror
50 | if "%VIEdRoot%"=="" goto envvarerror
51 | if "%InnoSetup%"=="" goto envvarerror
52 |
53 | :: Set other variables that don't depend on version
54 |
55 | set ProjectName=HTMLRes
56 | set BuildRoot=.\_build
57 | set Win32ExeDir=%BuildRoot%\exe
58 | set Win32Exe=%ProjectName%
59 | set ReleaseDir=%BuildRoot%\release
60 | set TempDir=%ReleaseDir%\~temp
61 | set SrcDir=Src
62 | set DocsDir=Docs
63 | set DemoDir=Demo
64 | set ReadMeFile=%DocsDir%\README.txt
65 | set ISCC="%InnoSetup%\ISCC.exe"
66 |
67 | :: Make a clean directory structure
68 |
69 | if exist %BuildRoot% rmdir /S /Q %BuildRoot%
70 | mkdir %ReleaseDir%
71 | mkdir %TempDir%
72 |
73 | :: Build Pascal
74 |
75 | setlocal
76 |
77 | cd %SrcDir%
78 |
79 | echo.
80 | echo Building HTMLRes
81 | echo.
82 |
83 | msbuild %ProjectName%.dproj /p:config=Release /p:platform=Win32
84 |
85 | endlocal
86 |
87 | :: Get version and set variables that depend on version
88 |
89 | PowerShell(Get-Command %Win32ExeDir%\%Win32Exe%.exe).FileVersionInfo.ProductVersion > "%TempDir%\~version"
90 | set /p Version= < "%TempDir%\~version"
91 |
92 | set SetupFileName=HTMLRes-Setup-%Version%
93 | set ZipFile=%ReleaseDir%\htmlres-exe-%Version%.zip
94 |
95 | :: Split Version into prefix and suffix with "-" delimiter: suffix may be empty
96 |
97 | for /f "tokens=1,2 delims=-" %%a in ("%Version%") do (
98 | :: prefix and suffix required for Inno Setup
99 | set VersionPrefix=%%a
100 | set VersionSuffix=%%b
101 | )
102 | if not [%VersionSuffix%] == [] (
103 | :: add back "-" when suffix not empty
104 | set VersionSuffix=-%VersionSuffix%
105 | )
106 |
107 | :: Build Setup
108 |
109 | setlocal
110 |
111 | cd %SrcDir%
112 |
113 | echo.
114 | echo Building setup program for release v%Version%
115 | echo.
116 |
117 | %ISCC% /DAppShortName=%ProjectName% /DAppVersion=%VersionPrefix% /DAppVersionSuffix=%VersionSuffix% /DSetupOutDir=%TempDir% /DSetupFileName=%SetupFileName% /DExeInDir=%Win32ExeDir% /DDocsInDir=%DocsDir% /DDemoInDir=%DemoDir% Install.iss
118 |
119 | endlocal
120 |
121 | :: Create zip files
122 |
123 | echo.
124 | echo Creating zip files for release v%Version%
125 | echo.
126 |
127 | %ZipRoot%\zip.exe -j -9 %ZipFile% %TempDir%\%SetupFileName%.exe
128 | %ZipRoot%\zip.exe -j -9 %ZipFile% %ReadMeFile%
129 |
130 | :: Tidy up
131 |
132 | echo.
133 | echo Deleting temporary directory %TempDir%
134 | echo.
135 |
136 | if exist %TempDir% rmdir /S /Q %TempDir%
137 |
138 | :: Done
139 |
140 | echo.
141 | echo ---------------
142 | echo Build completed
143 | echo ---------------
144 |
145 | goto end
146 |
147 | :: Error messages
148 |
149 | :envvarerror
150 | echo.
151 | echo ***ERROR: ZipRoot, VIEdRoot or InnoSteup environment variable not set
152 | echo.
153 | goto end
154 |
155 | :: End
156 |
157 | :end
158 |
--------------------------------------------------------------------------------
/Docs/ReadMe.txt:
--------------------------------------------------------------------------------
1 | DELPHIDABBLER HTML RESOURCE COMPILER README
2 | ================================================================================
3 |
4 | Scope
5 | --------------------------------------------------------------------------------
6 |
7 | This document relates to HTMLRes v1.3.1 and later.
8 |
9 | What is HTML Resource Compiler?
10 | --------------------------------------------------------------------------------
11 |
12 | HTMLRes is a Windows command line program that is used to create resource files
13 | containing HTML files. Each resource is of type HTML (#23) and is named after
14 | the source file.
15 |
16 | System Requirements
17 | --------------------------------------------------------------------------------
18 |
19 | HTMLRes and its installer required Windows 7 SP1 and later.
20 |
21 | Installation
22 | --------------------------------------------------------------------------------
23 |
24 | When installing or uninstalling you need to ensure that you have administrator
25 | privileges otherwise the installation can fail. The system may prompt, if
26 | necessary, for an administrator password. It will also elevate the install
27 | process.
28 |
29 | If you have HTML Resource Compiler 1.1 or earlier you should uninstall it using
30 | the Windows setting app before installing this version. Uninstalling v1.1 wil
31 | leave two files, InstallLib.dll and UnInstall.exe behind in the installation
32 | folder. You should delete these files manually.
33 |
34 | The program is distributed in a zip archive which contains two files -
35 | ReadMe.txt (this file) and HTMLRes-Setup-x.x.x.exe, where x.x.x. is the
36 | program's version number. Extract both files from the archive.
37 |
38 | HTMLRes-Setup-x.x.x.exe is the installation program. Double-click
39 | HTMLRes-Setup-x.x.x.exe. The installer is a standard wizard style Windows
40 | installer. Follow the instructions in the wizard. You must accept the program's
41 | license to proceed. Once the license is accepted you can configure the
42 | installation directory and the program group name. Once the installation has
43 | completed you have the option to display the user guide and/or license.
44 |
45 | The installer installs the main program along with documentation and some
46 | demonstration code that illustrates how to use the compiler. The files, relative
47 | to the installation folder, are:
48 |
49 | HTMLRes.exe - the HTML resource compiler.
50 |
51 | Demo\ sub folder - contains the following demo files:
52 | arrow.gif - GIF file displayed on index.html.
53 | Demo.hmfst - manifest file listing all demo files to be compiled by HTMLRes.
54 | Demo.utf8-hmfst - UTF-8 version of Demo.hmfst.
55 | DemoReadMe.txt - ReadMe file for demo code. Please read before using the
56 | demo code.
57 | HTMLLib.dpr & HTMLLib.dproj - Delphi project files for a resource only DLL.
58 | index.html - main demo HTML page.
59 | page2.html - secondary demo HTML page.
60 | style.css - demo style sheet used by HTML pages.
61 |
62 | Docs\ sub folder - contains program documentation:
63 | CHANGELOG.md - the program's update history.
64 | License.txt - the program's license.
65 | ReadMe.txt - contains important install and other information.
66 | UserGuide.md - a guide to using the program and the demo code.
67 |
68 | Uninstall sub folder - contains files required by the uninstaller.
69 |
70 | Uninstalling
71 | --------------------------------------------------------------------------------
72 |
73 | Uninstall HTMLRes via Windows Control Panel / Setting app. Select DelphiDabbler
74 | Resource Compiler v1.x.x (where x.x is the minor version number) from the list
75 | of installed applications and click the Remove or Uninstall button. uninstall
76 | program will now check if you want to go ahead with the uninstallation. Accept
77 | this prompt to continue with uninstallation.
78 |
79 | The uninstaller deletes any registry entries that were created by the installer.
80 |
81 | User Guide
82 | --------------------------------------------------------------------------------
83 |
84 | See UserGuide.md in the installation's Docs sub folder for information on using
85 | the program and the demo code.
86 |
87 | Copyright and Licensing
88 | --------------------------------------------------------------------------------
89 |
90 | The program is copyright (c) 2004-2024, Peter D Johnson (@delphidabbler). See
91 | License.txt in the installation's Docs sub folder for licensing information.
92 |
93 | Source Code
94 | --------------------------------------------------------------------------------
95 |
96 | HTMLRes is open source. Much of the source code is licensed under the Mozilla
97 | Public License and other open source licenses. Demo code is public domain.
98 | You can get the source code of the latest release from
99 | https://delphidabbler.com/software/htmlres.
100 |
101 | Source code of versions back to v1.2.0 can also be obtained from GitHub. Visit
102 | https://github.com/delphidabbler/htmlres/releases then select the required
103 | release.
104 |
105 | Git users can check out the source code from
106 | https://github.com/delphidabbler/htmlres. Choose the required branch, or for
107 | the source code of stable releases, choose a tag in the form vX.X.X where X.X.X
108 | is the release version number.
109 |
110 | Source code licensing information is provided in the file LICENSE.md in the root
111 | of the source code tree.
112 |
113 | --------------------------------------------------------------------------------
114 |
--------------------------------------------------------------------------------
/Src/Install.iss:
--------------------------------------------------------------------------------
1 | ; ------------------------------------------------------------------------------
2 | ; This Source Code Form is subject to the terms of the Mozilla Public License,
3 | ; v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | ; obtain one at https://mozilla.org/MPL/2.0/
5 | ;
6 | ; Copyright (C) 2008-2024, Peter Johnson (gravatar.com/delphidabbler).
7 | ;
8 | ; HTML Resource Compiler install file generation script for use with Inno Setup.
9 | ;
10 | ; The following defines use these macros that are predefined by ISPP:
11 | ; SourcePath - path where this script is located
12 | ; GetStringFileInfo - gets requested version info string from an executable
13 | ;
14 | ; The following define, which must be defined on the command line using the
15 | ; /D option:
16 | ; AppShortName - short name of project. Exe file will be named by appending
17 | ; ".exe"
18 | ; AppVersion - version number of the application (must contain only digits,
19 | ; e.g. 1.2.3.4).
20 | ; AppVersionSuffix - any suffix to the application version number (must start)
21 | ; with "-" , e.g. "-beta.1"
22 | ; SetupOutDir - setup program output directory relative to project root
23 | ; SetupFileName - name of setup file to be created (without path)
24 | ; ExeInDir - directory containing compiled .exe file relative to project root
25 | ; DocsInDir - directory containing documentation relative to project root
26 | ; DemoInDir - directory containing demo files relative to project root
27 | ; ------------------------------------------------------------------------------
28 |
29 | #define AppPublisher "DelphiDabbler"
30 | #define AppName "HTML Resource Compiler"
31 | #define AppDir AppShortName
32 | #define ExeFile AppShortName + ".exe"
33 | #define ReadmeFile "ReadMe.txt"
34 | #define LicenseFile "License.rtf"
35 | #define LicenseTextFile "LICENSE.md"
36 | #define ChangeLogFile "CHANGELOG.md"
37 | #define UserGuide "UserGuide.md"
38 | #define InstDocsDir "Docs"
39 | #define InstUninstDir "Uninstall"
40 | #define InstDemoDir "Demo"
41 | #define OutDir SourcePath + "..\" + SetupOutDir
42 | #define RootPath SourcePath + "..\"
43 | #define SrcExePath SourcePath + "..\" + ExeInDir + "\"
44 | #define SrcDocsPath SourcePath + "..\" + DocsInDir + "\"
45 | #define SrcDemoPath SourcePath + "..\" + DemoInDir + "\"
46 | #define ExeProg SrcExePath + ExeFile
47 | #define Company "DelphiDabbler.com"
48 | #define Copyright GetStringFileInfo(ExeProg, LEGAL_COPYRIGHT)
49 | #define WebAddress "delphidabbler.com"
50 | #define WebURL "https://" + WebAddress + "/"
51 | #define AppURL WebURL + "software/htmlres"
52 |
53 | [Setup]
54 | AppID={{A9C1BCAB-8034-4271-AA8B-9C484FE0EEBC}
55 | AppName={#AppName}
56 | AppVersion={#AppVersion}
57 | AppVerName={#AppPublisher} {#AppName} {#AppVersion}
58 | AppPublisher={#AppPublisher}
59 | AppPublisherURL={#WebURL}
60 | AppSupportURL={#AppURL}
61 | AppUpdatesURL={#AppURL}
62 | AppReadmeFile={app}\{#InstDocsDir}\{#ReadmeFile}
63 | AppCopyright={#Copyright} ({#WebAddress})
64 | AppComments=
65 | AppContact=
66 | DefaultDirName={pf}\{#AppPublisher}\{#AppDir}
67 | DefaultGroupName={#AppPublisher} {#AppName}
68 | AllowNoIcons=true
69 | LicenseFile={#SrcDocsPath}{#LicenseFile}
70 | Compression=lzma/ultra
71 | SolidCompression=true
72 | InternalCompressLevel=ultra
73 | OutputDir={#OutDir}
74 | OutputBaseFilename={#SetupFileName}
75 | VersionInfoVersion={#AppVersion}
76 | VersionInfoTextVersion={#AppVersion}
77 | VersionInfoProductVersion={#AppVersion}
78 | VersionInfoProductTextVersion={#AppVersion}{#AppVersionSuffix}
79 | VersionInfoCompany={#Company}
80 | VersionInfoDescription=Installer for {#AppName}
81 | VersionInfoCopyright={#Copyright}
82 | MinVersion=6.1sp1
83 | TimeStampsInUTC=true
84 | ShowLanguageDialog=yes
85 | RestartIfNeededByRun=false
86 | PrivilegesRequired=admin
87 | UsePreviousAppDir=true
88 | UsePreviousGroup=true
89 | UsePreviousSetupType=false
90 | UsePreviousTasks=false
91 | UninstallFilesDir={app}\{#InstUninstDir}
92 | UpdateUninstallLogAppName=true
93 | UninstallDisplayIcon={app}\{#ExeFile}
94 | UserInfoPage=false
95 |
96 | [Dirs]
97 | Name: {app}\{#InstDocsDir}; Flags: uninsalwaysuninstall
98 | Name: {app}\{#InstUninstDir}; Flags: uninsalwaysuninstall
99 |
100 | [Files]
101 | ; Executable files
102 | Source: {#SrcExePath}{#ExeFile}; DestDir: {app}; Flags: uninsrestartdelete
103 | ; Documentation
104 | Source: {#RootPath}{#LicenseTextFile}; DestDir: {app}\{#InstDocsDir}; Flags: ignoreversion
105 | Source: {#SrcDocsPath}{#ReadmeFile}; DestDir: {app}\{#InstDocsDir}; Flags: ignoreversion
106 | Source: {#RootPath}{#ChangeLogFile}; DestDir: {app}\{#InstDocsDir}; Flags: ignoreversion
107 | Source: {#SrcDocsPath}{#UserGuide}; DestDir: {app}\{#InstDocsDir}; Flags: ignoreversion
108 | ; Demo
109 | Source: {#SrcDemoPath}*.*; DestDir: {app}\{#InstDemoDir}; Flags: ignoreversion
110 |
111 | [Icons]
112 | Name: {group}\{#AppName}; Filename: {app}\{#ExeFile}
113 | Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe}
114 |
115 | [Run]
116 | Filename: {app}\{#InstDocsDir}\{#UserGuide}; Description: "View the user guide ({app}\{#InstDocsDir}\{#UserGuide})"; Flags: nowait postinstall skipifsilent shellexec skipifsilent
117 | Filename: {app}\{#InstDocsDir}\{#LicenseTextFile}; Description: "View the license ({app}\{#InstDocsDir}\{#LicenseTextFile})"; Flags: nowait postinstall skipifsilent shellexec skipifsilent
118 |
119 | [Messages]
120 | ; Brand installer
121 | BeveledLabel={#Company}
122 |
123 |
--------------------------------------------------------------------------------
/Build.md:
--------------------------------------------------------------------------------
1 | # HTMLRes Build Instructions
2 |
3 | ## Introduction
4 |
5 | _HTMLRes_ is written in Object Pascal and is targeted at Delphi 12.1 and later.
6 |
7 | Development can take place entirely within the IDE providing some prerequisites are met. However releases must be built using the `Deploy.bat` script.
8 |
9 | > These notes apply only to the source code of release v1.3.1 and later.
10 |
11 | ## Prerequisites
12 |
13 | ### Tools
14 |
15 | The following tools are required to build _HTMLRes_.
16 |
17 | Tools marked with an asterisk are required when compiling from the IDE: compiles will fail if they are not installed and configured.
18 |
19 | | Tools | Notes |
20 | |-------|--------|
21 | | Delphi 12.1 | Later Delphi compilers should be suitable. Some earlier compilers may work but none have been tested. |
22 | | MSBuild | This tool is installed with Delphi. Used directly by `Deploy.bat` to build _HTMLRes_. |
23 | | BRCC32 * | This tool is installed with Delphi. Used in pre-build events to create `.res` files from custom `.rc` files. |
24 | | Version Information Editor * | v2.15.1 or later is required. Used in pre-build events create an `.rc` file containing version information from `.vi` files. [Download here](https://github.com/delphidabbler/vied/releases). |
25 | | Inno Setup | v5.6.1 or later Unicode version (not v6). Used by `Deploy.bat` to create the installer. [Download here](https://www.innosetup.com/). |
26 | | InfoZip's Zip tool | Used by `Deploy.bat` to create the release zip file. [Download here](https://delphidabbler.com/extras/info-zip). |
27 | | PowerShell | Used by `Deploy.bat` to grab version information from the compiled `.exe` file. |
28 |
29 | ### Environment Variables
30 |
31 | The following environment variables must be set to build _HTMLRes_
32 |
33 | Environment variables marked with an asterisk are required when compiling from the IDE: compiles will fail if they are not set correctly. Such variables can be set using Delphi's _Tools | Options_ menu, going to the _Environment Variables_ page then creating the variable in _User System Overrides_ section.
34 |
35 | All environment variables are required when creating releases using `Deploy.bat`.
36 |
37 | | Environment Variables | Notes |
38 | |-----------------------|-------|
39 | | MSBuild specific variables | The `rsvars.bat` script in the `Bin` sub-directory of the Delphi installation directory sets these variables to the required values. |
40 | | `ZipRoot` | Set this to the directory where the InfoZip Zip tool was installed. |
41 | | `VIEdRoot` * | Set this to the directory where Version Information Editor was installed (the `DelphiDabbler\VIEd` subdirectory of the 32 bit program files directory, by default). |
42 | | `InnoSetup` | Set this to the directory where the Unicode version of Inno Setup 5 was installed. |
43 |
44 | You can configure the environment using a batch file similar to the following:
45 |
46 | ```batch
47 | :: set path to Delphi 12 installation (change directory if not using Delphi 12)
48 | set DELPHIROOT=C:\Program Files (x86)\Embarcadero\Studio\23.0
49 |
50 | :: set environment variables required by MSBuild
51 | call "%DELPHIROOT%\Bin\rsvars.bat"
52 |
53 | :: set install path of tools (change as required)
54 | set ZipRoot=C:\Tools
55 | set VIEdRoot=C:\Program Files (x86)\DelphiDabbler\VIEd
56 | set InnoSetup=C:\Program Files (x86)\Inno Setup 5
57 | ```
58 |
59 | ## Source Code
60 |
61 | Download the _HTMLRes_ source code from the ['delphidabbler/htmlres'](https://github.com/delphidabbler/htmlres) GitHub repository. You can either clone it using Git or download a zip file containing the source.
62 |
63 | There are no source code dependencies other than the Delphi RTL/VCL.
64 |
65 | After obtaining the source code you should have the following directory structure:
66 |
67 |
68 | ```text
69 | /-+
70 | |
71 | +-- .git - present only if using git
72 | |
73 | +-- Demo - demonstration source code & support files
74 | |
75 | +-- Docs - documentation
76 | |
77 | +-- Src - source code
78 | |
79 | +-- Vendor - imported 3rd party source code
80 | ```
81 |
82 | Git users will also see the usual `.git` hidden directory.
83 |
84 | ## Compiling
85 |
86 | ### From The Delphi IDE
87 |
88 | Simply open the `.dproj` file in Delphi and compile. Providing the [Prerequisites](#prerequisites) have been met, the program should compile without problems.
89 |
90 | All compiler output is placed in a `_build` directory. This directory is ignored by Git. The following structure is used:
91 |
92 | ```text
93 | /-+
94 | |
95 | +-- .git - present only if using git
96 | |
97 | +-- _build
98 | | |
99 | | +-- bin - contains all binary intermediate files
100 | | |
101 | | +-- exe - contains the compiled exe file
102 | |
103 | +-- Demo - demonstration source code & support files
104 | ⁞
105 | ```
106 |
107 | You can now hack away as you wish.
108 |
109 | ### Creating A Release
110 |
111 | To create a release ensure that all the [Prerequisite Tools](#tools) have been installed. Then:
112 |
113 | 1. Open a terminal.
114 | 2. Run any configuration script you have created, or set the [environment variables](#environment-variables) manually.
115 | 3. Change directory into the root of the _HTMLRes_ source code.
116 | 4. Run `Deploy.bat` without any parameters.
117 |
118 | `Deploy.bat` will:
119 |
120 | 1. Build the _HTMLRes_ executable.
121 | 2. Extract the release version information from the executable.
122 | 3. Compile the setup program.
123 | 4. Create a zip file containing the setup program and some documentation.
124 |
125 | The release version information extracted in step 2 is used to set the setup program's version and to embed the version number in the names of the setup program file and zip file.
126 |
127 | The `release` zip file is placed in the release sub-directory of `_build`:
128 |
129 | ```text
130 | /-+
131 | ⁞
132 | +-- _build
133 | | |
134 | | +-- bin - contains all binary intermediate files
135 | | |
136 | | +-- exe - contains the compiled exe file
137 | | |
138 | | +-- release - contains the release zip file
139 | ⁞
140 | ```
141 |
142 | ### Tidying Up
143 |
144 | If you are using Git you can run
145 |
146 | ```test
147 | git clean -fxd
148 | ```
149 |
150 | to remove all unwanted files.
151 |
152 | > :warning: Running the above command will remove the `_build` directory and all its contents, so ensure you copy any wanted files from there beforehand. The command will also remove Delphi's `__history` directory.
153 |
154 | ## Copyright
155 |
156 | If you are planning to re-use or modify any of the code, please see the file `LICENSE.md` for an overview of the open source licenses that apply
157 | to the source code.
158 |
--------------------------------------------------------------------------------
/Docs/UserGuide.md:
--------------------------------------------------------------------------------
1 | # DelphiDabbler HTML Resource Compiler User Guide
2 |
3 | ## Introduction
4 |
5 | _HTMLRes_ is a Windows command line program that is used to create resource files containing the contents of HTML, CSS, image etc. files as resources.
6 |
7 | Each file is stored as a separate resource. Each resources is of type `HTML` (`#23`) and is named after the source file.
8 |
9 | ## Scope
10 |
11 | This document relates to _HTMLRes_ v1.3.1 and later.
12 |
13 | ## Command Line
14 |
15 | The command line syntax of the application is:
16 |
17 | HTMLRes [-m] [-o] [options]
18 |
19 | where:
20 |
21 | `` is a sequence of zero or more file names. These files will be stored in the resource file. Relative file names are relative to the folder from where _HTMLRes_ was started. The `-r` option may be used to change this behaviour (see below).
22 |
23 | `` is the name of a file that contains a list of files to be stored in the resource file. Each file name is placed on a separate line in the manifest file. Blank lines are ignored. Lines beginning with `#` are treated as comments and are also ignored. Comments cannot be placed on the same line as a file name. Here's an example manifest file:
24 |
25 | # Files required for demo
26 | index.html
27 | page2.html
28 | arrow.gif
29 | style.css
30 |
31 | Spaces are not allowed between the `-m` command and the manifest file name. The file names specified in the manifest are, by default, relative to the folder from where _HTMLRes_ was executed. The `-r` option can be used to change this behaviour so that filenames are relative to the manifest file folder instead (see below).
32 |
33 | The manifest file is expected to be in the system default encoding unless it has a byte order mark prefix or preamble that identifies it as a UTF-16 or UTF-8 encoded file.
34 |
35 | `` is the name of the generated resource file. Spaces are not allowed between the `-o` command and the output file name. This command is optional. If no output file name is specified then the default name `out.res` is used. The `-u` option controls how pre-existing output files are handled (see below).
36 |
37 | `options` is a sequence of zero or more of space separated options from the following list:
38 |
39 | * `-q` - Quite mode. Does not display any normal output. Any error messages are displayed.
40 |
41 | * `-Q` - Silent mode. No normal or error messages are displayed.
42 |
43 | * `-p` or `-P` - Causes the program to pause on completion and prompts the user to press return before closing the program. The prompt is always displayed, regardless of whether the `-q` or `-Q` options have been used.
44 |
45 | * `-r` or `-R` - Causes all relative file names to be taken as relative to the manifest file's directory. If this option is not specified then file names are relative to the directory where _HTMLRes_ was executed. The option applies to the preceding `-m` manifest file command. If there is no `-m` command then this option is ignored. `-r` applies to all relative file names, i.e. input file, output file and all files listed in a manifest file.
46 |
47 | * `-u:param` or `-U:param` - Specifies the action to be taken if an output file already exists. `param` indicates the action to take:
48 |
49 | * `-u:fail` - The program fails with an error if the output file does not exist. The output file is not changed.
50 |
51 | * `-u:overwritefile` - The output file is overwritten (default).
52 |
53 | * `-u:insertres` - Inserts HTML resources into the existing file. An error is reported if the output file is not a valid resource file or if any resource name already exists in the file. The output file is not modified if an error occurs.
54 |
55 | * `-u:overwriteres` - Inserts HTML resources into the existing file, overwriting existing resources if there is a name clash. It is an error if the output file is not a valid resource file. In the event of an error the output file is not modified.
56 |
57 | * `-H`, `-h` or `-?` - Displays a help screen. The `-q` and `-Q` options are ignored.
58 |
59 | At least one input file must be provided, either directly on the command line or in a manifest file, unless the `-H`, `-h` or `-?` options are used. See below for restrictions placed on file names.
60 |
61 | ## Error Codes
62 |
63 | The program returns `0` on success or a positive error code on failure. The error codes are explained in the following table.
64 |
65 | | Error code | Explanation |
66 | |------------|-------------|
67 | | `1` | Command line error. |
68 | | `2` | Manifest file expected but doesn't exist. |
69 | | `3` | One or more source files don't exist. |
70 | | `4` | Duplicate file name. |
71 | | `5` | Output file exists (the `-u:fail` option has been used). |
72 | | `6` | Output file exists but is not a valid resource file (the `-u:insertres` or `-u:overwriteres` option has been used). |
73 | | `7` | Resource name already exists in output file (the `-u:insertres` option has been used). |
74 | | `255` | Unexpected / unknown error. |
75 |
76 | ## File Name Restrictions
77 |
78 | Since resource names cannot be duplicated in a resource file, and since base file names (without the path) are used as resource names, it follows that duplicate base file names cannot be specified either on the command line or in a manifest file. For example you can't specify both `C:\Foo\MyFile.htm` and `C:\Bar\MyFile.htm`.
79 |
80 | If you are intending to use the `res://` protocol to access the HTML resources from Internet Explorer or an embedded Web Browser control there are some restrictions on the resource names, and hence the files names, that you can use. Certain file names that begin with a digit or a punctuation character are not recognised and not loaded. Examples of names to avoid are:
81 |
82 | * `42.html`
83 | * `%3.css`
84 | * `4-a.jpg`
85 |
86 | ## Example
87 |
88 | An example Delphi project is supplied with the program. The demo files are installed in the `Demo` sub-folder of the main program installation folder.
89 |
90 | The demo project simply creates a resource only DLL that stores some HTML, CSS and GIF files that can be displayed in Internet Explorer.
91 |
92 | The demo files are:
93 |
94 | | File Name | Description |
95 | |-----------|-------------|
96 | | `index.html` | The main demo web page. |
97 | | `page2.html` | A subsidiary web page. |
98 | | `style.css` | A style sheet for the web pages. |
99 | | `arrow.gif` | A GIF displayed in `index.html`. |
100 | | `Demo.hmfst` | A manifest file that lists the demo files to be built by _HTMLRes_. |
101 | | `Demo.utf8-hmfst` | Same as `Demo.hmfst` except that the file has a UTF8 prefix ("BOM"). It should generate _exactly_ the same output as `Demo.hmfst`. Used to test that _HTMLRes_ can automatically detect UTF8 format text files. |
102 | | `HTMLLib.dpr` | The Delphi source code for the resource-only DLL. |
103 | | `DemoReadMem.txt` | ReadMe file for demo code. Please read before using the demo code. |
104 |
105 | Before building the demo project using Delphi you must first start a command console window and navigate to the demo directory. Now run _HTMLRes_ as follows:
106 |
107 | HTMLRes -mDemo.hmfst -oHTML.res
108 |
109 | This compiles the files specified in `Demo.hmfst` into the resource file `HTML.res`.
110 |
111 | The project file, `HTMLLib.dpr`, contains a resource statement that includes `HTML.res`. The project can now be compiled with Delphi to create the required resource DLL.
112 |
113 | If the demo DLL is stored in the `C:\HTMLRes\Demo` folder we can display the main page in Internet Explorer by entering the following URL in the browser's address bar:
114 |
115 | res://C:\HTMLRes\Demo\HTMLLib.dll/index.html
116 |
117 | The HTML file, its style sheet and the graphic are all stored in the DLL's resources along with a second page that can be displayed by clicking the link on the index page.
118 |
119 | ----
120 |
121 |
122 | This user guide is copyright © 2007-2021, [Peter D Johnson](https://gravatar.com/delphidabbler) and is licensed under a [Creative Commons CC BY-NC-SA 2.5 License](https://creativecommons.org/licenses/by-nc-sa/2.5).
123 |
--------------------------------------------------------------------------------
/Src/UParams.pas:
--------------------------------------------------------------------------------
1 | {
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at https://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 2004-2024, Peter Johnson (gravatar.com/delphidabbler).
7 | *
8 | * Implements class that parses the HTML Resource Compiler's command line, lists
9 | * errors and exposes information from command line as properties.
10 | }
11 |
12 |
13 | unit UParams;
14 |
15 |
16 | interface
17 |
18 |
19 | uses
20 | // Delphi
21 | System.Classes;
22 |
23 |
24 | type
25 |
26 | {
27 | TQuietState:
28 | Level of "quietness" of program output.
29 | }
30 | TQuietState = (
31 | qsOff, // all program messages displayed (default)
32 | qsErrsOnly, // only error messages are displayed
33 | qsSilent // totally silent: no output
34 | );
35 |
36 | {
37 | TFileUpdateAction:
38 | Action to take if output resource file already exists.
39 | }
40 | TFileUpdateAction = (
41 | uaFail, // fail if output already exists
42 | uaOverwriteFile, // overwrite any existing file (default)
43 | uaInsertRes, // insert resources into file, fail if resource exists
44 | uaOverwriteRes // insert resources into file, overwrite existing resource
45 | );
46 |
47 | {
48 | TParams:
49 | Parses command line, lists errors and exposes information from command line
50 | as properties.
51 | }
52 | TParams = class(TObject)
53 | private
54 | fPause: Boolean;
55 | {Whether to pause for return key press at end of program}
56 | fHelp: Boolean;
57 | {Whether to display help screen}
58 | fOutFile: string;
59 | {Name of output file}
60 | fManifestFile: string;
61 | {Name of any manifest file}
62 | fQuietness: TQuietState;
63 | {Level of verbosity of screen output}
64 | fFileUpdateAction: TFileUpdateAction;
65 | {Indicates how to handle output files that already exist}
66 | fInFiles: TStringList;
67 | {List of input files specified on command line}
68 | fErrors: TStringList;
69 | {List of command line errors}
70 | function GetInFile(Idx: Integer): string;
71 | {Gets the name of an input file from the InFiles[] property.
72 | @param Idx [in] Index into InFiles[] property.
73 | @return Input file name at the given index.
74 | }
75 | function GetInFileCount: Integer;
76 | {Gets the number of input files in InFiles[] property.
77 | @return File name count.
78 | }
79 | function GetError(Idx: Integer): string;
80 | {Gets an error message from the Errors[] property.
81 | @param Idx [in] Index into Errors[] property.
82 | @return error message at given index.
83 | }
84 | function GetErrorCount: Integer;
85 | {Gets the number of errors in Errors[] property.
86 | @return Error count.
87 | }
88 | public
89 | constructor Create;
90 | {Class constructor. Creates TParams object and parses command line.
91 | }
92 | destructor Destroy; override;
93 | {Class destructor. Tears down object.
94 | }
95 | property Pause: Boolean read fPause;
96 | {Whether to pause for return key press when program ends (-p switch)}
97 | property Quietness: TQuietState read fQuietness;
98 | {Verbosity of output required (-q and -Q switches)}
99 | property FileUpdateAction: TFileUpdateAction read fFileUpdateAction;
100 | {How to handle output files that already exist}
101 | property Help: Boolean read fHelp;
102 | {Whether to display help (-h or -? switches)}
103 | property ManifestFile: string read fManifestFile;
104 | {Name of manifest file from -m parameter (defaults to '')}
105 | property OutFile: string read fOutFile;
106 | {Name of output file from -o parameter (defaults to out.res)}
107 | property InFiles[Idx: Integer]: string read GetInFile;
108 | {Array of input files from command line, indexed 0..InFileCount-1}
109 | property InFileCount: Integer read GetInFileCount;
110 | {Number of input files from command line}
111 | property Errors[Idx: Integer]: string read GetError;
112 | {Array of command line errors, indexed 0..ErrorCount-1}
113 | property ErrorCount: Integer read GetErrorCount;
114 | {Number of command line errors in Errors property}
115 | end;
116 |
117 | function Params: TParams;
118 | {Gets reference to singleton TParams object.
119 | @return Required reference.
120 | }
121 |
122 |
123 | implementation
124 |
125 |
126 | uses
127 | // Delphi
128 | System.SysUtils;
129 |
130 |
131 | const
132 | // Default output file
133 | cDefOutFile = 'out.res';
134 |
135 |
136 | resourcestring
137 | // Error messages
138 | sBadFileSwitch = 'No file name supplied with switch "%s"';
139 | sUnknownSwitch = 'Unrecognised switch: "%s"';
140 | sMalformedSwitch = 'Malformed switch: "%s"';
141 | sNoInputFiles = 'No input files specified';
142 | sManifestNotInput = 'Manifest file can''t be specified as an input file';
143 | sOutputNotInput = 'Output file can''t be specified as an input file';
144 | sOutputAndManifestSame = 'Output and manifest files can''t have same name';
145 | sBadUpdateAction = 'Unrecognised file update action in -i switch: "%s"';
146 |
147 |
148 | var
149 | // Reference to singleton instance of TParams
150 | Singleton: TParams;
151 |
152 |
153 | function Params: TParams;
154 | {Gets reference to singleton TParams object.
155 | @return Required reference.
156 | }
157 | begin
158 | if not Assigned(Singleton) then
159 | Singleton := TParams.Create;
160 | Result := Singleton;
161 | end;
162 |
163 |
164 | { TParams }
165 |
166 | constructor TParams.Create;
167 | {Class constructor. Creates TParams object and parses command line.
168 | }
169 |
170 | // ---------------------------------------------------------------------------
171 | procedure RecordError(const Msg: string);
172 | {Records error message in command line Errors property.
173 | @param Msg [in] Error message to be recorded.
174 | }
175 | begin
176 | fErrors.Add(Msg);
177 | end;
178 |
179 | function FileNameFromSwitch(const Switch: string): string;
180 | {Extracts file name from end of switch (form -Xfilename). Records error
181 | message in Errors property if there is no file name after switch.
182 | @param Switch [in] Switch with appended file name.
183 | @return File name.
184 | }
185 | begin
186 | Result := Copy(Switch, 3, MaxInt);
187 | if Result = '' then
188 | RecordError(Format(sBadFileSwitch, [Switch]));
189 | end;
190 |
191 | function UpdateActionFromSwitch(const Switch: string): TFileUpdateAction;
192 | {Analyses -u switch to determine how output file is to be handled if it
193 | already exists.
194 | @param Switch [in] Complete -u switch.
195 | @return Action to be taken to handle output file.
196 | }
197 | var
198 | Action: string; // action component of -u switch
199 | begin
200 | // assume default result (keeps compiler happy)
201 | Result := uaOverwriteFile;
202 | // format of -u switch is -u:action
203 | Action := LowerCase(Copy(Switch, 3, MaxInt));
204 | if Action = ':fail' then
205 | Result := uaFail
206 | else if Action = ':overwritefile' then
207 | Result := uaOverwriteFile
208 | else if Action = ':insertres' then
209 | Result := uaInsertRes
210 | else if Action = ':overwriteres' then
211 | Result := uaOverwriteRes
212 | else
213 | RecordError(Format(sBadUpdateAction, [Action]));
214 | end;
215 | // ---------------------------------------------------------------------------
216 |
217 | var
218 | I: Integer; // loops thru command line parameters
219 | Param: string; // a parameter
220 | begin
221 | inherited;
222 | // Create owned objects
223 | fInFiles := TStringList.Create;
224 | fErrors := TStringList.Create;
225 | // Set default property values
226 | fPause := False;
227 | fQuietness := qsOff;
228 | fFileUpdateAction := uaOverwriteFile;
229 | fHelp := False;
230 | fManifestFile := '';
231 | fOutFile := cDefOutFile;
232 | // Parse command line
233 | for I := 1 to ParamCount do
234 | begin
235 | Param := ParamStr(I);
236 | if CharInSet(Param[1], ['-', '/']) then
237 | begin
238 | // Process a switch
239 | if Length(Param) >= 2 then
240 | begin
241 | case Param[2] of
242 | 'P', 'p':
243 | // pause at end of program until return pressed (ignores -q & -Q)9
244 | fPause := True;
245 | 'q':
246 | // no standard output: errors reported
247 | if fQuietness <> qsSilent then
248 | fQuietness := qsErrsOnly;
249 | 'Q':
250 | // no output at all: errors not reported (overrides -q)
251 | fQuietness := qsSilent;
252 | 'H', 'h', '?':
253 | // display help screen (ignores -q and -Q)
254 | fHelp := True;
255 | 'M', 'm':
256 | // use following file as input file manifest
257 | fManifestFile := FileNameFromSwitch(Param);
258 | 'O', 'o':
259 | // use following file as output file
260 | fOutFile := FileNameFromSwitch(Param);
261 | 'R', 'r':
262 | // use path to manifest as current directory for relative file names
263 | // this switch must follow -m on command line or it will be ignored
264 | if fManifestFile <> '' then
265 | SetCurrentDir(ExtractFileDir(fManifestFile));
266 | 'U', 'u':
267 | // indicates action to be taken if output file already exists: use
268 | // text following ':' to determine action
269 | fFileUpdateAction := UpdateActionFromSwitch(Param);
270 | else
271 | RecordError(Format(sUnknownSwitch, [Param]));
272 | end;
273 | end
274 | else
275 | // Error bad switch: no id
276 | RecordError(Format(sMalformedSwitch, [Param]));
277 | end
278 | else
279 | begin
280 | // Process a file name: ignore duplicates
281 | if fInFiles.IndexOf(Param) = -1 then
282 | fInFiles.Add(Param);
283 | end;
284 | end;
285 | // Check for error switch combinations
286 | // we must have at least one input file or a manifest file or be requesting
287 | // help
288 | if (fInFiles.Count = 0) and (fManifestFile = '') and not fHelp then
289 | RecordError(sNoInputFiles);
290 | // check that neither manifest file nor output file are also specified as
291 | // input files
292 | if fInFiles.IndexOf(fManifestFile) <> -1 then
293 | RecordError(sManifestNotInput);
294 | if fInFiles.IndexOf(fOutFile) <> -1 then
295 | RecordError(sOutputNotInput);
296 | // make sure that any manifest doesn't have same name as output file
297 | if AnsiCompareText(fOutFile, fManifestFile) = 0 then
298 | RecordError(sOutputAndManifestSame);
299 | end;
300 |
301 | destructor TParams.Destroy;
302 | {Class destructor. Tears down object.
303 | }
304 | begin
305 | fErrors.Free;
306 | fInFiles.Free;
307 | if Self = Singleton then
308 | Singleton := nil;
309 | inherited;
310 | end;
311 |
312 | function TParams.GetError(Idx: Integer): string;
313 | {Gets an error message from the Errors[] property.
314 | @param Idx [in] Index into Errors[] property.
315 | @return error message at given index.
316 | }
317 | begin
318 | Result := fErrors[Idx];
319 | end;
320 |
321 | function TParams.GetErrorCount: Integer;
322 | {Gets the number of errors in Errors[] property.
323 | @return Error count.
324 | }
325 | begin
326 | Result := fErrors.Count;
327 | end;
328 |
329 | function TParams.GetInFile(Idx: Integer): string;
330 | {Gets the name of an input file from the InFiles[] property.
331 | @param Idx [in] Index into InFiles[] property.
332 | @return Input file name at the given index.
333 | }
334 | begin
335 | Result := fInFiles[Idx];
336 | end;
337 |
338 | function TParams.GetInFileCount: Integer;
339 | {Gets the number of input files in InFiles[] property.
340 | @return File name count.
341 | }
342 | begin
343 | Result := fInFiles.Count;
344 | end;
345 |
346 |
347 | initialization
348 |
349 |
350 | finalization
351 |
352 | // Destroy singleton
353 | Singleton.Free;
354 |
355 | end.
356 |
357 |
--------------------------------------------------------------------------------
/Docs/PreSVNHistory.txt:
--------------------------------------------------------------------------------
1 | ================================================================================
2 |
3 | HTMLRES: Historical update information from v1.0.0 to v1.2.0
4 |
5 | ================================================================================
6 |
7 | This file records known changes to files and releases of HTMLRes from the first
8 | release (v1.0) until release 1.2 when the project was placed was placed under
9 | version control with Subversion.
10 |
11 | There are two sections:
12 |
13 | 1 Files: Lists all source code and development tools and provides details of
14 | changes to these files that preceded version control.
15 |
16 | 2 Releases: Lists all the releases of HTMLRes and notes which file revisions
17 | were included in each release.
18 |
19 | ================================================================================
20 | FILES
21 | ================================================================================
22 |
23 | This section lists all files for which update history is known between v1.0.0
24 | and v1.2.0.
25 |
26 | --------------------------------------------------------------------------------
27 | DevTools\BuildAll.bat
28 | --------------------------------------------------------------------------------
29 | v1.0 of 23 Aug 2008 - Original version
30 | 01 Aug 2009 - MOVED TO SUBVERSION
31 |
32 | --------------------------------------------------------------------------------
33 | DevTools\BuildPascal.bat
34 | --------------------------------------------------------------------------------
35 | v1.0 of 21 Aug 2008 - First version.
36 | 01 Aug 2009 - MOVED TO SUBVERSION
37 |
38 | --------------------------------------------------------------------------------
39 | DevTools\BuildResources.bat
40 | --------------------------------------------------------------------------------
41 | v1.0 of 21 Aug 2008 - First version.
42 | 01 Aug 2009 - MOVED TO SUBVERSION
43 |
44 | --------------------------------------------------------------------------------
45 | DevTools\BuildSetup.bat
46 | --------------------------------------------------------------------------------
47 | v1.0 of 23 Aug 2008 - First version.
48 | 01 Aug 2009 - MOVED TO SUBVERSION
49 |
50 | --------------------------------------------------------------------------------
51 | DevTools\ReleaseAll.bat
52 | --------------------------------------------------------------------------------
53 | v1.0 of 23 Aug 2008 - First version.
54 | 01 Aug 2009 - MOVED TO SUBVERSION
55 |
56 | --------------------------------------------------------------------------------
57 | DevTools\ReleaseExe.bat
58 | --------------------------------------------------------------------------------
59 | v1.0 of 23 Aug 2008 - First version.
60 | 01 Aug 2009 - MOVED TO SUBVERSION
61 |
62 | --------------------------------------------------------------------------------
63 | DevTools\ReleaseSrc.bat
64 | --------------------------------------------------------------------------------
65 | v1.0 of 21 Aug 2008 - First version.
66 | 01 Aug 2009 - MOVED TO SUBVERSION
67 |
68 | --------------------------------------------------------------------------------
69 | DevTools\Tidy.bat
70 | --------------------------------------------------------------------------------
71 | v1.0 of 21 Aug 2008 - First version.
72 | 01 Aug 2009 - MOVED TO SUBVERSION
73 |
74 | --------------------------------------------------------------------------------
75 | Docs\HTMLRes.phf
76 | --------------------------------------------------------------------------------
77 | 26 Jun 2004 - New project update file for HTMLRes v1.0 build 1.
78 | 18 Sep 2004 - Added details of HTMLRes v1.0.1 build 2.
79 | 29 May 2006 - Added details of HTMLRes v1.1 build 3.
80 | 23 Aug 2008 - Added details of HTMLRes v1.2 build 4.
81 | 01 Aug 2009 - MOVED TO SUBVERSION
82 |
83 | --------------------------------------------------------------------------------
84 | Src\Build.bat
85 | --------------------------------------------------------------------------------
86 | v1.0 of 23 Aug 2008 - Original version
87 | 01 Aug 2009 - MOVED TO SUBVERSION
88 |
89 | --------------------------------------------------------------------------------
90 | Src\HTMLRes.dpr
91 | --------------------------------------------------------------------------------
92 | v1.0 of 26 Jun 2004 - Original version.
93 | v1.1 of 18 Sep 2004 - Removed UResourceFile and UResourceUtils units.
94 | v1.2 of 29 May 2006 - Updated commenting.
95 | v1.3 of 21 Aug 2008 - Added new UVerInfo unit.
96 | 01 Aug 2009 - MOVED TO SUBVERSION
97 |
98 | --------------------------------------------------------------------------------
99 | Src\HTMLRes.manifest
100 | --------------------------------------------------------------------------------
101 | v1.0 of 21 Aug 2008 - Original version that permits application to run without
102 | elevation on Vista.
103 | 01 Aug 2009 - MOVED TO SUBVERSION
104 |
105 | --------------------------------------------------------------------------------
106 | Src\HTMLRes.rc
107 | --------------------------------------------------------------------------------
108 | v1.0 of 21 Aug 2008 - Original version. Contains only manifest file.
109 | 01 Aug 2009 - MOVED TO SUBVERSION
110 |
111 | --------------------------------------------------------------------------------
112 | Src\Install.iss
113 | --------------------------------------------------------------------------------
114 | v1.0 of 23 Aug 2008 - Original version.
115 | 01 Aug 2009 - MOVED TO SUBVERSION
116 |
117 | --------------------------------------------------------------------------------
118 | Src\UErrors.pas
119 | --------------------------------------------------------------------------------
120 | v1.0 of 26 Jun 2004 - Original version.
121 | v1.1 of 28 May 2006 - Rewrote commenting.
122 | - Renamed error code constants.
123 | v1.2 of 21 Aug 2008 - Added new ErrOutFileExists, cErrBadOutFile and
124 | cErrResourceExists error constants.
125 | 01 Aug 2009 - MOVED TO SUBVERSION
126 |
127 | --------------------------------------------------------------------------------
128 | Src\UMain.pas
129 | --------------------------------------------------------------------------------
130 | v1.0 of 26 Jun 2004 - Original version.
131 | v1.1 of 18 Sep 2004 - Replaced project's own resource file handling code with
132 | PJResFile library unit. Modified class names and method
133 | calls to suit. Now uses constants from PJResFile for
134 | memory flags and HTML resource type.
135 | v1.2 of 29 May 2006 - Revised help message re new -r command line switch
136 | that enables program to use paths relative to manifest
137 | file rather than program's default directory.
138 | - Changed to use renamed error constants.
139 | - Changed to use PJVersionInfo component to get version
140 | information. Now gets copyright information from version
141 | information resource.
142 | - Deleted reference to MPL in sign on message.
143 | - Rewrote commenting.
144 | v1.3 of 23 Aug 2008 - Revised to be able to insert resources into existing
145 | resource files (failing or overwriting duplicate
146 | resources) or to fail if resource file exists.
147 | - Now always creates language neutral resources rather than
148 | user's current language.
149 | - Added compiler directive to switch off unsafe warnings.
150 | - Updtated help screen and other messages re new -u switch
151 | and its implementation.
152 | - Changed to use singleton Params object rather managing
153 | own TParams object.
154 | - Moved routines that get version information to own unit.
155 | 01 Aug 2009 - MOVED TO SUBVERSION
156 |
157 | --------------------------------------------------------------------------------
158 | Src\UParams.pas
159 | --------------------------------------------------------------------------------
160 | v1.0 of 26 Jun 2004 - Original version.
161 | v1.1 of 28 May 2006 - Added new -r command line switch and code to support it.
162 | - Rewrote commenting.
163 | v1.2 of 21 Aug 2008 - Converted to singleton object.
164 | - Added new -u switch that governs how any existing
165 | resource file is updated.
166 | 01 Aug 2009 - MOVED TO SUBVERSION
167 |
168 | --------------------------------------------------------------------------------
169 | Src\UResourceFile.pas
170 | --------------------------------------------------------------------------------
171 | v1.0 of 26 Jun 2004 - Original version
172 | 18 Sep 2004 - DELETED
173 |
174 | --------------------------------------------------------------------------------
175 | Src\UResourceUtils.pas
176 | --------------------------------------------------------------------------------
177 | v1.0 of 26 Jun 2004 - Original version
178 | 18 Sep 2004 - DELETED
179 |
180 | --------------------------------------------------------------------------------
181 | Src\UVerInfo.pas
182 | --------------------------------------------------------------------------------
183 | v1.0 of 21 Aug 2008 - Original version.
184 | 01 Aug 2009 - MOVED TO SUBVERSION
185 |
186 | --------------------------------------------------------------------------------
187 | Src\VHTMLRes.vi
188 | --------------------------------------------------------------------------------
189 | 26 Jun 2004 - Version information. File and product numbers set to
190 | 1.0.0.
191 | 18 Sep 2004 - Updated file and product version numbers to 1.0.1.
192 | - Changed file description to "HTML Resource Compiler".
193 | - Changed product description to "DelphiDabbler HTML
194 | Resource Compiler".
195 | 29 May 2006 - Removed Comments string re license.
196 | - Updated file, product and build numbers to 1.1.0, build
197 | number 3.
198 | - Updated Copyright string and dates.
199 | 23 Aug 2008 - Updated file and product numbers to 1.2.0, build 4.
200 | - Deleted RC Comments and Resource output directory
201 | entries.
202 | 01 Aug 2009 - MOVED TO SUBVERSION
203 |
204 | ================================================================================
205 | RELEASES
206 | ================================================================================
207 |
208 | This section lists all releases of HTMLRes from the first version (1.0) to
209 | release 1.2. For each release the following is noted:
210 |
211 | + Version and build number.
212 | + Brief notes of changes to program.
213 | + List of new and added source files.
214 |
215 | The Development tools, .bpg and .cfg files, test files and documentation are not
216 | included in this information.
217 |
218 | --------------------------------------------------------------------------------
219 | v1.0 build 1 of 26 Jun 2004
220 | --------------------------------------------------------------------------------
221 | Notes:
222 | + Original version.
223 | File changes:
224 | + New: HTMLRes.dpr 1.0
225 | + New: UErrors.pas 1.0
226 | + New: UMain.pas 1.0
227 | + New: UParams.pas 1.0
228 | + New: UResourceFile.pas 1.0
229 | + New: UResourceUtils.pas v1.0
230 | + New: VHTMLRes.vi 26 Jun 2004
231 |
232 | --------------------------------------------------------------------------------
233 | v1.0.1 build 2 of 18 Sep 2004
234 | --------------------------------------------------------------------------------
235 | Notes:
236 | + Modified to use resource file handling code in DelphiDabbler library unit
237 | PJResFile rather than own custom code.
238 | File changes:
239 | + Updated: HTMLRes.dpr 1.1
240 | + Updated: UMain.pas 1.1
241 | + Updated: VHTMLRes.vi 18 Sep 2004
242 | + Removed: UResourceFile.pas
243 | + Removed: UResourceUtils.pas
244 |
245 | --------------------------------------------------------------------------------
246 | v1.1 build 3 of 29 May 2006
247 | --------------------------------------------------------------------------------
248 | Notes:
249 | + Added new -r command line switch that enables manifest files to reference
250 | files relative to manifest rather than directory HTMLRes executed from.
251 | + Updated message displayed when program starts.
252 | + Changed to new open source license for executable code (source still
253 | available under MPL)
254 | File changes:
255 | + Updated: HTMLRes.dpr 1.2
256 | + Updated: UErrors.pas 1.1
257 | + Updated: UMain.pas 1.2
258 | + Updated: UParams.pas 1.1
259 | + Update: VHTMLRes.vi 29 May 2006
260 |
261 | --------------------------------------------------------------------------------
262 | v1.2 of build 4 23 Aug 2008
263 | --------------------------------------------------------------------------------
264 | Notes:
265 | + Added facility to insert or update resources in existing output resource
266 | files. Options controlled by new -u switch.
267 | + Replaced command line installer to Windows installed built with Inno Setup
268 | installer.
269 | + Added new build script that can build program and installer.
270 | File changes:
271 | + New: Build.bat
272 | + Updated: HTMLRes.dpr 1.3
273 | + New: HTMLRes.rc 1.0
274 | + New: HTMLRes.manifest 1.0
275 | + New: Install.iss 1.0
276 | + Updated: UErrors.pas 1.2
277 | + Updated: UMain.pas 1.3
278 | + Updated: UParams.pas 1.2
279 | + New: UVersionInfo.pas 1.0
280 | + Update: VHTMLRes.vi 21 Aug 2006
281 |
282 | --------------------------------------------------------------------------------
283 |
--------------------------------------------------------------------------------
/Docs/MPL-2.0.txt:
--------------------------------------------------------------------------------
1 | Mozilla Public License Version 2.0
2 | ==================================
3 |
4 | 1. Definitions
5 | --------------
6 |
7 | 1.1. "Contributor"
8 | means each individual or legal entity that creates, contributes to
9 | the creation of, or owns Covered Software.
10 |
11 | 1.2. "Contributor Version"
12 | means the combination of the Contributions of others (if any) used
13 | by a Contributor and that particular Contributor's Contribution.
14 |
15 | 1.3. "Contribution"
16 | means Covered Software of a particular Contributor.
17 |
18 | 1.4. "Covered Software"
19 | means Source Code Form to which the initial Contributor has attached
20 | the notice in Exhibit A, the Executable Form of such Source Code
21 | Form, and Modifications of such Source Code Form, in each case
22 | including portions thereof.
23 |
24 | 1.5. "Incompatible With Secondary Licenses"
25 | means
26 |
27 | (a) that the initial Contributor has attached the notice described
28 | in Exhibit B to the Covered Software; or
29 |
30 | (b) that the Covered Software was made available under the terms of
31 | version 1.1 or earlier of the License, but not also under the
32 | terms of a Secondary License.
33 |
34 | 1.6. "Executable Form"
35 | means any form of the work other than Source Code Form.
36 |
37 | 1.7. "Larger Work"
38 | means a work that combines Covered Software with other material, in
39 | a separate file or files, that is not Covered Software.
40 |
41 | 1.8. "License"
42 | means this document.
43 |
44 | 1.9. "Licensable"
45 | means having the right to grant, to the maximum extent possible,
46 | whether at the time of the initial grant or subsequently, any and
47 | all of the rights conveyed by this License.
48 |
49 | 1.10. "Modifications"
50 | means any of the following:
51 |
52 | (a) any file in Source Code Form that results from an addition to,
53 | deletion from, or modification of the contents of Covered
54 | Software; or
55 |
56 | (b) any new file in Source Code Form that contains any Covered
57 | Software.
58 |
59 | 1.11. "Patent Claims" of a Contributor
60 | means any patent claim(s), including without limitation, method,
61 | process, and apparatus claims, in any patent Licensable by such
62 | Contributor that would be infringed, but for the grant of the
63 | License, by the making, using, selling, offering for sale, having
64 | made, import, or transfer of either its Contributions or its
65 | Contributor Version.
66 |
67 | 1.12. "Secondary License"
68 | means either the GNU General Public License, Version 2.0, the GNU
69 | Lesser General Public License, Version 2.1, the GNU Affero General
70 | Public License, Version 3.0, or any later versions of those
71 | licenses.
72 |
73 | 1.13. "Source Code Form"
74 | means the form of the work preferred for making modifications.
75 |
76 | 1.14. "You" (or "Your")
77 | means an individual or a legal entity exercising rights under this
78 | License. For legal entities, "You" includes any entity that
79 | controls, is controlled by, or is under common control with You. For
80 | purposes of this definition, "control" means (a) the power, direct
81 | or indirect, to cause the direction or management of such entity,
82 | whether by contract or otherwise, or (b) ownership of more than
83 | fifty percent (50%) of the outstanding shares or beneficial
84 | ownership of such entity.
85 |
86 | 2. License Grants and Conditions
87 | --------------------------------
88 |
89 | 2.1. Grants
90 |
91 | Each Contributor hereby grants You a world-wide, royalty-free,
92 | non-exclusive license:
93 |
94 | (a) under intellectual property rights (other than patent or trademark)
95 | Licensable by such Contributor to use, reproduce, make available,
96 | modify, display, perform, distribute, and otherwise exploit its
97 | Contributions, either on an unmodified basis, with Modifications, or
98 | as part of a Larger Work; and
99 |
100 | (b) under Patent Claims of such Contributor to make, use, sell, offer
101 | for sale, have made, import, and otherwise transfer either its
102 | Contributions or its Contributor Version.
103 |
104 | 2.2. Effective Date
105 |
106 | The licenses granted in Section 2.1 with respect to any Contribution
107 | become effective for each Contribution on the date the Contributor first
108 | distributes such Contribution.
109 |
110 | 2.3. Limitations on Grant Scope
111 |
112 | The licenses granted in this Section 2 are the only rights granted under
113 | this License. No additional rights or licenses will be implied from the
114 | distribution or licensing of Covered Software under this License.
115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
116 | Contributor:
117 |
118 | (a) for any code that a Contributor has removed from Covered Software;
119 | or
120 |
121 | (b) for infringements caused by: (i) Your and any other third party's
122 | modifications of Covered Software, or (ii) the combination of its
123 | Contributions with other software (except as part of its Contributor
124 | Version); or
125 |
126 | (c) under Patent Claims infringed by Covered Software in the absence of
127 | its Contributions.
128 |
129 | This License does not grant any rights in the trademarks, service marks,
130 | or logos of any Contributor (except as may be necessary to comply with
131 | the notice requirements in Section 3.4).
132 |
133 | 2.4. Subsequent Licenses
134 |
135 | No Contributor makes additional grants as a result of Your choice to
136 | distribute the Covered Software under a subsequent version of this
137 | License (see Section 10.2) or under the terms of a Secondary License (if
138 | permitted under the terms of Section 3.3).
139 |
140 | 2.5. Representation
141 |
142 | Each Contributor represents that the Contributor believes its
143 | Contributions are its original creation(s) or it has sufficient rights
144 | to grant the rights to its Contributions conveyed by this License.
145 |
146 | 2.6. Fair Use
147 |
148 | This License is not intended to limit any rights You have under
149 | applicable copyright doctrines of fair use, fair dealing, or other
150 | equivalents.
151 |
152 | 2.7. Conditions
153 |
154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155 | in Section 2.1.
156 |
157 | 3. Responsibilities
158 | -------------------
159 |
160 | 3.1. Distribution of Source Form
161 |
162 | All distribution of Covered Software in Source Code Form, including any
163 | Modifications that You create or to which You contribute, must be under
164 | the terms of this License. You must inform recipients that the Source
165 | Code Form of the Covered Software is governed by the terms of this
166 | License, and how they can obtain a copy of this License. You may not
167 | attempt to alter or restrict the recipients' rights in the Source Code
168 | Form.
169 |
170 | 3.2. Distribution of Executable Form
171 |
172 | If You distribute Covered Software in Executable Form then:
173 |
174 | (a) such Covered Software must also be made available in Source Code
175 | Form, as described in Section 3.1, and You must inform recipients of
176 | the Executable Form how they can obtain a copy of such Source Code
177 | Form by reasonable means in a timely manner, at a charge no more
178 | than the cost of distribution to the recipient; and
179 |
180 | (b) You may distribute such Executable Form under the terms of this
181 | License, or sublicense it under different terms, provided that the
182 | license for the Executable Form does not attempt to limit or alter
183 | the recipients' rights in the Source Code Form under this License.
184 |
185 | 3.3. Distribution of a Larger Work
186 |
187 | You may create and distribute a Larger Work under terms of Your choice,
188 | provided that You also comply with the requirements of this License for
189 | the Covered Software. If the Larger Work is a combination of Covered
190 | Software with a work governed by one or more Secondary Licenses, and the
191 | Covered Software is not Incompatible With Secondary Licenses, this
192 | License permits You to additionally distribute such Covered Software
193 | under the terms of such Secondary License(s), so that the recipient of
194 | the Larger Work may, at their option, further distribute the Covered
195 | Software under the terms of either this License or such Secondary
196 | License(s).
197 |
198 | 3.4. Notices
199 |
200 | You may not remove or alter the substance of any license notices
201 | (including copyright notices, patent notices, disclaimers of warranty,
202 | or limitations of liability) contained within the Source Code Form of
203 | the Covered Software, except that You may alter any license notices to
204 | the extent required to remedy known factual inaccuracies.
205 |
206 | 3.5. Application of Additional Terms
207 |
208 | You may choose to offer, and to charge a fee for, warranty, support,
209 | indemnity or liability obligations to one or more recipients of Covered
210 | Software. However, You may do so only on Your own behalf, and not on
211 | behalf of any Contributor. You must make it absolutely clear that any
212 | such warranty, support, indemnity, or liability obligation is offered by
213 | You alone, and You hereby agree to indemnify every Contributor for any
214 | liability incurred by such Contributor as a result of warranty, support,
215 | indemnity or liability terms You offer. You may include additional
216 | disclaimers of warranty and limitations of liability specific to any
217 | jurisdiction.
218 |
219 | 4. Inability to Comply Due to Statute or Regulation
220 | ---------------------------------------------------
221 |
222 | If it is impossible for You to comply with any of the terms of this
223 | License with respect to some or all of the Covered Software due to
224 | statute, judicial order, or regulation then You must: (a) comply with
225 | the terms of this License to the maximum extent possible; and (b)
226 | describe the limitations and the code they affect. Such description must
227 | be placed in a text file included with all distributions of the Covered
228 | Software under this License. Except to the extent prohibited by statute
229 | or regulation, such description must be sufficiently detailed for a
230 | recipient of ordinary skill to be able to understand it.
231 |
232 | 5. Termination
233 | --------------
234 |
235 | 5.1. The rights granted under this License will terminate automatically
236 | if You fail to comply with any of its terms. However, if You become
237 | compliant, then the rights granted under this License from a particular
238 | Contributor are reinstated (a) provisionally, unless and until such
239 | Contributor explicitly and finally terminates Your grants, and (b) on an
240 | ongoing basis, if such Contributor fails to notify You of the
241 | non-compliance by some reasonable means prior to 60 days after You have
242 | come back into compliance. Moreover, Your grants from a particular
243 | Contributor are reinstated on an ongoing basis if such Contributor
244 | notifies You of the non-compliance by some reasonable means, this is the
245 | first time You have received notice of non-compliance with this License
246 | from such Contributor, and You become compliant prior to 30 days after
247 | Your receipt of the notice.
248 |
249 | 5.2. If You initiate litigation against any entity by asserting a patent
250 | infringement claim (excluding declaratory judgment actions,
251 | counter-claims, and cross-claims) alleging that a Contributor Version
252 | directly or indirectly infringes any patent, then the rights granted to
253 | You by any and all Contributors for the Covered Software under Section
254 | 2.1 of this License shall terminate.
255 |
256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
257 | end user license agreements (excluding distributors and resellers) which
258 | have been validly granted by You or Your distributors under this License
259 | prior to termination shall survive termination.
260 |
261 | ************************************************************************
262 | * *
263 | * 6. Disclaimer of Warranty *
264 | * ------------------------- *
265 | * *
266 | * Covered Software is provided under this License on an "as is" *
267 | * basis, without warranty of any kind, either expressed, implied, or *
268 | * statutory, including, without limitation, warranties that the *
269 | * Covered Software is free of defects, merchantable, fit for a *
270 | * particular purpose or non-infringing. The entire risk as to the *
271 | * quality and performance of the Covered Software is with You. *
272 | * Should any Covered Software prove defective in any respect, You *
273 | * (not any Contributor) assume the cost of any necessary servicing, *
274 | * repair, or correction. This disclaimer of warranty constitutes an *
275 | * essential part of this License. No use of any Covered Software is *
276 | * authorized under this License except under this disclaimer. *
277 | * *
278 | ************************************************************************
279 |
280 | ************************************************************************
281 | * *
282 | * 7. Limitation of Liability *
283 | * -------------------------- *
284 | * *
285 | * Under no circumstances and under no legal theory, whether tort *
286 | * (including negligence), contract, or otherwise, shall any *
287 | * Contributor, or anyone who distributes Covered Software as *
288 | * permitted above, be liable to You for any direct, indirect, *
289 | * special, incidental, or consequential damages of any character *
290 | * including, without limitation, damages for lost profits, loss of *
291 | * goodwill, work stoppage, computer failure or malfunction, or any *
292 | * and all other commercial damages or losses, even if such party *
293 | * shall have been informed of the possibility of such damages. This *
294 | * limitation of liability shall not apply to liability for death or *
295 | * personal injury resulting from such party's negligence to the *
296 | * extent applicable law prohibits such limitation. Some *
297 | * jurisdictions do not allow the exclusion or limitation of *
298 | * incidental or consequential damages, so this exclusion and *
299 | * limitation may not apply to You. *
300 | * *
301 | ************************************************************************
302 |
303 | 8. Litigation
304 | -------------
305 |
306 | Any litigation relating to this License may be brought only in the
307 | courts of a jurisdiction where the defendant maintains its principal
308 | place of business and such litigation shall be governed by laws of that
309 | jurisdiction, without reference to its conflict-of-law provisions.
310 | Nothing in this Section shall prevent a party's ability to bring
311 | cross-claims or counter-claims.
312 |
313 | 9. Miscellaneous
314 | ----------------
315 |
316 | This License represents the complete agreement concerning the subject
317 | matter hereof. If any provision of this License is held to be
318 | unenforceable, such provision shall be reformed only to the extent
319 | necessary to make it enforceable. Any law or regulation which provides
320 | that the language of a contract shall be construed against the drafter
321 | shall not be used to construe this License against a Contributor.
322 |
323 | 10. Versions of the License
324 | ---------------------------
325 |
326 | 10.1. New Versions
327 |
328 | Mozilla Foundation is the license steward. Except as provided in Section
329 | 10.3, no one other than the license steward has the right to modify or
330 | publish new versions of this License. Each version will be given a
331 | distinguishing version number.
332 |
333 | 10.2. Effect of New Versions
334 |
335 | You may distribute the Covered Software under the terms of the version
336 | of the License under which You originally received the Covered Software,
337 | or under the terms of any subsequent version published by the license
338 | steward.
339 |
340 | 10.3. Modified Versions
341 |
342 | If you create software not governed by this License, and you want to
343 | create a new license for such software, you may create and use a
344 | modified version of this License if you rename the license and remove
345 | any references to the name of the license steward (except to note that
346 | such modified license differs from this License).
347 |
348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
349 | Licenses
350 |
351 | If You choose to distribute Source Code Form that is Incompatible With
352 | Secondary Licenses under the terms of this version of the License, the
353 | notice described in Exhibit B of this License must be attached.
354 |
355 | Exhibit A - Source Code Form License Notice
356 | -------------------------------------------
357 |
358 | This Source Code Form is subject to the terms of the Mozilla Public
359 | License, v. 2.0. If a copy of the MPL was not distributed with this
360 | file, You can obtain one at https://mozilla.org/MPL/2.0/.
361 |
362 | If it is not possible or desirable to put the notice in a particular
363 | file, then You may include the notice in a location (such as a LICENSE
364 | file in a relevant directory) where a recipient would be likely to look
365 | for such a notice.
366 |
367 | You may add additional accurate notices of copyright ownership.
368 |
369 | Exhibit B - "Incompatible With Secondary Licenses" Notice
370 | ---------------------------------------------------------
371 |
372 | This Source Code Form is "Incompatible With Secondary Licenses", as
373 | defined by the Mozilla Public License, v. 2.0.
--------------------------------------------------------------------------------
/Src/UMain.pas:
--------------------------------------------------------------------------------
1 | {
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at https://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 2004-2024, Peter Johnson (gravatar.com/delphidabbler).
7 | *
8 | * Implements a class that handles the HTML Resource Compiler's main program
9 | * processing.
10 | }
11 |
12 |
13 | unit UMain;
14 |
15 | {$WARN UNSAFE_TYPE OFF}
16 |
17 | interface
18 |
19 |
20 | uses
21 | // Delphi
22 | System.Classes,
23 | // Project
24 | UParams;
25 |
26 |
27 | type
28 |
29 | {
30 | TMain:
31 | Handles main program processing and traps and reports any exceptions.
32 | }
33 | TMain = class(TObject)
34 | private
35 | procedure BuildSourceFileList(const SrcFiles: TStringList);
36 | {Builds a list of all source files (i.e. those passed on command line and
37 | those from any manifest file).
38 | @param SrcFiles [in] List of source files built in method.
39 | @except EError raised with cErrMissingManifest error code if a
40 | specified file does not exist.
41 | }
42 | procedure CheckParamErrors;
43 | {Checks for existence of any command line parameters errors and raises
44 | exception if such errors exist.
45 | @except EError raised with cErrCommandLine error code if command line
46 | errors exist.
47 | }
48 | procedure CheckSourceFilesExist(const SrcFiles: TStringList);
49 | {Checks if all source files in given list exist and raises exception if
50 | not.
51 | @param SrcFiles [in] List of source files to check.
52 | @except EError raised with cErrMissingSourceFile error code if any
53 | source files don't exist.
54 | }
55 | procedure CheckDuplicateResNames(const SrcFiles: TStringList);
56 | {Checks all source file names for duplicates file names and raises
57 | exception if any found.
58 | @param SrcFiles [in] List of source file names (with paths) to be
59 | checked.
60 | @except EError raised with cErrDuplicateResource error code if any
61 | files have same name.
62 | }
63 | procedure CreateResourceFile(const SrcFiles: TStringList);
64 | {Creates required resource file containing all given source files as HTML
65 | resources.
66 | @param SrcFiles [in] List of source files to store in resources.
67 | }
68 | procedure DisplayHelp;
69 | {Writes out help on using program.
70 | }
71 | procedure SignOn;
72 | {Writes out sign-on message.
73 | }
74 | procedure SignOff;
75 | {Optionally displays a sign off message and gets user to press return to
76 | close program.
77 | }
78 | procedure WriteMsg(const Msg: string); overload;
79 | {Writes a message to output if permitted.
80 | @param Msg [in] Message to write.
81 | }
82 | procedure WriteMsg(const Fmt: string; const Args: array of const); overload;
83 | {Writes a messages made from a format string and arguments to output if
84 | permitted.
85 | @param Fmt [in] Format string.
86 | @param Args [in] Arguments that replace placeholders in format string.
87 | }
88 | procedure WriteErrMsg(const Msg: string);
89 | {Writes an error message to output if permitted.
90 | @param Msg [in] Message to write.
91 | }
92 | public
93 | procedure Execute;
94 | {Executes the main program code. Reads command line, processes source
95 | files and creates output file.
96 | }
97 | end;
98 |
99 |
100 | implementation
101 |
102 |
103 | uses
104 | // Delphi
105 | System.SysUtils,
106 | WinApi.Windows,
107 | // DelphiDabbler library
108 | PJResFile, PJVersionInfo,
109 | // Project
110 | UErrors, UVerInfo;
111 |
112 |
113 | const
114 | // End of line characters
115 | EOL = #13#10;
116 |
117 |
118 | resourcestring
119 | // Output strings
120 | sHelp = 'Usage: HTMLRes [] [-m] [-o] []'
121 | + EOL
122 | + EOL
123 | + ' = Zero or more input file names'
124 | + EOL
125 | + '-m = "Manifest" file containing list of input file names'
126 | + EOL
127 | + '-o = Output file name (default is "out.res")'
128 | + EOL
129 | + ' = Zero or more or the following:'
130 | + EOL
131 | + ' -r = Make all relative file names relative to manifest file'
132 | + ' directory'
133 | + EOL
134 | + ' (ignored if -m switch not specified before -r switch)'
135 | + EOL
136 | + ' -u = Determine how any pre-existing resource file is'
137 | + ' updated: -u is always'
138 | + EOL
139 | + ' immediately followed by :xxx where xxx is one of:'
140 | + EOL
141 | + ' * fail - halt program if output file exists'
142 | + EOL
143 | + ' * overwritefile - overwrite entire file (default)'
144 | + EOL
145 | + ' * insertres - insert resources into existing file'
146 | + ' (error if'
147 | + EOL
148 | + ' duplicate resources)'
149 | + EOL
150 | + ' * overwriteres - insert resources into existing file'
151 | + ' (duplicate'
152 | + EOL
153 | + ' resources are overwritten)'
154 | + EOL
155 | + ' If output file doesn''t exist then a new file is created'
156 | + EOL
157 | + ' -p = Pause at end of processing and wait for key press'
158 | + EOL
159 | + ' -q = Quiet mode: only error messages are output'
160 | + EOL
161 | + ' -Q = Very quiet mode: no screen output'
162 | + EOL
163 | + ' -h or -? = Display this help'
164 | + EOL
165 | + EOL
166 | + 'At least one input file or manifest file'
167 | + ' or -? switch must be specified.';
168 | sSignOnMsg = 'HTMLRes v%s' // inserts product version here
169 | + EOL
170 | + '%s'; // inserts copyright info here
171 | sProcessingSrcFile = 'Processing source file: "%s"';
172 | sOverwritingEntry = 'Overwriting resource entry: "%s"';
173 | sCreatingEntry = 'Creating resource entry: "%s"';
174 | sWritingResFile = 'Writing resource file: "%s"';
175 | sUsageMsg = 'Usage: HTMLRes [] [-m] [-o] []'
176 | + EOL
177 | + 'Use HTMLRes -? for help';
178 | sPressReturnMsg = 'Press return to end';
179 |
180 | // Error messages
181 | sError = 'ERROR:';
182 | sMissingManifestFile = 'Manifest file "%s" does not exist';
183 | sCommandLineErrPrefix = 'Command line error(s):';
184 | sMissingSrcFileErrPrefix = 'Source file(s) not found:';
185 | sDuplicateResName = 'Duplicate resource (file) names in files:';
186 | sOutFileExists = 'Output file "%s" already exists';
187 | sOutFileNotResFile = 'Output file "%s" is not a valid resource file';
188 | sResourceExists = 'Resource "%s" already exists in "%s"';
189 |
190 |
191 | { TMain }
192 |
193 | procedure TMain.BuildSourceFileList(const SrcFiles: TStringList);
194 | {Builds a list of all source files (i.e. those passed on command line and
195 | those from any manifest file).
196 | @param SrcFiles [in] List of source files built in method.
197 | @except EError raised with cErrMissingManifest error code if a
198 | specified file does not exist.
199 | }
200 | var
201 | I: Integer; // loops thru file lists
202 | ManFiles: TStringList; // list of files from manifest file
203 | ManFile: string; // a file from manifest file
204 | begin
205 | // Ensure source file list is sorted and ignores duplicate entries
206 | SrcFiles.Sorted := True;
207 | SrcFiles.Duplicates := dupIgnore;
208 | // Record files passed on command line
209 | for I := 0 to Pred(Params.InFileCount) do
210 | SrcFiles.Add(Params.InFiles[I]);
211 | // Read files from any manifest file
212 | if (Params.ManifestFile <> '') then
213 | begin
214 | if not FileExists(Params.ManifestFile) then
215 | raise EError.CreateFmt(
216 | sMissingManifestFile, [Params.ManifestFile], cErrMissingManifest
217 | );
218 | ManFiles := TStringList.Create;
219 | try
220 | // ** Unicode TStringList.LoadFromFile has default behaviour that it will
221 | // read UTF-8 or UTF-16 formatted manifest file providing they have a
222 | // suitable BOM or prefix. If there is no such prefix the file will be
223 | // assumed to be in the system default encoding.
224 | ManFiles.LoadFromFile(Params.ManifestFile);
225 | // process lines from manifest file (ignore blank and comment lines)
226 | for I := 0 to Pred(ManFiles.Count) do
227 | begin
228 | ManFile := Trim(ManFiles[I]);
229 | if (ManFile <> '') and (ManFile[1] <> '#') then
230 | SrcFiles.Add(ManFile);
231 | end;
232 | finally
233 | FreeAndNil(ManFiles);
234 | end;
235 | end;
236 | end;
237 |
238 | procedure TMain.CheckDuplicateResNames(const SrcFiles: TStringList);
239 | {Checks all source file names for duplicates file names and raises
240 | exception if any found.
241 | @param SrcFiles [in] List of source file names (with paths) to be
242 | checked.
243 | @except EError raised with cErrDuplicateResource error code if any
244 | files have same name.
245 | }
246 | var
247 | ResNames: TStringList; // list of resource names
248 | ResName: string; // a resource name
249 | Duplicates: TStringList; // list of duplicate file (resource) names
250 | I: Integer; // loops thru string lists
251 | Msg: string; // used to build error message
252 | begin
253 | Duplicates := nil;
254 | ResNames := TStringList.Create;
255 | try
256 | Duplicates := TStringList.Create;
257 | // loop thru input source files checking for duplicate file names
258 | for I := 0 to Pred(SrcFiles.Count) do
259 | begin
260 | ResName := UpperCase(ExtractFileName(SrcFiles[I]));
261 | if ResNames.IndexOf(ResName) = -1 then
262 | ResNames.Add(ResName)
263 | else
264 | Duplicates.Add(ResName); // we have duplicate - record it
265 | end;
266 | // Raise exception if duplicates detected
267 | if Duplicates.Count > 0 then
268 | begin
269 | Msg := sDuplicateResName;
270 | for I := 0 to Pred(Duplicates.Count) do
271 | Msg := Msg + EOL + ' ' + Duplicates[I];
272 | raise EError.Create(Msg, cErrDuplicateResource);
273 | end;
274 | finally
275 | FreeAndNil(Duplicates);
276 | FreeAndNil(ResNames);
277 | end;
278 | end;
279 |
280 | procedure TMain.CheckParamErrors;
281 | {Checks for existence of any command line parameters errors and raises
282 | exception if such errors exist.
283 | @except EError raised with cErrCommandLine error code if command line
284 | errors exist.
285 | }
286 | var
287 | I: Integer; // loops thru errors
288 | Msg: string; // error message
289 | begin
290 | if Params.ErrorCount > 0 then
291 | begin
292 | Msg := sCommandLineErrPrefix;
293 | for I := 0 to Pred(Params.ErrorCount) do
294 | Msg := Msg + EOL + ' ' + Params.Errors[I];
295 | raise EError.Create(Msg, cErrCommandLine);
296 | end;
297 | end;
298 |
299 | procedure TMain.CheckSourceFilesExist(const SrcFiles: TStringList);
300 | {Checks if all source files in given list exist and raises exception if
301 | not.
302 | @param SrcFiles [in] List of source files to check.
303 | @except EError raised with cErrMissingSourceFile error code if any
304 | source files don't exist.
305 | }
306 | var
307 | I: Integer; // loops thru string lists
308 | FileName: string; // a source file name
309 | BadFiles: TStringList; // list of source files that don't exist
310 | ErrMsg: string; // error message
311 | begin
312 | // Store names of all source files that don't exist in bad file list
313 | BadFiles := TStringList.Create;
314 | try
315 | for I := 0 to Pred(SrcFiles.Count) do
316 | begin
317 | FileName := SrcFiles[I];
318 | if not FileExists(FileName) then
319 | BadFiles.Add(FileName);
320 | end;
321 | // If we have bad files raise exception with message listing all such files
322 | if BadFiles.Count > 0 then
323 | begin
324 | ErrMsg := sMissingSrcFileErrPrefix;
325 | for I := 0 to Pred(BadFiles.Count) do
326 | ErrMsg := ErrMsg + EOL + ' ' + BadFiles[I];
327 | raise EError.Create(ErrMsg, cErrMissingSourceFile);
328 | end;
329 | finally
330 | FreeAndNil(BadFiles);
331 | end;
332 | end;
333 |
334 | procedure TMain.CreateResourceFile(const SrcFiles: TStringList);
335 | {Creates required resource file containing all given source files as HTML
336 | resources.
337 | @param SrcFiles [in] List of source files to store in resources.
338 | @except EError raised with various error codes if error conditions
339 | encountered.
340 | }
341 |
342 | // ---------------------------------------------------------------------------
343 | procedure HandleExistingResFile(const ResFile: TPJResourceFile);
344 | {Determines how to deal with a pre-existing resource file depending on
345 | configuration.
346 | @param ResFile [in] object encapsulating contents of resource file.
347 | @except EError raised with cErrOutFileExists error code if we are to fail
348 | program if output file exists.
349 | @except EError raised with cErrBadOutFile error code if file is to be
350 | updated and is not a valid resource file.
351 | }
352 | var
353 | ResFileStm: TFileStream; // stream used to read existing resource file
354 | begin
355 | // Action depends on configuration stored in parameter object's
356 | // FileUpdateAction property:
357 | // uaFail: program fails if output file already exists
358 | // uaOverwriteFile: output file is overwritten
359 | // uaInsertRes: inserts resource into existing file: program fails if
360 | // resource already exists
361 | // uaOverwriteRes: inserts resource into existing file: existing resources
362 | // are overwritten
363 | ResFile.Clear;
364 | if Params.FileUpdateAction = uaFail then
365 | raise EError.CreateFmt(
366 | sOutFileExists, [Params.OutFile], cErrOutFileExists
367 | );
368 | if Params.FileUpdateAction in [uaInsertRes, uaOverwriteRes] then
369 | begin
370 | // We need to update content of existing file
371 | ResFileStm := TFileStream.Create(
372 | Params.OutFile, fmOpenRead or fmShareDenyNone
373 | );
374 | try
375 | // load file if it is a valid resource file
376 | if not TPJResourceFile.IsValidResourceStream(ResFileStm) then
377 | raise EError.CreateFmt(
378 | sOutFileNotResFile, [Params.OutFile], cErrBadOutFile
379 | );
380 | ResFileStm.Position := 0;
381 | ResFile.LoadFromStream(ResFileStm);
382 | finally
383 | FreeAndNil(ResFileStm);
384 | end;
385 | end;
386 | end;
387 |
388 | function GetResourceEntry(const ResFile: TPJResourceFile;
389 | const ResName: string): TPJResourceEntry;
390 | {Gets resource entry for a resource name. Resource is created if it doesn't
391 | already exist. Resource has no content.
392 | @param ResFile [in] object encapsulating contents of resource file.
393 | @param ResName [in] name of required resource.
394 | @except EError raised with cErrResourceExists if resource exists in output
395 | file and we're inserting resources into file without overwriting
396 | duplicate resources.
397 | }
398 | begin
399 | // Assume we have no resource entry
400 | Result := nil;
401 | if Params.FileUpdateAction in [uaInsertRes, uaOverwriteRes] then
402 | begin
403 | // We are updating content of resource file
404 | if ResFile.EntryExists(RT_HTML, PChar(ResName), 0) then
405 | begin
406 | // Matching resource already exists in resource file
407 | if Params.FileUpdateAction = uaInsertRes then
408 | // we're inserting without overwriting existing resource entries:
409 | // this is an error
410 | raise EError.CreateFmt(
411 | sResourceExists, [ResName, Params.OutFile], cErrResourceExists
412 | );
413 | // we're inserting and overwriting existing resource entries: get
414 | // reference to existing entry
415 | WriteMsg(sOverwritingEntry, [ResName]);
416 | Result := ResFile.FindEntry(RT_HTML, PChar(ResName), 0);
417 | Result.Data.Size := 0;
418 | end;
419 | end;
420 | if not Assigned(Result) then
421 | begin
422 | // We haven't found matching entry: create a new one
423 | WriteMsg(sCreatingEntry, [ResName]);
424 | Result := ResFile.AddEntry(RT_HTML, PChar(ResName), 0);
425 | end;
426 | // Set entry's flags
427 | Result.MemoryFlags := RES_MF_MOVEABLE or RES_MF_PURE;
428 | end;
429 |
430 | procedure CopySourceFileToResourceEntry(const ResEntry: TPJResourceEntry;
431 | const SrcFileName: string);
432 | {Copies contents of a source file into a resource entry.
433 | @param ResEntry [in] Entry to receive source file contents.
434 | @param SrcFileName [in] Name of source file providing content.
435 | }
436 | var
437 | SrcFileStm: TFileStream; // read stream onto source file
438 | begin
439 | SrcFileStm := TFileStream.Create(
440 | SrcFileName, fmOpenRead or fmShareDenyNone
441 | );
442 | try
443 | ResEntry.Data.CopyFrom(SrcFileStm, 0);
444 | finally
445 | FreeAndNil(SrcFileStm);
446 | end;
447 | end;
448 |
449 | procedure WriteResourceFile(const ResFile: TPJResourceFile);
450 | {Writes completed resource file data to output file.
451 | @param ResFile [in] object encapsulating contents of resource file.
452 | }
453 | var
454 | OutFileStm: TFileStream; // write stream onto output file
455 | begin
456 | WriteMsg(sWritingResFile, [Params.OutFile]);
457 | OutFileStm := TFileStream.Create(Params.OutFile, fmCreate);
458 | try
459 | ResFile.SaveToStream(OutFileStm);
460 | finally
461 | FreeAndNil(OutFileStm);
462 | end;
463 | end;
464 | // ---------------------------------------------------------------------------
465 |
466 | var
467 | ResFile: TPJResourceFile; // object used to write resource file
468 | SrcFileName: string; // name of a source file
469 | ResEntry: TPJResourceEntry; // object used to for each resource entry in file
470 | ResName: string; // name of a resource
471 | I: Integer; // loops thru all
472 | begin
473 | // Create empty resource file
474 | ResFile := TPJResourceFile.Create;
475 | try
476 | // If output file already exists decide how to handle it
477 | if FileExists(Params.OutFile) then
478 | HandleExistingResFile(ResFile); // this may load existing resource file
479 | // Process each source file, adding to resource file
480 | for I := 0 to Pred(SrcFiles.Count) do
481 | begin
482 | SrcFileName := SrcFiles[I];
483 | WriteMsg(sProcessingSrcFile, [SrcFileName]);
484 | ResName := ExtractFileName(UpperCase(SrcFileName));
485 | ResEntry := GetResourceEntry(ResFile, ResName);
486 | CopySourceFileToResourceEntry(ResEntry, SrcFileName);
487 | end;
488 | WriteResourceFile(ResFile);
489 | finally
490 | FreeAndNil(ResFile);
491 | end;
492 | end;
493 |
494 | procedure TMain.DisplayHelp;
495 | {Writes out help on using program.
496 | }
497 | begin
498 | WriteLn(sHelp);
499 | end;
500 |
501 | procedure TMain.Execute;
502 | {Executes the main program code. Reads command line, processes source
503 | files and creates output file.
504 | }
505 | var
506 | SrcFiles: TStringList; // stores list of source files
507 | begin
508 | try
509 | SignOn; // displays sign-on message
510 | CheckParamErrors; // raises exception if parameters not valid
511 | if not Params.Help then
512 | begin
513 | // Do main processing
514 | SrcFiles := TStringList.Create;
515 | try
516 | BuildSourceFileList(SrcFiles); // exception if manifest doesn't exist
517 | CheckDuplicateResNames(SrcFiles); // exception on duplicates
518 | CheckSourceFilesExist(SrcFiles); // exception if file doesn't exist
519 | CreateResourceFile(SrcFiles);
520 | finally
521 | FreeAndNil(SrcFiles);
522 | end;
523 | end
524 | else
525 | // Help command line switch present
526 | DisplayHelp;
527 | except
528 | // Report any errors
529 | on E: EError do
530 | begin
531 | WriteErrMsg(E.Message);
532 | ExitCode := E.ErrorCode;
533 | end;
534 | on E: Exception do
535 | begin
536 | WriteErrMsg(E.Message);
537 | ExitCode := cErrUnexpected;
538 | end;
539 | end;
540 | SignOff;
541 | end;
542 |
543 | procedure TMain.SignOff;
544 | {Optionally displays a sign off message and gets user to press return to
545 | close program.
546 | }
547 | begin
548 | // Only display sign-off message if required by -p command line switch
549 | if Params.Pause then
550 | begin
551 | WriteLn;
552 | Write(sPressReturnMsg);
553 | ReadLn;
554 | end;
555 | end;
556 |
557 | procedure TMain.SignOn;
558 | {Writes out sign-on message.
559 | }
560 | begin
561 | WriteMsg(sSignOnMsg, [GetProductVersionStr, GetCopyrightStr]);
562 | WriteMsg('');
563 | end;
564 |
565 | procedure TMain.WriteErrMsg(const Msg: string);
566 | {Writes an error message to output if permitted.
567 | @param Msg [in] Message to write.
568 | }
569 | begin
570 | // Write actual error message if quietness level not silent
571 | if Params.Quietness <> qsSilent then
572 | WriteLn(sError, ' ', Msg);
573 | // And write following usage message only quietness levels are off
574 | WriteMsg('');
575 | WriteMsg(sUsageMsg);
576 | end;
577 |
578 | procedure TMain.WriteMsg(const Msg: string);
579 | {Writes a message to output if permitted.
580 | @param Msg [in] Message to write.
581 | }
582 | begin
583 | // Only write if quietness levels are off
584 | if Params.Quietness = qsOff then
585 | WriteLn(Msg);
586 | end;
587 |
588 | procedure TMain.WriteMsg(const Fmt: string; const Args: array of const);
589 | {Writes a messages made from a format string and arguments to output if
590 | permitted.
591 | @param Fmt [in] Format string.
592 | @param Args [in] Arguments that replace placeholders in format string.
593 | }
594 | begin
595 | WriteMsg(Format(Fmt, Args));
596 | end;
597 |
598 | end.
599 |
600 |
--------------------------------------------------------------------------------
/Src/HTMLRes.dproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {250E76DD-D3BA-4F99-A9C5-3032617831C0}
4 | HTMLRes.dpr
5 | True
6 | Release
7 | Console
8 | None
9 | DCC32
10 | 20.1
11 | Win32
12 | HTMLRes
13 | 1
14 |
15 |
16 | true
17 |
18 |
19 | true
20 | Base
21 | true
22 |
23 |
24 | true
25 | Base
26 | true
27 |
28 |
29 | true
30 | Base
31 | true
32 |
33 |
34 | true
35 | Base
36 | true
37 |
38 |
39 | true
40 | Base
41 | true
42 |
43 |
44 | true
45 | Base
46 | true
47 |
48 |
49 | true
50 | Cfg_1
51 | true
52 | true
53 |
54 |
55 | true
56 | Base
57 | true
58 |
59 |
60 | true
61 | Cfg_2
62 | true
63 | true
64 |
65 |
66 | ..\_build\bin;$(DCC_UnitSearchPath)
67 | 00400000
68 | 1
69 | .
70 | ..\_build\exe
71 | ..\_build\bin
72 | true
73 | false
74 | .
75 | false
76 | false
77 | false
78 | HTMLRes
79 | 2057
80 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=
81 | $(BDS)\bin\delphi_PROJECTICON.ico
82 |
86 | $(BDS)\bin\delphi_PROJECTICNS.icns
87 |
90 |
91 |
92 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png
93 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png
94 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png
95 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png
96 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png
97 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png
98 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png
99 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png
100 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png
101 | true
102 | true
103 | true
104 | true
105 | true
106 | true
107 | true
108 | true
109 | true
110 | true
111 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png
112 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png
113 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png
114 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png
115 | $(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png
116 |
117 |
118 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
119 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
120 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png
121 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png
122 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
123 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png
124 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
125 |
126 |
127 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
128 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
129 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png
130 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png
131 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
132 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png
133 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
134 |
135 |
136 | $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png
137 | $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png
138 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_40x40.png
139 | $(BDS)\bin\Artwork\iOS\iPhone\FM_NotificationIcon_60x60.png
140 | $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png
141 | $(BDS)\bin\Artwork\iOS\iPad\FM_NotificationIcon_40x40.png
142 | $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png
143 |
144 |
145 | Debug
146 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
147 | 1033
148 | (None)
149 | none
150 |
151 |
152 | false
153 | RELEASE;$(DCC_Define)
154 | 0
155 | 0
156 |
157 |
158 | 1033
159 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
160 |
161 |
162 | DEBUG;$(DCC_Define)
163 | false
164 | true
165 |
166 |
167 | 1033
168 | CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName)
169 |
170 |
171 |
172 | MainSource
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | Base
182 |
183 |
184 | Cfg_1
185 | Base
186 |
187 |
188 | Cfg_2
189 | Base
190 |
191 |
192 |
193 |
194 |
195 | Delphi.Personality.12
196 | VCLApplication
197 |
198 |
199 |
200 | HTMLRes.dpr
201 |
202 |
203 | False
204 | False
205 | 1
206 | 0
207 | 0
208 | 0
209 | False
210 | False
211 | False
212 | False
213 | False
214 | 2057
215 | 1252
216 |
217 |
218 |
219 |
220 | 1.0.0.0
221 |
222 |
223 |
224 |
225 |
226 | 1.0.0.0
227 |
228 |
229 |
230 | Microsoft Office 2000 Sample Automation Server Wrapper Components
231 | Microsoft Office XP Sample Automation Server Wrapper Components
232 | Embarcadero C++Builder Office 2000 Servers Package
233 | Embarcadero C++Builder Office XP Servers Package
234 |
235 |
236 |
237 | False
238 | False
239 | False
240 | False
241 | False
242 | False
243 | True
244 | False
245 |
246 |
247 | 12
248 |
249 |
250 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
251 | False
252 |
253 | False
254 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
255 | False
256 |
257 |
258 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
259 | False
260 |
261 | False
262 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
263 | False
264 |
265 |
266 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
267 | False
268 |
269 | False
270 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
271 | False
272 |
273 |
274 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
275 | False
276 |
277 | False
278 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
279 | False
280 |
281 |
282 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
283 | False
284 |
285 | False
286 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
287 | False
288 |
289 |
290 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
291 | False
292 |
293 | False
294 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
295 | False
296 |
297 |
298 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
299 | False
300 |
301 | False
302 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
303 | False
304 |
305 |
306 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
307 | False
308 |
309 | False
310 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
311 | False
312 |
313 |
314 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
315 | False
316 |
317 | False
318 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
319 | False
320 |
321 |
322 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
323 | False
324 |
325 | False
326 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
327 | False
328 |
329 |
330 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
331 | False
332 |
333 | False
334 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
335 | False
336 |
337 |
338 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
339 | False
340 |
341 | False
342 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
343 | False
344 |
345 |
346 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
347 | False
348 |
349 | False
350 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
351 | False
352 |
353 |
354 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
355 | False
356 |
357 | False
358 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
359 | False
360 |
361 |
362 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
363 | False
364 |
365 | False
366 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
367 | False
368 |
369 |
370 | "$(VIEDROOT)\VIEd.exe" -makerc .\VHTMLRes.vi .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\VHTMLRes.res" .\VHTMLRes.virc&&"$(BDSBIN)\BRCC32" -fo "..\_build\bin\HTMLRes.res" .\HTMLRes.rc
371 | False
372 |
373 | False
374 | DEL .\VHTMLRes.virc&&DEL .\HTMLRES.res
375 | False
376 |
377 |
378 |
--------------------------------------------------------------------------------
/Src/Vendor/PJVersionInfo.pas:
--------------------------------------------------------------------------------
1 | {
2 | * This Source Code Form is subject to the terms of the Mozilla Public License,
3 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4 | * obtain one at http://mozilla.org/MPL/2.0/
5 | *
6 | * Copyright (C) 1998-2014, Peter Johnson (www.delphidabbler.com).
7 | *
8 | * $Rev: 1515 $
9 | * $Date: 2014-01-11 02:36:28 +0000 (Sat, 11 Jan 2014) $
10 | *
11 | * Version Information Component. The component reads version information from
12 | * executable files.
13 | }
14 |
15 |
16 | unit PJVersionInfo;
17 |
18 | // Determine if certain features are supported by compiler
19 | // * Supports_Assert - Defined if assertions supported (all compilers
20 | // except Delphi 2).
21 | // * Supports_ResourceString - Defined if resourcestring keyword supported (all
22 | // compilers except Delphi 2).
23 | // * Supports_AdvancedRecords - Defined if advanced records with record methods,
24 | // operator overloads etc. supported (Delphi 2006
25 | // and later).
26 | // * Supports_RTLNameSpaces - Defined if Delphi RTL / VCL unit references
27 | // should be qualified with namespaces.
28 | {$DEFINE Supports_Assert}
29 | {$DEFINE Supports_ResourceString}
30 | {$UNDEF Supports_AdvancedRecords}
31 | {$UNDEF Supports_RTLNameSpaces}
32 | {$IFDEF VER90} // Delphi 2
33 | {$UNDEF Supports_Assert}
34 | {$UNDEF Supports_ResourceString}
35 | {$ENDIF}
36 | // Switch off unsafe code warnings if switch supported
37 | {$IFDEF CONDITIONALEXPRESSIONS}
38 | {$IF CompilerVersion >= 24.0} // Delphi XE3 and later
39 | {$LEGACYIFEND ON} // NOTE: this must come before all $IFEND directives
40 | {$IFEND}
41 | {$IF CompilerVersion >= 23.0} // Delphi XE2 and later
42 | {$DEFINE Supports_RTLNameSpaces}
43 | {$IFEND}
44 | {$IF CompilerVersion >= 18.0} // Delphi 2006 and later
45 | {$DEFINE Supports_AdvancedRecords}
46 | {$IFEND}
47 | {$IF CompilerVersion >= 15.0} // Delphi 7 and later
48 | {$WARN UNSAFE_CODE OFF}
49 | {$IFEND}
50 | {$ENDIF}
51 |
52 | interface
53 |
54 |
55 | uses
56 | // Delphi
57 | {$IFDEF Supports_RTLNameSpaces}
58 | Winapi.Windows, System.Classes;
59 | {$ELSE}
60 | Windows, Classes;
61 | {$ENDIF}
62 |
63 |
64 | type
65 |
66 | {
67 | TPJVersionNumber:
68 | Record that encapsulates version numbers.
69 | }
70 | TPJVersionNumber = record
71 | V1: Word; // Major version number
72 | V2: Word; // Minor version number
73 | V3: Word; // Revision version number
74 | V4: Word; // Build number
75 | {$IFDEF Supports_AdvancedRecords}
76 | class operator Implicit(Ver: TPJVersionNumber): string;
77 | {Operator overload that performs implicit conversion of TPJVersionNumber
78 | to string as dotted quad.
79 | @param Ver [in] Version number to be converted.
80 | @return Version number as dotted quad.
81 | }
82 | class operator LessThanOrEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
83 | {Operator overload that compares two version numbers to check if first is
84 | less than or equal to the second.
85 | @param Ver1 [in] First version number.
86 | @param Ver2 [in] Second version number.
87 | @return True if Ver1 <= Ver2, False otherwise.
88 | }
89 | class operator LessThan(Ver1, Ver2: TPJVersionNumber): Boolean;
90 | {Operator overload that compares two version numbers to check if first is
91 | less than second.
92 | @param Ver1 [in] First version number.
93 | @param Ver2 [in] Second version number.
94 | @return True if Ver1 < Ver2, False otherwise.
95 | }
96 | class operator GreaterThan(Ver1, Ver2: TPJVersionNumber): Boolean;
97 | {Operator overload that compares two version numbers to check if first is
98 | greater than second.
99 | @param Ver1 [in] First version number.
100 | @param Ver2 [in] Second version number.
101 | @return True if Ver1 > Ver2, False otherwise.
102 | }
103 | class operator GreaterThanOrEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
104 | {Operator overload that compares two version numbers to check if first is
105 | greater than or equal to the second.
106 | @param Ver1 [in] First version number.
107 | @param Ver2 [in] Second version number.
108 | @return True if Ver1 >= Ver2, False otherwise.
109 | }
110 | class operator Equal(Ver1, Ver2: TPJVersionNumber): Boolean;
111 | {Operator overload that compares two version numbers to check for
112 | equality.
113 | @param Ver1 [in] First version number.
114 | @param Ver2 [in] Second version number.
115 | @return True if Ver1 = Ver2, False otherwise.
116 | }
117 | class operator NotEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
118 | {Operator overload that compares two version numbers to check for
119 | inequality.
120 | @param Ver1 [in] First version number.
121 | @param Ver2 [in] Second version number.
122 | @return True if Ver1 <> Ver2, False otherwise.
123 | }
124 | {$ENDIF}
125 | end;
126 |
127 | {
128 | TPJVersionInfo:
129 | Component that accesses the version information embedded in an executable
130 | file and exposes the information as properties. Supports multi-lingual
131 | version iformation resources.
132 | }
133 | TPJVersionInfo = class(TComponent)
134 | private // properties
135 | fFileName: string;
136 | fHaveInfo: Boolean;
137 | fNumTranslations: Integer;
138 | fCurrentTranslation: Integer;
139 | fFixedFileInfo: TVSFixedFileInfo;
140 | procedure SetFileName(AName: string);
141 | function GetProductVersionNumber: TPJVersionNumber;
142 | function GetFileVersionNumber: TPJVersionNumber;
143 | function GetLanguage: string;
144 | function GetCharSet: string;
145 | function GetCharSetCode: WORD;
146 | function GetLanguageCode: WORD;
147 | function GetCurrentTranslation: Integer;
148 | procedure SetCurrentTranslation(const Value: Integer);
149 | function GetStringFileInfo(const Name: string): string;
150 | function GetStringFileInfoByIdx(Index: Integer): string;
151 | function GetFixedFileInfoItemByIdx(Index: Integer): DWORD;
152 | private
153 | fPInfoBuffer: PChar; // Pointer to info buffer
154 | fPTransBuffer: Pointer; // Pointer to translation buffer
155 | procedure GetInfoBuffer(Len: DWORD);
156 | {Creates an info buffer of required size.
157 | @param Len [in] Required buffer size in characters.
158 | }
159 | procedure GetTransBuffer(Len: UINT);
160 | {Creates a translation table buffer of required size.
161 | @param Required buffer size in bytes.
162 | }
163 | function GetTransStr: string;
164 | {Encodes information about the current translation in a string.
165 | @return Required translation information.
166 | }
167 | protected
168 | procedure ClearProperties; virtual;
169 | {Forces properties to return cleared values.
170 | }
171 | procedure ReadVersionInfo; virtual;
172 | {Reads version info from file named by FileName property.
173 | }
174 | public
175 | constructor Create(AOwner: TComponent); override;
176 | {Object constructor. Sets default values.
177 | @param AOwner [in] Component that owns this one. May be nil.
178 | }
179 | destructor Destroy; override;
180 | {Object destructor. Frees allocated memory.
181 | }
182 | property HaveInfo: Boolean
183 | read fHaveInfo;
184 | {Property true if file version info for the file named by the FileName
185 | property has been successfully read}
186 | property FixedFileInfo: TVSFixedFileInfo
187 | read fFixedFileInfo;
188 | {Exposes the whole fixed file info record. Following properties expose
189 | the various fields of it}
190 | property FileVersionNumber: TPJVersionNumber
191 | read GetFileVersionNumber;
192 | {Version number of file in numeric format. From fixed file info}
193 | property ProductVersionNumber: TPJVersionNumber
194 | read GetProductVersionNumber;
195 | {Version number of product in numeric format. From fixed file info}
196 | property FileOS: DWORD index 0
197 | read GetFixedFileInfoItemByIdx;
198 | {Code describing operating system to be used by file, From fixed file
199 | info}
200 | property FileType: DWORD index 1
201 | read GetFixedFileInfoItemByIdx;
202 | {Code descibing type of file. From fixed file info}
203 | property FileSubType: DWORD index 2
204 | read GetFixedFileInfoItemByIdx;
205 | {Code describing sub-type of file - only used for certain values of
206 | FileType property. From fixed file info}
207 | property FileFlagsMask: DWORD index 3
208 | read GetFixedFileInfoItemByIdx;
209 | {Code describing which FileFlags are valid. From fixed file info}
210 | property FileFlags: DWORD index 4
211 | read GetFixedFileInfoItemByIdx;
212 | {Flags describing file state. From fixed file info}
213 | property Comments: string index 0
214 | read GetStringFileInfoByIdx;
215 | {String file info property giving user defined comments in current
216 | translation}
217 | property CompanyName: string index 1
218 | read GetStringFileInfoByIdx;
219 | {String file info property giving name of company in current translation}
220 | property FileDescription: string index 2
221 | read GetStringFileInfoByIdx;
222 | {String file info property giving description of file in current
223 | translation}
224 | property FileVersion: string index 3
225 | read GetStringFileInfoByIdx;
226 | {String file info property giving version number of file in string format
227 | in current translation}
228 | property InternalName: string index 4
229 | read GetStringFileInfoByIdx;
230 | {String file info property giving internal name of file in current
231 | translation}
232 | property LegalCopyright: string index 5
233 | read GetStringFileInfoByIdx;
234 | {String file info property giving copyright message in current
235 | translation}
236 | property LegalTrademarks: string index 6
237 | read GetStringFileInfoByIdx;
238 | {String file info property giving trademark info in current translation}
239 | property OriginalFileName: string index 7
240 | read GetStringFileInfoByIdx;
241 | {String file info property giving original name of file in current
242 | translation}
243 | property PrivateBuild: string index 8
244 | read GetStringFileInfoByIdx;
245 | {String file info property giving information about a private build of
246 | file in current translation}
247 | property ProductName: string index 9
248 | read GetStringFileInfoByIdx;
249 | {String file info property giving name of product in current translation}
250 | property ProductVersion: string index 10
251 | read GetStringFileInfoByIdx;
252 | {String file info property giving version number of product in string
253 | format in current translation}
254 | property SpecialBuild: string index 11
255 | read GetStringFileInfoByIdx;
256 | {String file info property giving information about a special build of
257 | file in current translation}
258 | property StringFileInfo[const Name: string]: string
259 | read GetStringFileInfo;
260 | {Value of named string file info item in current translation. This
261 | property can access both standard and custom string info}
262 | property Language: string
263 | read GetLanguage;
264 | {Name of language in use in current translation}
265 | property CharSet: string
266 | read GetCharSet;
267 | {Name of character set in use in current translation}
268 | property LanguageCode: WORD
269 | read GetLanguageCode;
270 | {Code of laguage in use in current translation}
271 | property CharSetCode: WORD
272 | read GetCharSetCode;
273 | {Code of character set in use in current translation}
274 | property NumTranslations: Integer
275 | read fNumTranslations;
276 | {The number of difference translations (ie languages and char sets) in
277 | the version information}
278 | property CurrentTranslation: Integer
279 | read GetCurrentTranslation write SetCurrentTranslation;
280 | {Zero-based index of the current translation: this is 0 when a file is
281 | first accessed. Set to a value in range 0..NumTranslations-1 to access
282 | other translations. All string info, language and char set properties
283 | return information for the current translation}
284 | published
285 | property FileName: string read fFileName write SetFileName;
286 | {Name of file containing version information. If set to '' (default) the
287 | version information comes from the containing executable file}
288 | end;
289 |
290 | function VerNumToStr(const Ver: TPJVersionNumber): string;
291 | {Converts a version number to its string representation as a dotted quad.
292 | @param Ver [in] Version number to be converted.
293 | @return Version number as dotted quad.
294 | }
295 |
296 | function CompareVerNums(const Ver1, Ver2: TPJVersionNumber): Integer;
297 | {Compares two version numbers and returns a value indicating if the first is
298 | less than, equal to or greater than the second.
299 | @param Ver1 [in] First version number to compare.
300 | @param Ver2 [in] Second version number to compare.
301 | @return 0 if Ver1 = Ver2, -ve if Ver1 < Ver2, +ve if Ver1 > Ver2.
302 | }
303 |
304 | procedure Register;
305 | {Registers this component.
306 | }
307 |
308 |
309 | implementation
310 |
311 |
312 | uses
313 | {$IFDEF Supports_RTLNameSpaces}
314 | System.SysUtils;
315 | {$ELSE}
316 | // Delphi
317 | SysUtils;
318 | {$ENDIF}
319 |
320 |
321 | procedure Register;
322 | {Registers this component.
323 | }
324 | begin
325 | RegisterComponents('DelphiDabbler', [TPJVersionInfo]);
326 | end;
327 |
328 | type
329 | // ANSI version of CPINFOEX: provides information about a code page
330 | _cpinfoexA = packed record
331 | MaxCharSize: UINT;
332 | {max length in bytes of a character in the code page}
333 | DefaultChar: array[0..MAX_DEFAULTCHAR-1] of Byte;
334 | {default character used to translate strings to the specific code page}
335 | LeadByte: array[0..MAX_LEADBYTES-1] of Byte;
336 | {fixed-length array of lead byte ranges: all elements null if none}
337 | UnicodeDefaultChar: WideChar;
338 | {unicode default char used in translations from the specific code page}
339 | CodePage: UINT;
340 | {code page value}
341 | CodePageName: array[0..MAX_PATH-1] of AnsiChar;
342 | {full localised name of the code page}
343 | end;
344 | CPINFOEXA = _cpinfoexA;
345 | PCPInfoExA = ^CPINFOEXA;
346 | TCPInfoExA = CPINFOEXA;
347 |
348 | // Unicode version of CPINFOEX: provides information about a code page
349 | _cpinfoexW = packed record
350 | MaxCharSize: UINT;
351 | {max length in bytes of a character in the code page}
352 | DefaultChar: array[0..MAX_DEFAULTCHAR-1] of Byte;
353 | {default character used to translate strings to the specific code page}
354 | LeadByte: array[0..MAX_LEADBYTES-1] of Byte;
355 | {fixed-length array of lead byte ranges: all elements null if none}
356 | UnicodeDefaultChar: WideChar;
357 | {unicode default char used in translations from the specific code page}
358 | CodePage: UINT;
359 | {code page value}
360 | CodePageName: array[0..MAX_PATH-1] of WideChar;
361 | {full localised name of the code page}
362 | end;
363 | CPINFOEXW = _cpinfoexW;
364 | PCPInfoExW = ^CPINFOEXW;
365 | TCPInfoExW = CPINFOEXW;
366 |
367 | // Set TCPInfoEx etc to required ANSI or Unicode version of structure
368 | {$IFDEF UNICODE}
369 | TCPInfoEx = TCPInfoExW;
370 | PCPInfoEx = PCPInfoExW;
371 | {$ELSE}
372 | TCPInfoEx = TCPInfoExA;
373 | PCPInfoEx = PCPInfoExA;
374 | {$ENDIF}
375 | CPINFOEX = TCPInfoEx;
376 |
377 | var
378 | // Pointer to Windows API GetCPInfoEx function if it exists or to GetCPInfoAlt
379 | // otherwise
380 | GetCPInfoExFn: function (CodePage: UINT; dwFlags: DWORD;
381 | var lpCPInfoEx: TCPInfoEx): BOOL; stdcall;
382 |
383 | const
384 | // Import name of GetCPInfoEx. Unicode and ANSI versions.
385 | {$IFDEF UNICODE}
386 | cGetCPInfoEx = 'GetCPInfoExW';
387 | {$ELSE}
388 | cGetCPInfoEx = 'GetCPInfoExA';
389 | {$ENDIF}
390 |
391 | function GetCPInfoAlt(CodePage: UINT; dwFlags: DWORD;
392 | var lpCPInfoEx: TCPInfoEx): BOOL; stdcall;
393 | {Local implementation of GetCPInfoEx, for use on OSs that don't support
394 | GetCPInfoEx. Calls older GetCPInfo API function and calculates members of
395 | TCPInfoEx not provided by GetCPInfo.
396 | @param CodePage [in] Code page for which information is required.
397 | @param dwFlags [in] Reserved. Must be 0.
398 | @param lpCPInfoEx [in/out] Structure that receives information about the
399 | code page.
400 | @return True on success, False on error.
401 | }
402 | // ---------------------------------------------------------------------------
403 | procedure CopyByteArray(const Src: array of Byte; var Dest: array of Byte);
404 | {Makes a copy of a byte array.
405 | @param Src [in] Byte array to be copied.
406 | @param Dest [in/out] In: Array to receive copy: must be same size as Src.
407 | Out: Receives copy of Src.
408 | }
409 | var
410 | Idx: Integer; // loops thru array
411 | begin
412 | {$IFDEF Supports_Assert}
413 | Assert((Low(Src) = Low(Dest)) and (High(Src) = High(Dest)));
414 | {$ENDIF}
415 | for Idx := Low(Src) to High(Src) do
416 | Dest[Idx] := Src[Idx];
417 | end;
418 | // ---------------------------------------------------------------------------
419 | {$IFDEF Supports_ResourceString}
420 | resourcestring
421 | {$ELSE}
422 | const
423 | {$ENDIF}
424 | sCodePage = 'Code Page %d'; // description of code page if OS doesn't provide
425 | var
426 | OldInfo: TCPInfo; // old style code page info structure for Win95/NT4
427 | begin
428 | // We haven't got GetCPInfoEx: use old GetCPInfo to get some info
429 | Result := GetCPInfo(CodePage, OldInfo);
430 | if Result then
431 | begin
432 | // We update TCPInfoEx structure from old style structure and calculate
433 | // additional info
434 | // copy over from old style TCPInfo structure
435 | lpCPInfoEx.MaxCharSize := OldInfo.MaxCharSize;
436 | CopyByteArray(OldInfo.DefaultChar, lpCPInfoEx.DefaultChar);
437 | CopyByteArray(OldInfo.LeadByte, lpCPInfoEx.LeadByte);
438 | // no new default char
439 | lpCPInfoEx.UnicodeDefaultChar := #0;
440 | // store reference to code page
441 | lpCPInfoEx.CodePage := CodePage;
442 | // description is simply "Code Page NNN"
443 | StrPLCopy(
444 | lpCPInfoEx.CodePageName,
445 | Format(sCodePage, [CodePage]),
446 | SizeOf(lpCPInfoEx.CodePageName)
447 | );
448 | end;
449 | end;
450 |
451 | function VerNumToStr(const Ver: TPJVersionNumber): string;
452 | {Converts a version number to its string representation as a dotted quad.
453 | @param Ver [in] Version number to be converted.
454 | @return Version number as dotted quad.
455 | }
456 | begin
457 | Result := Format('%d.%d.%d.%d', [Ver.V1, Ver.V2, Ver.V3, Ver.V4]);
458 | end;
459 |
460 | function CompareVerNums(const Ver1, Ver2: TPJVersionNumber): Integer;
461 | {Compares two version numbers and returns a value indicating if the first is
462 | less than, equal to or greater than the second.
463 | @param Ver1 [in] First version number to compare.
464 | @param Ver2 [in] Second version number to compare.
465 | @return 0 if Ver1 = Ver2, -ve if Ver1 < Ver2, +ve if Ver1 > Ver2.
466 | }
467 | begin
468 | Result := Ver1.V1 - Ver2.V1;
469 | if Result <> 0 then
470 | Exit;
471 | Result := Ver1.V2 - Ver2.V2;
472 | if Result <> 0 then
473 | Exit;
474 | Result := Ver1.V3 - Ver2.V3;
475 | if Result <> 0 then
476 | Exit;
477 | Result := Ver1.V4 - Ver2.V4;
478 | end;
479 |
480 | type
481 | {
482 | TTransRec:
483 | Record of language code and char set codes that are returned from version
484 | information.
485 | }
486 | TTransRec = packed record
487 | Lang: Word; // language code
488 | CharSet: Word; // character set code
489 | end;
490 | {
491 | TTransRecs:
492 | Type used to type cast translation data into an array of translation
493 | records.
494 | }
495 | TTransRecs = array[0..1000] of TTransRec;
496 | {
497 | PTransRecs:
498 | Pointer to an array of translation records.
499 | }
500 | PTransRecs = ^TTransRecs;
501 |
502 |
503 | { TPJVersionInfo }
504 |
505 | procedure TPJVersionInfo.ClearProperties;
506 | {Forces properties to return cleared values.
507 | }
508 | begin
509 | // Record that we haven't read ver info: this effectively clears properties
510 | // since each property read access method checks this flag before returning
511 | // result
512 | fHaveInfo := False;
513 | end;
514 |
515 | constructor TPJVersionInfo.Create(AOwner: TComponent);
516 | {Object constructor. Sets default values.
517 | @param AOwner [in] Component that owns this one. May be nil.
518 | }
519 | begin
520 | inherited Create(AOwner);
521 | // Default is no file name - refers to executable file for application
522 | FileName := '';
523 | end;
524 |
525 | destructor TPJVersionInfo.Destroy;
526 | {Object destructor. Frees allocated memory.
527 | }
528 | begin
529 | // Ensure that info buffer is freed if allocated
530 | if fPInfoBuffer <> nil then
531 | StrDispose(fPInfoBuffer);
532 | // Ensure that translation buffer is free if allocated
533 | if fPTransBuffer <> nil then
534 | FreeMem(fPTransBuffer);
535 | inherited Destroy;
536 | end;
537 |
538 | function TPJVersionInfo.GetCharSet: string;
539 | {Read accessor for CharSet property:
540 | @return String describing character set if version info is available or
541 | empty string if not.
542 | }
543 | var
544 | Info: TCPInfoEx; // receives code page info
545 | CP: Word; // code page
546 | {$IFDEF Supports_ResourceString}
547 | resourcestring
548 | {$ELSE}
549 | const
550 | {$ENDIF}
551 | // Special code page messages
552 | sUnknownCP = '%d (Unknown Code Page)'; // unknown
553 | // Messages for pages API can't return (managed apps only)
554 | sUTF16LE = '%d (Unicode UTF-16, little endian byte order)';
555 | sUTF16BE = '%d (Unicode UTF-16, big endian byte order)';
556 | sUTF32LE = '%d (Unicode UTF-32, little endian byte order)';
557 | sUTF32BE = '%d (Unicode UTF-32, big endian byte order)';
558 | begin
559 | Result := '';
560 | if fHaveInfo then
561 | begin
562 | CP := GetCharSetCode;
563 | case CP of
564 | // Check for char codes only available in managed apps (API call won't
565 | // find them)
566 | 1200: Result := Format(sUTF16LE, [CP]);
567 | 1201: Result := Format(sUTF16BE, [CP]);
568 | 12000: Result := Format(sUTF32LE, [CP]);
569 | 12001: Result := Format(sUTF32BE, [CP]);
570 | else
571 | begin
572 | // Not a known problem code page: get it from OS
573 | if GetCPInfoExFn(CP, 0, Info) then
574 | Result := Info.CodePageName
575 | else
576 | // Give up: can't find it
577 | Result := Format(sUnknownCP, [CP]);
578 | end;
579 | end;
580 | end;
581 | end;
582 |
583 | function TPJVersionInfo.GetCharSetCode: WORD;
584 | {Read accessor for CharSetCode property.
585 | @return Char set code for current translation or 0 if there is no
586 | translation or there is no version info.
587 | }
588 | begin
589 | if fHaveInfo and (GetCurrentTranslation >= 0) then
590 | Result := PTransRecs(fPTransBuffer)^[GetCurrentTranslation].CharSet
591 | else
592 | Result := 0;
593 | end;
594 |
595 | function TPJVersionInfo.GetCurrentTranslation: Integer;
596 | {Read accessor for CurrentTranslation property.
597 | @return Index to current translation if version info is available or -1 if
598 | not.
599 | }
600 | begin
601 | if fHaveInfo then
602 | Result := fCurrentTranslation
603 | else
604 | Result := -1;
605 | end;
606 |
607 | function TPJVersionInfo.GetFileVersionNumber: TPJVersionNumber;
608 | {Read accessor for FileVersionNumber property.
609 | @return Record containing version information. If there is no version info
610 | then all fields will be zero.
611 | }
612 | begin
613 | Result.V1 := HiWord(fFixedFileInfo.dwFileVersionMS);
614 | Result.V2 := LoWord(fFixedFileInfo.dwFileVersionMS);
615 | Result.V3 := HiWord(fFixedFileInfo.dwFileVersionLS);
616 | Result.V4 := LoWord(fFixedFileInfo.dwFileVersionLS);
617 | end;
618 |
619 | function TPJVersionInfo.GetFixedFileInfoItemByIdx(Index: Integer): DWORD;
620 | {Read accessor method for various DWORD fields of the fixed file information
621 | record accessed by index.
622 | NOTE: This is a fix for C++ Builder. Delphi is able to access the fields of
623 | the TVSFixedFileInfo record directly in the read clause of the property
624 | declaration but this is not possible in C++ Builder.
625 | @param Index [in] Index of required property.
626 | @return Required DWORD value.
627 | }
628 | begin
629 | case Index of
630 | 0: Result := fFixedFileInfo.dwFileOS;
631 | 1: Result := fFixedFileInfo.dwFileType;
632 | 2: Result := fFixedFileInfo.dwFileSubType;
633 | 3: Result := fFixedFileInfo.dwFileFlagsMask;
634 | 4: Result := fFixedFileInfo.dwFileFlags;
635 | else Result := 0;
636 | end;
637 | end;
638 |
639 | procedure TPJVersionInfo.GetInfoBuffer(Len: DWORD);
640 | {Creates an info buffer of required size.
641 | @param Len [in] Required buffer size in characters.
642 | }
643 | begin
644 | // Clear any existing buffer
645 | if fPInfoBuffer <> nil then
646 | StrDispose(fPInfoBuffer);
647 | // Create the new one
648 | fPInfoBuffer := StrAlloc(Len);
649 | end;
650 |
651 | function TPJVersionInfo.GetLanguage: string;
652 | {Read accessor for Language property
653 | @return String describing language or empty string if no version info
654 | available.
655 | }
656 | const
657 | cBufSize = 256; // size of buffer
658 | var
659 | Buf: array[0..Pred(cBufSize)] of Char; // stores langauge string from API call
660 | begin
661 | // Assume failure
662 | Result := '';
663 | // Try to get language name from Win API if we have ver info
664 | if fHaveInfo and
665 | (VerLanguageName(GetLanguageCode, Buf, Pred(cBufSize)) > 0) then
666 | Result := Buf;
667 | end;
668 |
669 | function TPJVersionInfo.GetLanguageCode: WORD;
670 | {Read accessor for LanguageCode property
671 | @return Language code for current translation or 0 if there is no
672 | translation or there is no version info.
673 | }
674 | begin
675 | if fHaveInfo and (GetCurrentTranslation >= 0) then
676 | Result := PTransRecs(fPTransBuffer)^[GetCurrentTranslation].Lang
677 | else
678 | Result := 0;
679 | end;
680 |
681 | function TPJVersionInfo.GetProductVersionNumber: TPJVersionNumber;
682 | {Read accessor for ProductVersionNumber property.
683 | @return Record containing version information. If there is no version info
684 | then all fields will be zero.
685 | }
686 | begin
687 | Result.V1 := HiWord(fFixedFileInfo.dwProductVersionMS);
688 | Result.V2 := LoWord(fFixedFileInfo.dwProductVersionMS);
689 | Result.V3 := HiWord(fFixedFileInfo.dwProductVersionLS);
690 | Result.V4 := LoWord(fFixedFileInfo.dwProductVersionLS);
691 | end;
692 |
693 | function TPJVersionInfo.GetStringFileInfo(const Name: string): string;
694 | {Read accessor for StringFileInfo array property.
695 | @param Name [in] Name of required string information.
696 | @return String associated Name or empty string if there is no version info.
697 | }
698 | var
699 | CommandBuf: array[0..255] of char; // buffer to build API call command str
700 | Ptr: Pointer; // pointer to result of API call
701 | Len: UINT; // length of structure returned from API
702 | begin
703 | // Set default failure result to empty string
704 | Result := '';
705 | // Check if we have valid information recorded in info buffer - exit if not
706 | if fHaveInfo then
707 | begin
708 | // Build API call command string for reading string file info:
709 | // this uses info string + language and character set
710 | StrPCopy(CommandBuf, '\StringFileInfo\' + GetTransStr + '\' + Name);
711 | // Call API to get required string and return it if successful
712 | if VerQueryValue(fPInfoBuffer, CommandBuf, Ptr, Len) then
713 | Result := PChar(Ptr);
714 | end;
715 | end;
716 |
717 | function TPJVersionInfo.GetStringFileInfoByIdx(Index: Integer): string;
718 | {Read accessor for all string file info properties.
719 | @param Index [in] Index of required property.
720 | @return Appropriate string value of the indexed property or empty string if
721 | property has no value or there is no version info.
722 | }
723 | const
724 | cNames: array[0..11] of string =
725 | ('Comments', 'CompanyName', 'FileDescription', 'FileVersion',
726 | 'InternalName', 'LegalCopyright', 'LegalTrademarks', 'OriginalFileName',
727 | 'PrivateBuild', 'ProductName', 'ProductVersion', 'SpecialBuild');
728 | {names of predefined string file info strings}
729 | begin
730 | Result := GetStringFileInfo(cNames[Index]);
731 | end;
732 |
733 | procedure TPJVersionInfo.GetTransBuffer(Len: UINT);
734 | {Creates a translation table buffer of required size.
735 | @param Required buffer size in bytes.
736 | }
737 | begin
738 | // Clear any existing buffer
739 | if fPTransBuffer <> nil then
740 | FreeMem(fPTransBuffer);
741 | // Create the new one
742 | GetMem(fPTransBuffer, Len);
743 | end;
744 |
745 | function TPJVersionInfo.GetTransStr: string;
746 | {Encodes information about the current translation in a string.
747 | @return Required translation information.
748 | }
749 | var
750 | TransRec: TTransRec; // translation record in array of translations
751 | begin
752 | if GetCurrentTranslation >= 0 then
753 | begin
754 | // There is a valid current translation: return hex string related to it
755 | TransRec := PTransRecs(fPTransBuffer)^[GetCurrentTranslation];
756 | Result := Format('%4.4x%4.4x', [TransRec.Lang, TransRec.CharSet]);
757 | end
758 | else
759 | // No valid translation string: return empty string
760 | Result := '';
761 | end;
762 |
763 | procedure TPJVersionInfo.ReadVersionInfo;
764 | {Reads version info from file named by FileName property.
765 | }
766 | var
767 | Len: UINT; // length of structs returned from API calls
768 | Ptr: Pointer; // points to version info structures
769 | InfoSize: DWORD; // size of info buffer
770 | Dummy: DWORD; // stores 0 in call to GetFileVersionInfoSize
771 | begin
772 | // Record default value of HaveInfo property - no info read
773 | fHaveInfo := False;
774 | // Store zeros in fixed file info structure: this is used when no info
775 | FillChar(fFixedFileInfo, SizeOf(fFixedFileInfo), 0);
776 | // Set NumTranslations property to 0: this is value if no info
777 | fNumTranslations := 0;
778 | // Record required size of version info buffer
779 | InfoSize := GetFileVersionInfoSize(PChar(fFileName), Dummy);
780 | // Check that there was no error
781 | if InfoSize > 0 then
782 | begin
783 | // Found info size OK
784 | // Ensure we have a sufficiently large buffer allocated
785 | GetInfoBuffer(InfoSize);
786 | // Read file version info into storage and check success
787 | if GetFileVersionInfo(PChar(fFileName), Dummy, InfoSize, fPInfoBuffer) then
788 | begin
789 | // Success: we've read file version info to storage OK
790 | fHaveInfo := True;
791 | // Get fixed file info & copy to own storage
792 | VerQueryValue(fPInfoBuffer, '\', Ptr, Len);
793 | fFixedFileInfo := PVSFixedFileInfo(Ptr)^;
794 | // Get first translation table info from API
795 | VerQueryValue(fPInfoBuffer, '\VarFileInfo\Translation', Ptr, Len);
796 | // Ptr is to block of translation records each of size Len:
797 | // work out number of translations
798 | fNumTranslations := Len div SizeOf(TTransRec);
799 | // store translation array in a buffer
800 | GetTransBuffer(Len);
801 | Move(Ptr^, fPTransBuffer^, Len);
802 | // make first translation in block current one (-1 if no translations)
803 | SetCurrentTranslation(0); // adjusts value to -1 if no translations
804 | end;
805 | end;
806 | end;
807 |
808 | procedure TPJVersionInfo.SetCurrentTranslation(const Value: Integer);
809 | {Write acceesor method CurrentTranslation property
810 | @param Index of required translation. If Value is out of range then the
811 | property is set to -1 to indicate no translation.
812 | }
813 | begin
814 | if (Value >= 0) and (Value < NumTranslations) then
815 | fCurrentTranslation := Value
816 | else
817 | fCurrentTranslation := -1
818 | end;
819 |
820 | procedure TPJVersionInfo.SetFileName(AName: string);
821 | {Write accessor for FileName property. Action at design time and run time is
822 | different. At design time we simply record the property value while at run
823 | time we store the value and read any version information from the file.
824 | @param AName [in] New value of FileName property. If '' then property is set
825 | to the name of the program's executable file.
826 | }
827 | begin
828 | if csDesigning in ComponentState then
829 | // We are designing, simply record the required name
830 | fFileName := AName
831 | else
832 | begin
833 | // It's run-time
834 | // use Application exec file name if name is ''
835 | if AName = '' then
836 | fFileName := ParamStr(0)
837 | else
838 | fFileName := AName;
839 | // clear all properties and read file version info for new file
840 | ClearProperties;
841 | ReadVersionInfo;
842 | end;
843 | end;
844 |
845 | {$IFDEF Supports_AdvancedRecords}
846 |
847 | { TPJVersionNumber }
848 |
849 | class operator TPJVersionNumber.Equal(Ver1, Ver2: TPJVersionNumber): Boolean;
850 | {Operator overload that compares two version numbers to check for equality.
851 | @param Ver1 [in] First version number.
852 | @param Ver2 [in] Second version number.
853 | @return True if Ver1 = Ver2, False otherwise.
854 | }
855 | begin
856 | Result := CompareVerNums(Ver1, Ver2) = 0;
857 | end;
858 |
859 | class operator TPJVersionNumber.GreaterThan(Ver1,
860 | Ver2: TPJVersionNumber): Boolean;
861 | {Operator overload that compares two version numbers to check if first is
862 | greater than second.
863 | @param Ver1 [in] First version number.
864 | @param Ver2 [in] Second version number.
865 | @return True if Ver1 > Ver2, False otherwise.
866 | }
867 | begin
868 | Result := CompareVerNums(Ver1, Ver2) > 0;
869 | end;
870 |
871 | class operator TPJVersionNumber.GreaterThanOrEqual(Ver1,
872 | Ver2: TPJVersionNumber): Boolean;
873 | {Operator overload that compares two version numbers to check if first is
874 | greater than or equal to the second.
875 | @param Ver1 [in] First version number.
876 | @param Ver2 [in] Second version number.
877 | @return True if Ver1 >= Ver2, False otherwise.
878 | }
879 | begin
880 | Result := CompareVerNums(Ver1, Ver2) >= 0;
881 | end;
882 |
883 | class operator TPJVersionNumber.Implicit(Ver: TPJVersionNumber): string;
884 | {Operator overload that performs implicit conversion of TPJVersionNumber to
885 | string as dotted quad.
886 | @param Ver [in] Version number to be converted.
887 | @return Version number as dotted quad.
888 | }
889 | begin
890 | Result := VerNumToStr(Ver);
891 | end;
892 |
893 | class operator TPJVersionNumber.LessThan(Ver1, Ver2: TPJVersionNumber): Boolean;
894 | {Operator overload that compares two version numbers to check if first is less
895 | than second.
896 | @param Ver1 [in] First version number.
897 | @param Ver2 [in] Second version number.
898 | @return True if Ver1 < Ver2, False otherwise.
899 | }
900 | begin
901 | Result := CompareVerNums(Ver1, Ver2) < 0;
902 | end;
903 |
904 | class operator TPJVersionNumber.LessThanOrEqual(Ver1,
905 | Ver2: TPJVersionNumber): Boolean;
906 | {Operator overload that compares two version numbers to check if first is less
907 | than or equal to the second.
908 | @param Ver1 [in] First version number.
909 | @param Ver2 [in] Second version number.
910 | @return True if Ver1 <= Ver2, False otherwise.
911 | }
912 | begin
913 | Result := CompareVerNums(Ver1, Ver2) <= 0;
914 | end;
915 |
916 | class operator TPJVersionNumber.NotEqual(Ver1, Ver2: TPJVersionNumber): Boolean;
917 | {Operator overload that compares two version numbers to check for inequality.
918 | @param Ver1 [in] First version number.
919 | @param Ver2 [in] Second version number.
920 | @return True if Ver1 <> Ver2, False otherwise.
921 | }
922 | begin
923 | Result := CompareVerNums(Ver1, Ver2) <> 0;
924 | end;
925 |
926 | {$ENDIF}
927 |
928 |
929 | initialization
930 |
931 | // Get reference to GetCPInfoEx function
932 | GetCPInfoExFn := GetProcAddress(GetModuleHandle('Kernel32.dll'), cGetCPInfoEx);
933 | if not Assigned(GetCPInfoExFn) then
934 | GetCPInfoExFn := GetCPInfoAlt;
935 |
936 | end.
937 |
938 |
--------------------------------------------------------------------------------