├── 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 | --------------------------------------------------------------------------------