From 4a5037b2d9d3101364bcd967a20751bf755d9710 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 15 Oct 2014 01:29:49 +0100 Subject: [PATCH 01/80] Standardised LegalCopyright string in version information of both PasHi and PasHiGUI. --- Src/GUI/VersionInfo.vi | 2 +- Src/VerInfo.vi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/GUI/VersionInfo.vi b/Src/GUI/VersionInfo.vi index 6d2d54b..1cbb3c9 100644 --- a/Src/GUI/VersionInfo.vi +++ b/Src/GUI/VersionInfo.vi @@ -31,7 +31,7 @@ Company Name=DelphiDabbler File Description=Pascal Highlighter GUI File Version=<#F1>.<#F2>.<#F3> build <#F4> Internal Name= -Legal Copyright=Copyright (c) P.D.Johnson (www.delphidabbler.com) 2006-. +Legal Copyright=Copyright (C) 2006-, Peter Johnson (www.delphidabbler.com). Legal Trademark= Original File Name=PasHiGUI.exe Private Build= diff --git a/Src/VerInfo.vi b/Src/VerInfo.vi index c380dc2..a0a28c4 100644 --- a/Src/VerInfo.vi +++ b/Src/VerInfo.vi @@ -30,7 +30,7 @@ Company Name=DelphiDabbler File Description=PasHi Pascal Highlighter File Version=<#F1>.<#F2>.<#F3> build <#F4> Internal Name= -Legal Copyright=Copyright (C) P.D.Johnson, 2005-. +Legal Copyright=Copyright (C) 2005-, Peter Johnson (www.delphidabbler.com). Legal Trademark= Original File Name=PasHi.exe Private Build= From 974da1a4893ce594725422e965f2e97aac70aa10 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 00:45:16 +0000 Subject: [PATCH 02/80] Added new unit to get version information from host program resources and modified UMain unit to use it to get PasHi's version. --- Src/PasHi.dpr | 3 +- Src/PasHi.dproj | 1 + Src/UMain.pas | 51 +----------------------------- Src/UVersionInfo.pas | 74 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 51 deletions(-) create mode 100644 Src/UVersionInfo.pas diff --git a/Src/PasHi.dpr b/Src/PasHi.dpr index bd52e61..3c7185c 100644 --- a/Src/PasHi.dpr +++ b/Src/PasHi.dpr @@ -74,7 +74,8 @@ uses Renderers.USourceCode in 'Renderers.USourceCode.pas', Renderers.UTitleTag in 'Renderers.UTitleTag.pas', Renderers.UStyles in 'Renderers.UStyles.pas', - Renderers.UDocument in 'Renderers.UDocument.pas'; + Renderers.UDocument in 'Renderers.UDocument.pas', + UVersionInfo in 'UVersionInfo.pas'; { Main program code } diff --git a/Src/PasHi.dproj b/Src/PasHi.dproj index a0645ea..4fd4bf9 100644 --- a/Src/PasHi.dproj +++ b/Src/PasHi.dproj @@ -65,6 +65,7 @@ + Base diff --git a/Src/UMain.pas b/Src/UMain.pas index 774a1df..616a9ad 100644 --- a/Src/UMain.pas +++ b/Src/UMain.pas @@ -72,56 +72,7 @@ implementation // Project IO.UTypes, IO.Readers.UFactory, IO.Writers.UFactory, IO.UHelper, Renderers.UTypes, - UParams, Renderers.UFactory, USourceProcessor; - - -function GetProductVersionStr: string; - {Gets the program's product version number from version information. - @return Version number as a dot delimited string. - } -var - Dummy: DWORD; // unused variable required in API calls - VerInfoSize: Integer; // size of version information data - VerInfoBuf: Pointer; // buffer holding version information - ValPtr: Pointer; // pointer to a version information value - FFI: TVSFixedFileInfo; // fixed file information from version info -begin - Result := ''; - // Get fixed file info from program's version info - // get size of version info - VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy); - if VerInfoSize > 0 then - begin - // create buffer and read version info into it - GetMem(VerInfoBuf, VerInfoSize); - try - if GetFileVersionInfo( - PChar(ParamStr(0)), Dummy, VerInfoSize, VerInfoBuf - ) then - begin - // get fixed file info from version info (ValPtr points to it) - if VerQueryValue(VerInfoBuf, '\', ValPtr, Dummy) then - begin - FFI := PVSFixedFileInfo(ValPtr)^; - // Build version info string from product version field of FFI - { TODO: delete following line and reinstate commented out lines once - beta program has ended. } - Result := Format('v2.0.0 beta %d', [HiWord(FFI.dwProductVersionLS)]); -// Result := Format( -// 'v%d.%d.%d', -// [ -// HiWord(FFI.dwProductVersionMS), -// LoWord(FFI.dwProductVersionMS), -// HiWord(FFI.dwProductVersionLS) -// ] -// ); - end - end; - finally - FreeMem(VerInfoBuf); - end; - end; -end; + UParams, Renderers.UFactory, USourceProcessor, UVersionInfo; resourcestring diff --git a/Src/UVersionInfo.pas b/Src/UVersionInfo.pas new file mode 100644 index 0000000..d7207c8 --- /dev/null +++ b/Src/UVersionInfo.pas @@ -0,0 +1,74 @@ +{ + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/ + * + * Copyright (C) 2014, Peter Johnson (www.delphidabbler.com). + * + * Gets details of host program's version number from its version information + * resources. +} + + +unit UVersionInfo; + + +interface + + +/// Gets the file version number from version information of the host +/// program. +function GetProductVersionStr: string; + + +implementation + + +uses + // Delphi + SysUtils, Windows; + + +function GetProductVersionStr: string; +var + Dummy: DWORD; // unused variable required in API calls + VerInfoSize: Integer; // size of version information data + VerInfoBuf: Pointer; // buffer holding version information + ValPtr: Pointer; // pointer to a version information value + FFI: TVSFixedFileInfo; // fixed file information from version info +begin + Result := ''; + // Get fixed file info (FFI) from program's version info + // get size of version info + VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy); + if VerInfoSize > 0 then + begin + // create buffer and read version info into it + GetMem(VerInfoBuf, VerInfoSize); + try + if GetFileVersionInfo( + PChar(ParamStr(0)), Dummy, VerInfoSize, VerInfoBuf + ) then + begin + // read FFI from version info + if VerQueryValue(VerInfoBuf, '\', ValPtr, Dummy) then + begin + FFI := PVSFixedFileInfo(ValPtr)^; + // Build version info string from file version fields of FFI + Result := Format( + 'v%d.%d.%d', + [ + HiWord(FFI.dwFileVersionMS), + LoWord(FFI.dwFileVersionMS), + HiWord(FFI.dwFileVersionLS) + ] + ); + end + end; + finally + FreeMem(VerInfoBuf); + end; + end; +end; + +end. From b55c6b6c0517b548e5fb03f8642c9ae3b8913dcc Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 00:55:19 +0000 Subject: [PATCH 03/80] Modified about box to get version information from program's resources, using UVersionInfo unit, instead of hard coding the value. --- Src/GUI/FmMain.pas | 17 +++++++++++------ Src/GUI/PasHiGUI.dpr | 3 ++- Src/GUI/PasHiGUI.dproj | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Src/GUI/FmMain.pas b/Src/GUI/FmMain.pas index 6aa9345..c973819 100644 --- a/Src/GUI/FmMain.pas +++ b/Src/GUI/FmMain.pas @@ -205,7 +205,7 @@ implementation // Delphi SysUtils, ComObj, Messages, // Project - UClipFmt, UDataObjectAdapter, UOutputData, UUtils, UDropTarget; + UClipFmt, UDataObjectAdapter, UOutputData, UUtils, UDropTarget, UVersionInfo; {$R *.dfm} @@ -222,12 +222,17 @@ procedure TMainForm.actAboutExecute(Sender: TObject); @param Sender [in] Not used. } begin - { TODO: Get version information from resources instead of hard coding. } - { TODO: Remove "beta" message once beta program has ended. } Application.MessageBox( - 'PasHiGUI v1.0.0 beta 2.'#13#10#13#10 - + 'A GUI front end for the PasHi Syntax Highlighter v2.'#13#10#13#10 - + 'Copyright (c) 2006-2014 by Peter D Johnson (www.delphidabbler.com).', + PChar( + Format('PasHiGUI %s.', [GetProductVersionStr]) + + #10#10 + + 'A GUI front end for the PasHi Syntax Highlighter v2.' + + #10#10 + + 'Copyright (c) 2006-2014 by Peter D Johnson (www.delphidabbler.com).' + + #10#10 + + 'Released under the terms of the Mozilla Public License v2.0. ' + + 'See the file License.txt for full details.' + ), 'About', MB_OK ); diff --git a/Src/GUI/PasHiGUI.dpr b/Src/GUI/PasHiGUI.dpr index a6c858d..637e396 100644 --- a/Src/GUI/PasHiGUI.dpr +++ b/Src/GUI/PasHiGUI.dpr @@ -57,7 +57,8 @@ uses FrOptions.UHelper in 'FrOptions.UHelper.pas', FrOptions.ULineStyle in 'FrOptions.ULineStyle.pas' {LineStyleOptionsFrame: TFrame}, FrOptions.UCSS in 'FrOptions.UCSS.pas' {CSSOptionsFrame: TFrame}, - FrOptions.UMisc in 'FrOptions.UMisc.pas' {MiscOptionsFrame: TFrame}; + FrOptions.UMisc in 'FrOptions.UMisc.pas' {MiscOptionsFrame: TFrame}, + UVersionInfo in '..\UVersionInfo.pas'; {$R Resources.res} // main program resources, including icon {$R VersionInfo.res} // version information resource diff --git a/Src/GUI/PasHiGUI.dproj b/Src/GUI/PasHiGUI.dproj index f9a1875..35f9bfe 100644 --- a/Src/GUI/PasHiGUI.dproj +++ b/Src/GUI/PasHiGUI.dproj @@ -71,6 +71,7 @@
MiscOptionsFrame
TFrame
+ Base From 98ba9d5e790354c2612738a3fddce2c820543dd7 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 00:58:30 +0000 Subject: [PATCH 04/80] Renamed routine that gets host program's version information to indicate it gets "file" and not "product" version information and updated affected code. --- Src/GUI/FmMain.pas | 2 +- Src/UMain.pas | 2 +- Src/UVersionInfo.pas | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Src/GUI/FmMain.pas b/Src/GUI/FmMain.pas index c973819..f650237 100644 --- a/Src/GUI/FmMain.pas +++ b/Src/GUI/FmMain.pas @@ -224,7 +224,7 @@ procedure TMainForm.actAboutExecute(Sender: TObject); begin Application.MessageBox( PChar( - Format('PasHiGUI %s.', [GetProductVersionStr]) + Format('PasHiGUI %s.', [GetFileVersionStr]) + #10#10 + 'A GUI front end for the PasHi Syntax Highlighter v2.' + #10#10 diff --git a/Src/UMain.pas b/Src/UMain.pas index 616a9ad..335811f 100644 --- a/Src/UMain.pas +++ b/Src/UMain.pas @@ -206,7 +206,7 @@ procedure TMain.SignOn; Msg: string; // sign on message text begin // Create and write sign on message - Msg := Format(sSignOn, [GetProductVersionStr]); + Msg := Format(sSignOn, [GetFileVersionStr]); fConsole.WriteLn(Msg); // underline sign-on message with dashes fConsole.WriteLn(StringOfChar('-', Length(Msg))); diff --git a/Src/UVersionInfo.pas b/Src/UVersionInfo.pas index d7207c8..02816a3 100644 --- a/Src/UVersionInfo.pas +++ b/Src/UVersionInfo.pas @@ -18,7 +18,7 @@ interface /// Gets the file version number from version information of the host /// program. -function GetProductVersionStr: string; +function GetFileVersionStr: string; implementation @@ -29,7 +29,7 @@ implementation SysUtils, Windows; -function GetProductVersionStr: string; +function GetFileVersionStr: string; var Dummy: DWORD; // unused variable required in API calls VerInfoSize: Integer; // size of version information data From 7a87af77142a769e70be86b577b00f936d1c810f Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 01:32:27 +0000 Subject: [PATCH 05/80] Modified hint text used in main form and switched on hinting. --- Src/GUI/FmMain.dfm | 36 ++++++++++++++++-------------------- Src/GUI/FmMain.pas | 3 ++- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/Src/GUI/FmMain.dfm b/Src/GUI/FmMain.dfm index 6508090..bde8d22 100644 --- a/Src/GUI/FmMain.dfm +++ b/Src/GUI/FmMain.dfm @@ -16,6 +16,7 @@ object MainForm: TMainForm Menu = mnuMain OldCreateOrder = False Position = poDesigned + ShowHint = True OnCreate = FormCreate OnDestroy = FormDestroy OnShow = FormShow @@ -236,7 +237,6 @@ object MainForm: TMainForm Top = 18 Width = 223 Height = 357 - VertScrollBar.Position = 55 VertScrollBar.Tracking = True Align = alNone Anchors = [akLeft, akTop, akBottom] @@ -249,18 +249,17 @@ object MainForm: TMainForm ParentColor = True TabOrder = 2 object cpnlMisc: TCategoryPanel - Top = 135 + Top = 190 Height = 30 Caption = 'Miscellaneous' Color = clWindow Collapsed = True TabOrder = 0 - ExplicitTop = 353 ExpandedHeight = 217 inline frmMisc: TMiscOptionsFrame Left = 0 Top = 0 - Width = 202 + Width = 219 Height = 0 Align = alClient TabOrder = 0 @@ -269,18 +268,17 @@ object MainForm: TMainForm end end object cpnlLines: TCategoryPanel - Top = 105 + Top = 160 Height = 30 Caption = 'Line Numbering && Striping' Color = clWindow Collapsed = True TabOrder = 1 - ExplicitTop = 323 ExpandedHeight = 167 inline frmLines: TLineStyleOptionsFrame Left = 0 Top = 0 - Width = 202 + Width = 219 Height = 0 Align = alClient TabOrder = 0 @@ -289,7 +287,7 @@ object MainForm: TMainForm end end object cpnlCSS: TCategoryPanel - Top = 75 + Top = 130 Height = 30 Caption = 'Style Sheets' Color = clWindow @@ -308,7 +306,7 @@ object MainForm: TMainForm end end object cpnlDocType: TCategoryPanel - Top = -55 + Top = 0 Height = 130 Caption = 'Document Type' Color = clWindow @@ -316,7 +314,7 @@ object MainForm: TMainForm inline frmDocType: TDocTypeOptionsFrame Left = 0 Top = 0 - Width = 202 + Width = 219 Height = 104 Align = alClient TabOrder = 0 @@ -383,7 +381,7 @@ object MainForm: TMainForm 'Pascal files (*.pas,*.dpr,*.inc)|*.pas;*.dpr;*.inc|All files (*.' + '*)|*.*' Dialog.Options = [ofHideReadOnly, ofAllowMultiSelect, ofFileMustExist, ofEnableSizing] - Hint = 'Open|Opens and highlights a file' + Hint = 'Open File' ImageIndex = 0 ShortCut = 16463 OnAccept = actOpenAccept @@ -396,7 +394,7 @@ object MainForm: TMainForm 'HTML files (*.html)|*.html;*.htm|Text files (*.txt)|*.txt|All fi' + 'les (*.*)|*.*' Dialog.Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing] - Hint = 'Save As|Saves highlighted code as HTML' + Hint = 'Save Highlighted Document' ImageIndex = 2 ShortCut = 16467 OnAccept = actSaveAsAccept @@ -405,12 +403,12 @@ object MainForm: TMainForm object actExit: TFileExit Category = 'File' Caption = 'E&xit' - Hint = 'Exit|Quits the application' + Hint = 'Exit' end object actCopy: TAction Category = 'Edit' Caption = '&Copy' - Hint = 'Copy|Copies highlighted code to clipboard' + Hint = 'Copy' ImageIndex = 1 ShortCut = 16451 OnExecute = actCopyExecute @@ -419,7 +417,7 @@ object MainForm: TMainForm object actPaste: TAction Category = 'Edit' Caption = '&Paste' - Hint = 'Paste|Highlights source code pasted from clipboard' + Hint = 'Paste' ImageIndex = 3 ShortCut = 16470 OnExecute = actPasteExecute @@ -428,19 +426,17 @@ object MainForm: TMainForm object actAbout: TAction Category = 'Help' Caption = '&About...' - Hint = 'About|Displays About dialog' + Hint = 'Display About Box' OnExecute = actAboutExecute end object actRestoreDefaults: TAction Category = 'Options' Caption = '&Restore Defaults' - Hint = '|Restore default values from PasHi config file' OnExecute = actRestoreDefaultsExecute end object actApply: TAction Category = 'Options' Caption = 'Apply' - Hint = '|Apply options to any current document' OnExecute = actApplyExecute end object actOptionsBar: TAction @@ -455,7 +451,7 @@ object MainForm: TMainForm object actPasHiGUIWiki: TBrowseURL Category = 'Help' Caption = 'Online User Guide' - Hint = 'User Guide|Display user guide online' + Hint = 'View User Guide' URL = 'www.delphidabbler.com/view/url/pashigui-wiki' end end @@ -464,7 +460,7 @@ object MainForm: TMainForm Left = 336 Top = 152 Bitmap = { - 494C010105000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 494C010105000900080010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000002000000001002000000000000020 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/Src/GUI/FmMain.pas b/Src/GUI/FmMain.pas index f650237..5c2e27f 100644 --- a/Src/GUI/FmMain.pas +++ b/Src/GUI/FmMain.pas @@ -300,7 +300,8 @@ procedure TMainForm.actOptionsBarUpdate(Sender: TObject); const Captions: array[Boolean] of string = (sShow, sHide); begin - actOptionsBar.Caption := Captions[actOptionsBar.Checked] + actOptionsBar.Caption := Captions[actOptionsBar.Checked]; + actOptionsBar.Hint := Captions[actOptionsBar.Checked]; end; procedure TMainForm.actPasteExecute(Sender: TObject); From 2a7037bd44b987f6b8657dea290f5e803281db17 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 01:39:39 +0000 Subject: [PATCH 06/80] Added __history directory generated by Delphi IDE to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1cc283c..a750b13 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ Bin/ Exe/ Release/ +__history Src/GUI/PasHiGUI.cfg Src/PasHi.cfg From 886bee9b7c6a6c678c306b9bf1f31425c1abcf0c Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 01:43:45 +0000 Subject: [PATCH 07/80] Imported DelphiDabbler Window State Components v5.6.1 for use in GUI program. Window State Components imported into new Src/GUI/Imported directory. Added read-me file to Src/GUI/Imported that explains use and content of directory. --- Src/GUI/Imported/PJWdwState.pas | 2052 +++++++++++++++++++++++++++++++ Src/GUI/Imported/ReadMe.txt | 5 + 2 files changed, 2057 insertions(+) create mode 100644 Src/GUI/Imported/PJWdwState.pas create mode 100644 Src/GUI/Imported/ReadMe.txt diff --git a/Src/GUI/Imported/PJWdwState.pas b/Src/GUI/Imported/PJWdwState.pas new file mode 100644 index 0000000..7ea1182 --- /dev/null +++ b/Src/GUI/Imported/PJWdwState.pas @@ -0,0 +1,2052 @@ +{ + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/ + * + * Copyright (C) 1999-2014, Peter Johnson (www.delphidabbler.com). + * + * $Rev: 1966 $ + * $Date: 2014-10-28 01:20:04 +0000 (Tue, 28 Oct 2014) $ + * + * DelphiDabbler Window state components. +} + + +unit PJWdwState; + +// Conditional defines +// Note: There is no version checking for Delphi 1 and 2 not since this unit +// will not compile with those compilers. +{$DEFINE WarnDirs} // $WARN compiler directives available +{$DEFINE RegAccessFlags} // TRegistry access flags available +{$DEFINE RequiresFileCtrl} // FileCtrl unit is required for ForceDirectories +{$UNDEF RTLNameSpaces} // Don't qualify RTL units names with namespaces +{$UNDEF TScrollStyleMoved} // TScrollStyle hasn't moved to System.UITypes units +{$UNDEF SupportsPathDelim} // PathDelim and related routine not defined +{$IFDEF VER100} // Delphi 3 + {$UNDEF WarnDirs} + {$UNDEF RegAccessFlags} +{$ENDIF} +{$IFDEF VER120} // Delphi 4 + {$UNDEF WarnDirs} + {$UNDEF RegAccessFlags} +{$ENDIF} +{$IFDEF VER130} // Delphi 5 + {$UNDEF WarnDirs} + {$UNDEF RegAccessFlags} +{$ENDIF} +{$IFDEF CONDITIONALEXPRESSIONS} + {$IF CompilerVersion >= 24.0} // Delphi XE3 and later + {$LEGACYIFEND ON} // NOTE: this must come before all $IFEND directives + {$DEFINE TScrollStyleMoved} + {$IFEND} + {$IF CompilerVersion >= 23.0} // Delphi XE2 and later + {$DEFINE RTLNameSpaces} + {$IFEND} + {$IF CompilerVersion >= 14.0} // Delphi 6 and later + {$DEFINE SupportsPathDelim} + {$UNDEF WarnDirs} + {$UNDEF RequiresFileCtrl} + {$IFEND} +{$ENDIF} + + +interface + + +uses + // Delphi + {$IFDEF RTLNameSpaces} + System.Classes, Vcl.Controls, Winapi.Messages, Winapi.Windows, Vcl.Forms, + System.SysUtils, System.Win.Registry; + {$ELSE} + Classes, Controls, Messages, Windows, Forms, SysUtils, Registry + {$IFDEF RequiresFileCtrl} + , FileCtrl // needed for ForceDirectories since it's not in SysUtils yet. + {$ENDIF} + ; + {$ENDIF} + + +const + // Custom messages used internally + // instructs component to set window state (normal, minimized or maximized) + PJM_SETWDWSTATE = WM_USER + 0; + // instructs MDI child components they can restore their windows + PJM_RESTOREMDICHILD = WM_USER + 1; + + +type + + TPJCustomWdwState = class; + + { + TPJWdwStateHook: + Class that hooks into window of owning form and passes on WMCreate and + WMDestroy messages to TPJCustomWdwState component. Instances of this class + should not be created by user code - this control is designed for private + use by TPJCustomWdwState. + } + TPJWdwStateHook = class(TWinControl) + private + fWdwState: TPJCustomWdwState; + {Reference to owning window state component} + procedure SendMsgToOwner(var Msg: TMessage); + {Dispatches given message to component's owner component. + @param Msg [in/out] The message. May be changed by message handler. + } + procedure WMDestroy(var Msg: TMessage); message WM_DESTROY; + {Handles WM_DESTROY message and dispatches it to owning window state + component. + @param Msg [in/out] The message. May be modified by message handler. + } + procedure CMShowingChanged(var Msg: TMessage); message CM_SHOWINGCHANGED; + {Handles CM_SHOWINGCHANGED message and dispatches it to owning window + state component. + @param Msg [in/out] The message. May be modified by message handler. + } + procedure PJMSetWindowState(var Msg: TMessage); message PJM_SETWDWSTATE; + {Handles PJM_SETWDWSTATE message and dispatches it to owning window state + component. + @param Msg [in/out] The message. May be modified by message handler. + } + public + constructor Create(AOwner: TComponent); override; + {Class constructor. Records reference to owner. + @param AOwner [in] Owning component. Must be a TPJCustomWdwState. + } + end; + + { + EPJCustomWdwState: + Type of exception raised by TPJCustomWdwState. + } + EPJCustomWdwState = class(Exception); + + { + TPJWdwStateReadEvent: + Type of event triggered after the window's stored placement information is + read from storage. Event handlers can adjust the values before they are used + to restore the window. + @param Sender [in] Reference to component triggering the event. + @param Left [in/out] Left edge of window. In: value read from storage. + Out: value modified in event handler. Leave unchanged or set to MaxInt + to use default value. + @param Top [in/out] Top edge of window. In: value read from storage. Out: + value modified in event handler. Leave unchanged or set to MaxInt to use + default value. + @param Width [in/out] Width of window. In: value read from storage. Out: + value modified in event handler. Leave unchanged or set to MaxInt to use + default value. + @param Height [in/out] Height of window. In: value read from storage. Out: + value modified in event handler. Leave unchanged or set to MaxInt to use + default value. + @param State [in/out] State of window. In: value read from storage. Out: + value modified in event handler. This value is the ordinal value of a + TWindowState value. Leave unchanged or set to MaxInt to use default + value. + } + TPJWdwStateReadEvent = procedure(Sender: TObject; var Left, Top, Width, + Height, State: Integer) of object; + + { + TPJWdwStateOptions + Set of values that are stored in the component's Options property. + } + TPJWdwStateOptions = set of ( + woIgnoreState, // stored wdw state is ignored and wdw is display normal + woIgnoreSize, // stored wdw size is ignored and wdw's defaults are used + woFitWorkArea // restored wdw appears wholy within work area + // (wdw may be resized to fit if woIgnoreSize not set) + // (work area is desktop or MDI client area for MDI child + // windows) + ); + + { + TPJCustomWdwState: + Abstract base class for components that record window size, position and + state between program executions. + } + TPJCustomWdwState = class(TComponent) + private + fAutoSaveRestore: Boolean; + {Value of AutoSaveRestore property} + fMinimizeDelay: Integer; + {Value of MinimizeDelay property} + fOnReadWdwState: TPJWdwStateReadEvent; + {Event handler for OnReadWdwState event} + fOnAfterWindowSized: TNotifyEvent; + {Event handler for OnAfterWindowSized event} + fOnAfterWindowRestored: TNotifyEvent; + {Event handler for OnAfterWindowRestored event} + fOptions: TPJWdwStateOptions; + {Value of Options property} + fHook: TPJWdwStateHook; + {Instance of a privately owned windowed control that is used to intercept + relevant messages in owning form and custom messages posted by this + component and to notify this component of the messages} + fWindow: TForm; + {Instance of form on which to operate} + fFormShown: Boolean; + {Flag false until form has been shown and true afterwards. Any call to + Restore method while this flag is false is recorded as pending and called + again once form has been shown} + fFormRestored: Boolean; + {Flag false until component has fully restored its window} + fRestorePending: Boolean; + {Flag true if Restore method has been called while fFormShown flag false: + such calls set this flag which in turn causes Restore method to be called + again once the form has been shown} + function GetIgnoreState: Boolean; + {Read accessor for IgnoreState property. Checks for presence of + woIgnoreState in Options property. + @return True if Options contain woIgnoreState, False otherwise. + } + procedure SetIgnoreState(const Value: Boolean); + {Write accessor for IgnoreState property. Includes or excludes + woIgnoreState property in Options according to Value. + @param Value [in] New property value. + } + protected + function GetMDIParentForm: TForm; + {Finds an MDI child form's parent form. + @return Reference to parent form. Nil if parent not found or if + component's form is not an MDI child form. + } + function GetWdwStateCmp(const Form: TForm): TPJCustomWdwState; + {Finds any TPJCustomWdwState component placed on a form. + @param Form [in] Form to be searched. + @return Reference to window state component or nil if no such component + on form. + } + function CanRestoreMDIChild: Boolean; + {Checks if an MDI child form can be restored. + @return True if form can be restored, False otherwise. + } + procedure WMDestroy(var Msg: TMessage); message WM_DESTROY; + {Message handler for owning form's WM_DESTROY message. The message is sent + to this component by the hook window component. Save the form's state if + the AutoSaveRestore property is true. + @param Msg [in/out] Not used. + } + procedure CMShowingChanged(var Msg: TMessage); message CM_SHOWINGCHANGED; + {Message handler for owning form's CM_SHOWINGCHANGED message. The message + ismsent to this component by the hook window component to indicate that + the form's showing state has changed. This causes any pending window + restoration to be executed. + @param Msg [in/out] Not used. + } + procedure PJMSetWindowState(var Msg: TMessage); message PJM_SETWDWSTATE; + {Message handler for owning form's custom PJM_SETWDWSTATE message. The + message is sent to this component by the hook window component. We update + the form's window state. A message is used for this purpose since the + Restore method needs to ensure the form has been shown before we execute + this code. Posting this message enables this to happen. + @param Msg [in/out] Message structure containing the required window + state in its LParam field. Message is not modified. + } + procedure PJMRestoreMDIChild(var Msg: TMessage); + message PJM_RESTOREMDICHILD; + {Message handled for custom PJM_RESTOREMDICHILD message. This message is + dispatched by a MDI parent form to all MDI child forms when the parent + form has restored. In response to the message we restore the form if the + AutoSaveRestore property is true and form has not been restored. + @param Msg [in/out] Not used. + } + procedure DispatchMDIChildMessages; + {Dispatches PJM_RESTOREMDICHILD messages to window state components on MDI + child forms. + } + procedure ReadWdwState(var Left, Top, Width, Height, State: Integer); + virtual; abstract; + {Read state of window from storage. Caller passes default values and + method returns new values from storage, or defaults if no stored values + found. Implementation depends on method of storage used by derived + classes. + @param Left [in/out] Left side of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value + read from storage passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from storage passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state + passed in. Value read from storage passed out, or default if no value + read. This value is the ordinal value of a TWindowState value. + } + procedure DoReadWdwState(var Left, Top, Width, Height, State: Integer); + virtual; + {Fetches the state of the window from storage via the abstract + ReadWdwState method then triggers the OnReadWdwState event which permits + any of the values read to be modified before passing them back to the + caller. The default window values per the window's form properties are + passed into the method. + @param Left [in/out] Left side of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value + read from storage passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from storage passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state + passed in. Value read from storage passed out, or default if no value + read. This value is the ordinal value of a TWindowState value. + } + procedure SaveWdwState(const Left, Top, Width, Height, State: Integer); + virtual; abstract; + {Save state of window to storage. Implementation depends on method of + storage used by derived classes. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } + procedure SetParentComponent(Value: TComponent); override; + {Override of SetParentComponent method. Sets the parent of the hook + window. This enables the hook window to receive messages from the parent + window. The method normally called by the streaming system when component + is loaded on a form. We have made method public so that it can be called + explicitly when component is dynamically created. + @param Value [in] Reference to parent component. + } + property OnReadWdwState: TPJWdwStateReadEvent + read fOnReadWdwState write fOnReadWdwState; + {Event triggered just after the window's state is read from storage. Any + of the values read can be altered before the component sets the window's + properties. Setting any of the values to MaxInt causes the form's default + value to be used in place of the stored value} + public + constructor Create(AOwner: TComponent); override; + {Class constructor. Records reference to any owning form, sets default + property values and creates a hook window to trap messages from owning + form. Permits only one TPJCustomWdwState derived component to be placed on + the form. + NOTE: This constructor is only suitable for components present at design + time. When constructing components dynamically use the CreateStandAlone + constructor instead. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } + constructor CreateStandAlone(AOwner: TForm); virtual; + {Class constructor. Creates instance of component dynamically, ensuring + all required housekeeping is performed. Use when constructing a component + that is not present at design time. AOwner must be a TForm. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } + procedure Restore; + {Reads window placement and state from storage and set up the window's + size, position and state as required. + } + procedure Save; + {Save window placement, size and state to storage. + } + published + property AutoSaveRestore: Boolean + read fAutoSaveRestore write fAutoSaveRestore default False; + {When true component automatically restores window state on form creation + and saves it on form destruction} + property IgnoreState: Boolean + read GetIgnoreState write SetIgnoreState default False; + {When true Restore method ignores the saved state of the window and leaves + current state unchanged while still setting size and position. When false + Restore also sets the window state according to the saved state. Changing + this property updates the Options property: including and excluding + woIgnoreState in the set as necessary. + NOTE: Use of IgnoreState is now deprecated and Options should be used + instead} + property MinimizeDelay: Integer + read fMinimizeDelay write fMinimizeDelay default 100; + {When a form is to be started minimized this property determines the delay + (in ms) between displaying the normalised form on screen and minimising + it} + property Options: TPJWdwStateOptions + read fOptions write fOptions default []; + {Provides a set of display options that affect how the window is displayed + or if certain stored values are ignored. See the TPJWdwStateOptions type + definition for details. Including/excluding the woIgnoreState value is the + same as setting IgnoreState to true or false respectively} + property OnAfterWindowSized: TNotifyEvent + read fOnAfterWindowSized write fOnAfterWindowSized; + {Event triggered immediately after window has been sized, but before it + has been restored} + property OnAfterWindowRestored: TNotifyEvent + read fOnAfterWindowRestored write fOnAfterWindowRestored; + {Event triggered immediately after window has been restored to required + state} + end; + + { + TPJWdwStateData: + Record used to store window state information. + } + TPJWdwStateData = record + Left: Integer; // position of left side of window + Top: Integer; // position of top of window + Width: Integer; // width of window + Height: Integer; // height of window + State: Integer; // state of window (ordinal value of TWindowState value) + end; + + { + TPJWdwStateReadData: + Type of event triggered by TPJUserWdwState when window state data is + to be read from persistent storage. + @param Sender [in] Reference to component triggering this event. + @param Data [in/out] Window state informatiom. Set to default values when + called. Handler should set Data fields to values it reads from + persistent storage. + } + TPJWdwStateReadData = procedure(Sender: TObject; var Data: TPJWdwStateData) + of object; + + { + TPJWdwStateSaveData: + Type of event triggered by TPJUserWdwState when window state data is + to be written to persistent storage. + @param Sender [in] Reference to component triggering this event. + @param Data [in] Window state data to be written to persistent storage. + } + TPJWdwStateSaveData = procedure(Sender: TObject; const Data: TPJWdwStateData) + of object; + + { + TPJUserWdwState: + Implements a component that records a window's size, position and state + between program executions in persistent storage. The user must provide the + mechanism for storing and saving by handling the OnReadData and OnSaveData + events. + } + TPJUserWdwState = class(TPJCustomWdwState) + private + fOnReadData: TPJWdwStateReadData; + {Event handler for OnReadData event} + fOnSaveData: TPJWdwStateSaveData; + {Event handler for OnSaveData event} + protected + procedure ReadWdwState(var Left, Top, Width, Height, State: Integer); + override; + {Gets window state information from OnReadData event. If no event handler + is assigned default window state is used. + @param Left [in/out] Left side of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value + read from storage passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from storage passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state + passed in. Value read from storage passed out, or default if no value + read. This value is the ordinal value of a TWindowState value. + } + procedure SaveWdwState(const Left, Top, Width, Height, State: Integer); + override; + {Triggers OnSaveData event to request handler to store window state. If no + event handler is assigned window state is not recorded. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } + published + property OnReadData: TPJWdwStateReadData + read fOnReadData write fOnReadData; + {Event triggered when window state data is to be read from persistent + storage. User must read required data in response to this event. If the + event is not handled default window state is used} + property OnSaveData: TPJWdwStateSaveData + read fOnSaveData write fOnSaveData; + {Event triggered when window state is to be written to persistent storage. + User must write provided data in response to this event. If the event is + not handled window state is not saved} + end; + + { + TPJWdwStateIniRootDir: + Identifiers of the directories supported in the TPJWdwState.IniRootDir + property. + } + TPJWdwStateIniRootDir = ( + rdWindowsDir, // Windows system directory: not recommended + rdExeDir, // Program directory: use for portable programs only + rdAppDataDir, // Per-user application data directory + rdProgramDataDir // Common application data directory + ); + + { + TPJWdwStateGetIniData: + Type of event that is triggered just before ini file is accessed. It allows + the handler to change the ini file name and section to be used. + @param AIniFileName [in/out] Value of IniFileName property passed in. + Handler can change this value. If the value passed out is a relative + path the file will be relative to the folder specified by the IniRootDir + property. + @param ASection [in/out] Default ini section name passed in. Handler can + change this value. + } + TPJWdwStateGetIniData = procedure(var AIniFilename, ASection: string) + of object; + + { + TPJWdwStateGetIniDataEx: + Type of event that is triggered just before ini file is accessed. It allows + handler to change the ini root folder, file name and section to be used. + @param AIniRootDir [in/out] Value of IniRootDir property passed in. + Hander can change this value. If the value passed out in AIniFileName is + a relative path then AIniRootDir will be used to determine the folder + used to store the file. + @param AIniFileName [in/out] Value of IniFileName property passed in. + Handler can change this value. If the value passed out is a relative + path the file will be relative to the folder specified by the + AIniRootDir parameter. + @param ASection [in/out] Default ini section name passed in. Handler can + change this value. + } + TPJWdwStateGetIniDataEx = procedure(var AIniRootDir: TPJWdwStateIniRootDir; + var AIniFilename, ASection: string) of object; + + { + TPJWdwState: + Implements a component that records a window's size, position and state + between program executions. An ini file is used to store the information. + } + TPJWdwState = class(TPJCustomWdwState) + private + fSection: string; + {Value of Section property} + fIniFileName: string; + {Value in IniFileName property} + fIniRootDir: TPJWdwStateIniRootDir; + {Value of IniRootDir property} + fOnGetIniData: TPJWdwStateGetIniData; + {Event handler for OnGetIniData event} + fOnGetIniDataEx: TPJWdwStateGetIniDataEx; + {Event handler for OnGetIniDataEx event} + function BuildIniFileName(AIniRootDir: TPJWdwStateIniRootDir; + AIniFileName: string): string; + {Constructs the ini file name to be used. + @param AIniRootDir [in] ID of ini file root directory use for relative + ini file names. + @param AIniFileName [in] Name of ini file. If this is a relative path + it will have a directory specified by AIniRootDir prepended. + @return Required file name. This will always be a rooted file spec. + } + function IniRootPath(const AIniRootDir: TPJWdwStateIniRootDir): string; + {Returns the root path specified by the given root directory ID. This root + directory is used for any ini file names that are relative paths. + @param AIniRootDir [in] ID of require root directory. + @return Required path. This is always a rooted path. + } + protected + procedure GetIniInfo(var AIniFileName, ASection: string); + {Triggers OnGetIniData event to get ini file and section names to be used + when restoring / saving window state. + @param AIniFileName [in/out] Required ini file name. Set to value of + IniFileName property when called. Can be changed by event handler. + @param ASection [in/out] Required section name. Set to value of Section + property when called. Can be changed by event handler. + } + procedure ReadWdwState(var Left, Top, Width, Height, State: Integer); + override; + {Reads window state from ini file. + @param Left [in/out] Left side of window. Default passed in. Value read + from ini file passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read + from ini file passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value + read from ini file passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from ini file passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state + passed in. Value read from ini file passed out, or default if no value + read. This value is the ordinal value of a TWindowState value. + } + procedure SaveWdwState(const Left, Top, Width, Height, State: Integer); + override; + {Writes window state to ini file. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } + public + constructor Create(AOwner: TComponent); override; + {Class constructor. Sets default property values. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } + function IniFilePath: string; + {Returns the fully specified file to the ini file used to store window + state information. + NOTE: This method will trigger the OnGetIniData and OnGetIniDataEx events. + } + published + // Published inherited property + property OnReadWdwState; + // New properties + property IniRootDir: TPJWdwStateIniRootDir + read fIniRootDir write fIniRootDir default rdAppDataDir; + {An identifier that specifies the root directory to be used for any + relative ini file name specified in the IniFileName property. If + IniFileName contains no path information, and IniRootDir is either + rdAppData or rdProgramData then the "DelphiDabbler\WindowStateStore\" + sub-directory of rdAppData or rdProgramData is used. The actual value used + to generate the file name can be changed in the OnGetIniDataEx event + handler.} + property IniFileName: string read fIniFileName write fIniFileName; + {The name of the ini file in which to save window information. If this + file name is a fully specified file path it is used as-is. If the file + name is relative it is stored in the root directory specified by the + IniRootDir parameter. If IniFileName is the empty string then the ini file + is has the same name as the program file, with the extension changed to + .ini. The actual value used to generate the file name can be changed in + the OnGetIniData or OnGetIniDataEx event handlers.} + property Section: string read fSection write fSection; + {The name of the section in ini file in which to save window information. + Uses "Window_
" (eg 'Window_Form1') if set to empty string + (default). The actual section name used can be changed in the OnGetIniData + or OnGetIniDataEx event handlers.} + property OnGetIniData: TPJWdwStateGetIniData + read fOnGetIniData write fOnGetIniData; + {Event triggered just before ini file is read when restoring and saving + window state. By handling this event you can change the ini file name and + section from those specified in the IniFileName and Section properties. + NOTE 1: If a relative path is specified for the file name it will be + appended to the sub-folder specified by the IniRootDir property. + NOTE 2: The IniFileName and Section properties are not modified. + NOTE 3: This event is not triggered if OnGetIniDataEx is handled.} + property OnGetIniDataEx: TPJWdwStateGetIniDataEx + read fOnGetIniDataEx write fOnGetIniDataEx; + {Event triggered just before ini file is read when restoring and saving + window state. By handling this event you can change the default ini root + directory file name and section from those specified in the IniRootDir, + IniFileName and Section properties. + NOTE 1: If a relative path is specified for the file name it will be + appended to the sub-folder specified by the value returned in the event + handler's AIniRootDir parameter. + NOTE 2: The IniRootDir, IniFileName and Section properties are not + modified. + NOTE 3: If this event is handled then the OnGetIniData event is not + triggered.} + end; + + { + TPJWdwStateGetRegData: + Type of event that is triggered just before registry is accessed. It allows + handler to change the registry root key and sub key to be used. + @param RootKey [in/out] Registry root key. Default HKEY value passed in. + May be changed in event handler. + @param SubKey [in/out] Registry sub key. Default value passed in. May be + changed in event handler. + } + TPJWdwStateGetRegData = procedure(var RootKey: HKEY; + var SubKey: string) of object; + + {TPJRegRootKey: + Enumeration of values that represent the registry root keys supported by + TPJRegWdwState. Each value represents and maps to the similarly named + HKEY_* constant, as shown in the comments. + } + TPJRegRootKey = ( + hkClassesRoot, // HKEY_CLASSES_ROOT + hkCurrentUser, // HKEY_CURRENT_USER + hkLocalMachine, // HKEY_LOCAL_MACHINE + hkUsers, // HKEY_USERS + hkPerformanceData, // HKEY_PERFORMANCE_DATA + hkCurrentConfig, // HKEY_CURRENT_CONFIG + hkDynData // HKEY_DYN_DATA + ); + + { + TPJWdwStateGetRegDataEx: + Type of event that is triggered just before registry is accessed. It allows + handler to change the registry root key and sub key to be used. + @param RootKeyEx [in/out] Registry root key. Default TPJRegRootKey value + passed in. May be changed in event handler. + @param SubKey [in/out] Registry sub key. Default value passed in. May be + changed in event handler. + } + TPJWdwStateGetRegDataEx = procedure(var RootKeyEx: TPJRegRootKey; + var SubKey: string) of object; + + { + TPJWdwStateRegAccessEvent: + Type of event that is triggered after registry is opened, ready for access. + Permits handler to read / write additional data to sub key. + Added by BJM. + @param Reg [in] Reference to registry object that allows registry to be + read. Reg is set to the registry sub key where window state data is + stored and can be used to read / write additional data. + } + TPJWdwStateRegAccessEvent = procedure(const Reg: TRegistry) of object; + + { + TPJRegWdwState: + Implements a component that records a window's size, position and state + between program executions. The registry is used to store the information. + NOTE: Do not use TPJRegWdwState in programs compiled with Delphi 5 and + earlier if the program is to run on 64 bit Windows: The version of TRegistry + used by these early Delphis does not fully support access to the 64 bit + registry view. + } + TPJRegWdwState = class(TPJCustomWdwState) + private // properties + fRootKeyEx: TPJRegRootKey; + {Value of RootKeyEx property} + fSubKey: string; + {Value of SubKey property} + fOnGetRegData: TPJWdwStateGetRegData; + {Event handler for OnGetRegData event} + fOnGetRegDataEx: TPJWdwStateGetRegDataEx; + {Event handler for OnGetRegDataEx event} + fOnGettingRegData: TPJWdwStateRegAccessEvent; // Added by BJM + {Event handler for OnGettingRegData event} + fOnPuttingRegData: TPJWdwStateRegAccessEvent; // Added by BJM + {Event handler for OnPuttingRegData event} + function GetRootKey: HKEY; + {Read accessor for RootKey property. + @return Required property value. + } + procedure SetRootKey(const Value: HKEY); + {Write accessor for RootKey property. + @param Value [in] New property value. + @exception ERangeError raised if value is not a recognised HKEY_* value. + } + procedure SetSubKey(const Value: string); + {Write accessor method for SubKey property. + @param Value [in] New property value. If Value='' then the property is + set to \Software\\Window\. + } + protected + procedure GetRegInfo(var ARootKey: TPJRegRootKey; var ASubKey: string); + {Triggers OnGetRegData event to get registry root key and sub key to be + used when restoring / saving window state. + @param ARootKey [in/out] Required root key value. Set to value of + RootKey property by default. May be changed in event handler. + @param ASubKey [in/ou] Required sub key. Set to value of SubKey property + when called. May be changed in event handler. + } + procedure ReadWdwState(var Left, Top, Width, Height, State: Integer); + override; + {Reads window state from registry. + @param Left [in/out] Left side of window. Default passed in. Value read + from registry passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read + from registry passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value + read from registry passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from registry passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state + passed in. Value read from registry passed out, or default if no value + read. This value is the ordinal value of a TWindowState value. + } + procedure SaveWdwState(const Left, Top, Width, Height, State: Integer); + override; + {Writes window state to registry. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } + public + constructor Create(AOwner: TComponent); override; + {Class constructor. Sets default property values. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } + published + // Published inherited property + property OnReadWdwState; + // New properties + property RootKey: HKEY read GetRootKey write SetRootKey + default HKEY_CURRENT_USER; + {Registry root key to use. Must be set to a valid HKEY value. Setting this + property also sets RootKeyEx to a corresponding value} + property RootKeyEx: TPJRegRootKey read fRootKeyEx write fRootKeyEx + stored False default hkCurrentUser; + {Registry root key to use as specified by a value from the TPJRegRootKey + enumeration. Setting this property also sets RootKey to a corresponding + value. + NOTE: This property is provided to make it easier to set root keys at + design time to avoid remembering the root key value as an integer} + property SubKey: string read fSubKey write SetSubKey; + {The sub-key below root key where window state is to be stored. If set to + empty string the value of '/Software//Window/' + is used} + property OnGetRegData: TPJWdwStateGetRegData + read fOnGetRegData write fOnGetRegData; + {Event triggered just before registry is read when restoring and saving + window state. Allows handler to change root key and subkey to be used to + store window state. Root key is specified via its HKEY value. If this + event is handled then RootKey, RootKeyEx and SubKey properties are all + ignored} + property OnGetRegDataEx: TPJWdwStateGetRegDataEx + read fOnGetRegDataEx write fOnGetRegDataEx; + {Event triggered just before registry is read when restoring and saving + window state. Allows handler to change root key and subkey to be used to + store window state. Root key is specified via its TPJRegRootKey value. If + this event is handled then RootKey, RootKeyEx and SubKey properties are + all ignored} + property OnGettingRegData: TPJWdwStateRegAccessEvent // Added by BJM + read fOnGettingRegData write fOnGettingRegData; + {Event triggered when component is reading window state data from + registry. Handle this event to read any additional data from registry} + property OnPuttingRegData: TPJWdwStateRegAccessEvent // Added by BJM + read fOnPuttingRegData write fOnPuttingRegData; + {Event triggered when component is writing window state data to registry. + Handle this event to write any additional data to registry} + end; + + +procedure Register; + {Registers the components. + } + + +implementation + + +uses + // Delphi + {$IFDEF RTLNameSpaces} + System.IniFiles, Winapi.MultiMon, Vcl.StdCtrls, Winapi.ActiveX, Winapi.ShlObj + {$IFDEF TScrollStyleMoved} + , System.UITypes + {$ENDIF} + ; + {$ELSE} + IniFiles, MultiMon, StdCtrls, ActiveX, ShlObj; + {$ENDIF} + + +{ Component registration routine } + +procedure Register; + {Registers the components. + } +begin + RegisterComponents( + 'DelphiDabbler', + [TPJWdwState, TPJRegWdwState, TPJUserWdwState] + ); +end; + +{$IFNDEF SupportsPathDelim} +// Definitions used for versions of Delphi that don't implement the following +// constant and function in SysUtils. + +const + // File path delimiter + PathDelim = '/'; + +// Ensures that given directory or path ends with exactly one path delimiter. +function IncludeTrailingPathDelimiter(const PathOrDir: string): string; +begin + Result := PathOrDir; + // remove all trailing path delimiters if any, to get rid of any duplicates + while (Result <> '') and (Result[Length(Result)] = PathDelim) do + Result := Copy(Result, 1, Length(Result) - 1); + // add a single trailing delimiter + Result := Result + PathDelim; +end; +{$ENDIF} + +{ TPJWdwStateHook } + +procedure TPJWdwStateHook.CMShowingChanged(var Msg: TMessage); + {Handles CM_SHOWINGCHANGED message and dispatches it to owning window state + component. + @param Msg [in/out] The message. May be modified by message handler. + } +begin + inherited; + SendMsgToOwner(Msg); +end; + +constructor TPJWdwStateHook.Create(AOwner: TComponent); + {Class constructor. Records reference to owner. + @param AOwner [in] Owning component. Must be a TPJCustomWdwState. + } +begin + Assert(Assigned(AOwner)); + Assert(AOwner is TPJCustomWdwState); + inherited; + fWdwState := AOwner as TPJCustomWdwState; +end; + +procedure TPJWdwStateHook.PJMSetWindowState(var Msg: TMessage); + {Handles PJM_SETWDWSTATE message and dispatches it to owning window state + component. + @param Msg [in/out] The message. May be modified by message handler. + } +begin + inherited; + SendMsgToOwner(Msg); +end; + +procedure TPJWdwStateHook.SendMsgToOwner(var Msg: TMessage); + {Dispatches given message to component's owner component. + @param Msg [in/out] The message. May be changed by message handler. + } +begin + fWdwState.Dispatch(Msg); +end; + +procedure TPJWdwStateHook.WMDestroy(var Msg: TMessage); + {Handles WM_DESTROY message and dispatches it to owning window state + component. + @param Msg [in/out] The message. May be modified by message handler. + } +begin + SendMsgToOwner(Msg); + inherited; +end; + +{ TPJCustomWdwState } + +resourcestring + // Error messages + sErrFormRequired = 'TPJCustomWdwState.Create():'#13#10 + + 'Window state components must be placed on a form. ' + + 'To create a component dynamically use the CreateStandAlone constructor.'; + sErrDynamic = 'TPJCustomWdwState.CreateStandAlone():'#13#10 + + 'A non-nil parent form is required.'; + sErrSingleInstance = 'TPJCustomWdwState.Create():'#13#10 + + 'Only one window state component is permitted on a form: %s is already ' + + 'present on %s.'; + +function TPJCustomWdwState.CanRestoreMDIChild: Boolean; + {Checks if an MDI child form can be restored. + @return True if form can be restored, False otherwise. + } +var + ParentForm: TForm; // MDI child's parent form + ParentCmp: TPJCustomWdwState; // parent form's window state control, if any +begin + ParentForm := GetMDIParentForm; + ParentCmp := GetWdwStateCmp(ParentForm); + if woFitWorkArea in fOptions then + begin + // Fitting to work area => we need information about parent form's client + // area. + if Assigned(ParentCmp) then + // Parent has a window state control that may alter client area. Therefore + // we can only restore this child form once parent has restored itself. + Result := ParentCmp.fFormRestored + else + // Parent has no window state control to alter client area. Assuming (as + // we do) that client area is known before this method is called we can + // go ahead and restore + Result := True; + end + else + // Not fitting to work area. Always OK to restore since we don't need any + // info from parent form before restoring + Result := True; +end; + +procedure TPJCustomWdwState.CMShowingChanged(var Msg: TMessage); + {Message handler for owning form's CM_SHOWINGCHANGED message. The message is + sent to this component by the hook window component to indicate that the + form's showing state has changed. This causes any pending window restoration + to be executed. + @param Msg [in/out] Not used. + } +begin + inherited; + // We only act on this method the first time it's called: fFormShown indicates + // if we've been here before + if not fFormShown then + begin + // This code executed first time called only + fFormShown := True; + if not (csDesigning in ComponentState) + and (AutoSaveRestore or fRestorePending) then + // We call restore method if a call to the method is pending or we're + // auto-saving + Restore; + end; +end; + +constructor TPJCustomWdwState.Create(AOwner: TComponent); + {Class constructor. Records reference to any owning form, sets default + property values and creates a hook window to trap messages from owning form. + Permits only one TPJCustomWdwState derived component to be placed on the form. + NOTE: This constructor is only suitable for components present at design time. + When constructing components dynamically use the CreateStandAlone constructor + instead. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } +var + Idx: Integer; // loops thru form's components +begin + // Record reference to owning form (raise execption if no owning form) + if not Assigned(AOwner) or not (AOwner is TForm) then + raise EPJCustomWdwState.Create(sErrFormRequired); + fWindow := AOwner as TForm; + // Ensure there is only one TPJCustomWdwState component on a form + for Idx := 0 to Pred(AOwner.ComponentCount) do + if AOwner.Components[Idx] is TPJCustomWdwState then + raise EPJCustomWdwState.CreateFmt(sErrSingleInstance, + [AOwner.Components[Idx].Name, AOwner.Name]); + // All OK: go ahead and create component + inherited Create(AOwner); + // Set default property values + fAutoSaveRestore := False; + fOptions := []; + fMinimizeDelay := 100; + // Hook into owning form (run time only) + // the hook control is auto-destroyed when this component is destroyed + if not (csDesigning in ComponentState) then + fHook := TPJWdwStateHook.Create(Self); + // Set default flags + fFormShown := False; + fRestorePending := False; +end; + +constructor TPJCustomWdwState.CreateStandAlone(AOwner: TForm); + {Class constructor. Creates instance of component dynamically, ensuring all + required housekeeping is performed. Use when constructing a component that is + not present at design time. AOwner must be a TForm. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } +begin + if not Assigned(AOwner) then + raise EPJCustomWdwState.Create(sErrDynamic); + // Do default construction + Create(AOwner); + // Make given owner the component's parent + SetParentComponent(AOwner); +end; + +procedure TPJCustomWdwState.DispatchMDIChildMessages; + {Dispatches PJM_RESTOREMDICHILD messages to window state components on MDI + child forms. + } +var + ChildIdx: Integer; // loops thru all owner form's MDI child forms + WdwState: TPJCustomWdwState; // ref to MDI child form's window state comp + Msg: TMessage; // message sent to each MDI child form +begin + inherited; + if not Assigned(fWindow) or (fWindow.FormStyle <> fsMDIForm) then + Exit; + // Set up message + Msg.Msg := PJM_RESTOREMDICHILD; + Msg.LParam := 0; + Msg.WParam := 0; + Msg.Result := 0; + // Send message to each MDI child + for ChildIdx := 0 to Pred(fWindow.MDIChildCount) do + begin + WdwState := GetWdwStateCmp(fWindow.MDIChildren[ChildIdx]); + if Assigned(WdwState) then + WdwState.Dispatch(Msg); + end; +end; + +procedure TPJCustomWdwState.DoReadWdwState(var Left, Top, Width, Height, + State: Integer); + {Fetches the state of the window from storage via the abstract ReadWdwState + method then triggers the OnReadWdwState event which permits any of the values + read to be modified before passing them back to the caller. The default window + values per the window's form properties are passed into the method + @param Left [in/out] Left side of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read + from storage passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value + read from storage passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from storage passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state + passed in. Value read from storage passed out, or default if no value + read. This value is the ordinal value of a TWindowState value. + } +var + DefLeft, DefTop: Integer; // default window position + DefWidth, DefHeight: Integer; // default window size + DefState: Integer; // default window state +begin + // Record default placement: this is form's window default window placement + DefLeft := Left; + DefTop := Top; + DefWidth := Width; + DefHeight := Height; + DefState := State; + // Read details from storage (storage method defined by sub-classes) + ReadWdwState(Left, Top, Width, Height, State); + if Assigned(fOnReadWdwState) then + begin + // Trigger OnReadWdwState event: permits read values to be overridden + fOnReadWdwState(Self, Left, Top, Width, Height, State); + // If any of values set to MaxInt in event handler, restore default value + if Left = MaxInt then Left := DefLeft; + if Top = MaxInt then Top := DefTop; + if Width = MaxInt then Width := DefWidth; + if Height = MaxInt then Height := DefHeight; + if State = MaxInt then State := DefState; + end; +end; + +function TPJCustomWdwState.GetIgnoreState: Boolean; + {Read accessor for IgnoreState property. Checks for presence of woIgnoreState + in Options property. + @return True if Options contain woIgnoreState, False otherwise. + } +begin + Result := woIgnoreState in fOptions; +end; + +function TPJCustomWdwState.GetMDIParentForm: TForm; + {Finds an MDI child form's parent form. + @return Reference to parent form. Nil if parent not found or if component's + form is not an MDI child form. + } +var + FormIdx: Integer; // loops through all forms in project + Form: TForm; // reference to each form in project + ChildIdx: Integer; // loops thru MDI form's MDI child forms. +begin + Result := nil; + if fWindow.FormStyle <> fsMDIChild then + Exit; + for FormIdx := 0 to Pred(Screen.FormCount) do + begin + Form := Screen.Forms[FormIdx]; + if Form.FormStyle = fsMDIForm then + begin + for ChildIdx := 0 to Pred(Form.MDIChildCount) do + begin + if Form.MDIChildren[ChildIdx] = fWindow then + begin + Result := Form; + Exit; + end; + end; + end; + end; +end; + +function TPJCustomWdwState.GetWdwStateCmp( + const Form: TForm): TPJCustomWdwState; + {Finds any TPJCustomWdwState component placed on a form. + @param Form [in] Form to be searched. + @return Reference to window state component or nil if no such component on + form. + } +var + CmpIdx: Integer; // loops thru all components on form +begin + Result := nil; + if not Assigned(Form) then + Exit; + for CmpIdx := 0 to Pred(Form.ComponentCount) do + begin + if Form.Components[CmpIdx] is TPJCustomWdwState then + begin + Result := Form.Components[CmpIdx] as TPJCustomWdwState; + Break; + end; + end; +end; + +procedure TPJCustomWdwState.PJMRestoreMDIChild(var Msg: TMessage); + {Message handled for custom PJM_RESTOREMDICHILD message. This message is + dispatched by a MDI parent form to all MDI child forms when the parent form + has restored. In response to the message we restore the form if the + AutoSaveRestore property is true and form has not been restored. + @param Msg [in/out] Not used. + } +begin + inherited; + if not Assigned(fWindow) then + Exit; + if (fWindow.FormStyle = fsMDIChild) and not fFormRestored then + begin + if not (csDesigning in ComponentState) + and (AutoSaveRestore or fRestorePending) then + Restore; + end; +end; + +procedure TPJCustomWdwState.PJMSetWindowState(var Msg: TMessage); + {Message handler for owning form's custom PJM_SETWDWSTATE message. The message + is sent to this component by the hook window component. We update the form's + window state. A message is used for this purpose since the Restore method + needs to ensure the form has been shown before we execute this code. Posting + this message enables this to happen. + @param Msg [in/out] Message structure containing the required window state + in its LParam field. Message is not modified. + } + + procedure BusyWait(const Interval: Cardinal); + {Performs a busy wait for a specified time. + @param Interval [in] Time to wait in milliseconds. + } + var + Start: Cardinal; // Number of ticks at start of loop + TicksNow: Cardinal; // Number of ticks at current time + begin + Start := GetTickCount; + repeat + Application.ProcessMessages; + TicksNow := GetTickCount; + until (Int64(TicksNow) - Int64(Start) >= Interval) // time elapsed + or (TicksNow < Start); // ticks have wrapped round (v unlikely!) + end; + +begin + inherited; + // Check that a form window is available + if Assigned(fWindow) then + begin + // Change the state of the window as required + case TWindowState(Msg.LParam) of + wsMaximized: + // maximise the window + fWindow.WindowState := wsMaximized; + wsMinimized: + begin + // minimize the window: + // pause for required interval before doing minimization + if fMinimizeDelay > 0 then + BusyWait(fMinimizeDelay); + // if window is main form, minimize the whole app else minimize window + if Application.MainForm = fWindow then + Application.Minimize + else + fWindow.WindowState := wsMinimized; + end; + wsNormal: + // normal window state + fWindow.WindowState := wsNormal; + end; + // Note that the form is now restored + fFormRestored := True; + // Notify any MDI child forms that this form has been restored + DispatchMDIChildMessages; + end; + // Trigger event to inform that window has been restored + if Assigned(fOnAfterWindowRestored) then + fOnAfterWindowRestored(Self); +end; + +procedure TPJCustomWdwState.Restore; + {Reads window placement and state from storage and set up the window's size, + position and state as required. + } + + //---------------------------------------------------------------------------- + function WindowScrollbars(const Wnd: HWND): TScrollStyle; + {Finds which, if any scrollbars are displayed by a window. + @param Wnd [in] Handle of window we are checking. + @return Identifies scroll bars displayed if any. + } + var + StyleFlags: DWORD; // window style flags providing scrollbar info + begin + // Get style flags (allow WS_VSCROLL and WS_HSCROLL only) + StyleFlags:= GetWindowLong(Wnd, GWL_STYLE) and (WS_VSCROLL or WS_HSCROLL); + // Convert style flags to TScrollStyle + case StyleFlags of + 0: Result := ssNone; + WS_VSCROLL: Result := ssVertical; + WS_HSCROLL: Result := ssHorizontal; + else Result := ssBoth; + end; + end; + //---------------------------------------------------------------------------- + +var + Left, Top: Integer; // position of window + Width, Height: integer; // dimensions of window + State: Integer; // state of window as integer + Pl: TWindowPlacement; // info structure for placement of window + WorkArea: TRect; // work area in which form to be aligned + AMonitor: HMonitor; // handle to a monitor + MonitorInfo: TMonitorInfo; // receives info about a monitor + MDIParent: TForm; // reference to parent form of MDI child + Scrollbars: TScrollStyle; // scrollbars displayed by MDI child +begin + Assert(not (csDesigning in ComponentState)); + + // Check if there is an owning window and get out if not + if fWindow = nil then + Exit; + // If not ready to act on restore command set pending flag for later handling + if not fFormShown + or ((fWindow.FormStyle = fsMDIChild) and not CanRestoreMDIChild) then + begin + // note that a restore is pending + fRestorePending := True; + Exit; + end; + + // We are actually doing the restoration: note that not pending any more + fRestorePending := False; + + // Read info from storage + + // Set default values in case any of items are not recorded in storage + Left := fWindow.Left; + Top := fWindow.Top; + Width := fWindow.Width; + Height := fWindow.Height; + State := Ord(fWindow.WindowState); + + // Read state and size of window from storage - using defaults set above. The + // values could be altered by OnReadWdwState event handler that is triggered + // inside DoReadWdwState + DoReadWdwState(Left, Top, Width, Height, State); + + // Adjust read values + + // Restore default window size if we're ignoring recorded window size + if woIgnoreSize in fOptions then + begin + Width := fWindow.Width; + Height := fWindow.Height; + end; + + // Set state to normal if we're ignoring recorded window state + if woIgnoreState in fOptions then + State := Ord(wsNormal); + + // Ensure window fits in desktop workarea if woFitWorkArea specified + // We proceed differently depending on whether form is MDI child or not + if (woFitWorkArea in Options) then + begin + // Get size of desktop workarea (excludes taskbar and any other toolbars) + // Work area is different for MDI and SDI forms + if (fWindow.FormStyle = fsMDIChild) then // Added by BJM + begin + // We have MDI form. Work area in this case is client area of parent form + // that MDI child windows. + // We should not be able to get here until we have received unlock message + // from parent window. + // NOTE: this requires that parent form also has TPJCustomWdwState + // component. + MDIParent := GetMDIParentForm; + if Assigned(MDIParent) then + begin + // Important: use Windows.GetClientRect here since + // fMDIParentForm.ClientWidth and fMDIParentForm.ClientHeight don't have + // correct values and they don't allow for status bars, toolbars etc. + // If form has scrollbars client width is underestimated so we adjust + // for that. + Scrollbars := WindowScrollbars(MDIParent.ClientHandle); + GetClientRect(MDIParent.ClientHandle, WorkArea); + if Scrollbars in [ssHorizontal, ssBoth] then + Inc(WorkArea.Bottom, GetSystemMetrics(SM_CXHSCROLL)); + if Scrollbars in [ssVertical, ssBoth] then + Inc(WorkArea.Right, GetSystemMetrics(SM_CYHSCROLL)); + end + else + // Can't read parent form (possibly because it has no TPJCustomWdwState + // component) => we can't get client rectangle. We make work area empty. + WorkArea := Rect(0, 0, 0, 0); + end + else + begin + // Not MDI child form. Work area is that of desktop in current monitor. + // This code provided by CS + // First get bounds rectangle of restored window + SetRect(WorkArea, Left, Top, Left + Width, Top + Height); + {$IFDEF WarnDirs}{$WARN UNSAFE_CODE OFF}{$ENDIF} + // Next find out which monitor window is on + AMonitor := MonitorFromRect(@WorkArea, MONITOR_DEFAULTTONEAREST); + // Finally, get work area of relevant monitor + MonitorInfo.cbSize := SizeOf(MonitorInfo); + GetMonitorInfo(AMonitor, @MonitorInfo); + {$IFDEF WarnDirs}{$WARN UNSAFE_CODE ON}{$ENDIF} + WorkArea:= MonitorInfo.rcWork; + // offset work area so it has top left of (0,0): fix re issue#26 + OffsetRect(WorkArea, -WorkArea.Left, -WorkArea.Top); + end; + + // Adjust window if we have got a work area + if not IsRectEmpty(WorkArea) then + begin + + // Resize window if too wide or high if resizing permitted + if Width > WorkArea.Right - WorkArea.Left then + Width := WorkArea.Right - WorkArea.Left; + if Height > WorkArea.Bottom - WorkArea.Top then + Height := WorkArea.Bottom - WorkArea.Top; + // Adjust left of window if off left or right of work area + if Left + Width > WorkArea.Right then + Left := WorkArea.Right - Width; + if Left < WorkArea.Left then + Left := WorkArea.Left; + // Adjust height of window if off top or bottom of work area + if Top + Height > WorkArea.Bottom then + Top := WorkArea.Bottom - Height; + if Top < WorkArea.Top then + Top := WorkArea.Top; + end; + end; + + // Set window to required size + + // Set up the window placement structure + FillChar(Pl, SizeOf(Pl), #0); + Pl.Length := SizeOf(TWindowPlacement); + Pl.rcNormalPosition.Left := Left; + Pl.rcNormalPosition.Top := Top; + Pl.rcNormalPosition.Right := Left + Width; + Pl.rcNormalPosition.Bottom := Top + Height; + Pl.showCmd := SW_SHOW; // needed when restore called late in start-up + // Finally, set the actual size. This call allows for task bar etc. + {$IFDEF WarnDirs}{$WARN UNSAFE_CODE OFF}{$ENDIF} + SetWindowPlacement(fWindow.Handle, @Pl); + {$IFDEF WarnDirs}{$WARN UNSAFE_CODE ON}{$ENDIF} + // Trigger event to inform that window has been sized + if Assigned(fOnAfterWindowSized) then + fOnAfterWindowSized(Self); + + // Set window state + + // Window state is set by posting message to ensure it is done after form + // shown + PostMessage(fHook.Handle, PJM_SETWDWSTATE, 0, State); +end; + +procedure TPJCustomWdwState.Save; + {Save window placement, size and state to storage. + } +var + Pl: TWindowPlacement; // info structure for placement of window + R: TRect; // rectangle to hold normal position & size details + State: Integer; // state of window +begin + Assert(not (csDesigning in ComponentState)); + + // Check if there is an owning window - get out if not + if fWindow = nil then + Exit; + + // Calculate window's normal size and position using Windows API call - the + // form's Width, Height, Top and Left properties will give actual window size + // if form is maximised, which is not what we want here + Pl.Length := SizeOf(TWindowPlacement); + {$IFDEF WarnDirs}{$WARN UNSAFE_CODE OFF}{$ENDIF} + GetWindowPlacement(fWindow.Handle, @Pl); + {$IFDEF WarnDirs}{$WARN UNSAFE_CODE ON}{$ENDIF} + R := Pl.rcNormalPosition; + + // Record window state (maximised, minimised or normal) + // we have a special case when form is app's main form: here if minimised it's + // the application window that's actually minimised not the form + if (Application.MainForm = fWindow) and IsIconic(Application.Handle) then + // minimized main form + State := Ord(wsMinimized) + else + // not mimimized main form - we can rely on window state of form + State := Ord(fWindow.WindowState); + + // Save window info + SaveWdwState(R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top, State); +end; + +procedure TPJCustomWdwState.SetIgnoreState(const Value: Boolean); + {Write accessor for IgnoreState property. Includes or excludes woIgnoreState + property in Options according to Value. + @param Value [in] New property value. + } +begin + if Value <> GetIgnoreState then + begin + if Value then + Include(fOptions, woIgnoreState) + else + Exclude(fOptions, woIgnoreState); + end; +end; + +procedure TPJCustomWdwState.SetParentComponent(Value: TComponent); + {Override of SetParentComponent method. Sets the parent of the hook + window. This enables the hook window to receive messages from the parent + window. The method normally called by the streaming system when component is + loaded on a form. We have made method public so that it can be called + explicitly when component is dynamically created. + @param Value [in] Reference to parent component. + } +begin + inherited; + if not (csDesigning in ComponentState) and (Value is TWinControl) then + fHook.Parent := Value as TWinControl; +end; + +procedure TPJCustomWdwState.WMDestroy(var Msg: TMessage); + {Message handler for owning form's WM_DESTROY message. The message is sent to + this component by the hook window component. Save the form's state if the + AutoSaveRestore property is true. + @param Msg [in/out] Not used. + } +begin + if not (csDesigning in ComponentState) and AutoSaveRestore then + Save; + inherited; +end; + +{ TPJWdwState } + +function TPJWdwState.BuildIniFileName(AIniRootDir: TPJWdwStateIniRootDir; + AIniFileName: string): string; + {Constructs the ini file name to be used. + @param AIniRootDir [in] ID of ini file root directory use for relative ini + file names. + @param AIniFileName [in] Name of ini file. If this is a relative path it + will have a directory specified by AIniRootDir prepended. + @return Required file name. This will always be a rooted file spec. + } +var + SubDir: string; // any sub directory to be inserted in relative paths +begin + if AIniFileName = '' then + AIniFileName := ChangeFileExt(ExtractFileName(ParamStr(0)), '.ini'); + if ExtractFileDrive(AIniFileName) = '' then + begin + // relative file path + if (AnsiPos(PathDelim, AIniFileName) = 0) + and (AIniRootDir in [rdAppDataDir, rdProgramDataDir]) then + // fIniFileName is a simple file name with no path. Since it's not good + // practise to write a file in the root of %AppData% or %ProgramData% we + // interpose a suitable subdirectory for the ini file + SubDir := 'DelphiDabbler\WindowStateStore\' + else + SubDir := ''; + Result := IniRootPath(AIniRootDir) + SubDir + AIniFileName; + end + else + // fully specified file name + Result := AIniFileName; +end; + +constructor TPJWdwState.Create(AOwner: TComponent); + {Class constructor. Sets default property values. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } +begin + inherited Create(AOwner); + fIniFileName := ''; + fSection := ''; + fIniRootDir := rdAppDataDir; +end; + +procedure TPJWdwState.GetIniInfo(var AIniFileName, ASection: string); + {Triggers OnGetIniData event to get ini file and section names to be used when + restoring / saving window state. + @param AIniFileName [in/out] Required ini file name. Set to value of + IniFileName property when called. Can be changed by event handler. + @param ASection [in/out] Required section name. Set to value of Section + property when called. Can be changed by event handler. + } +var + RootDir: TPJWdwStateIniRootDir; + FileName: string; +begin + // Use IniFileName and Section properties as default values + RootDir := fIniRootDir; + FileName := fIniFileName; + ASection := fSection; + // Allow user to change these by handling OnGetIniData event + if Assigned(fOnGetIniDataEx) then + fOnGetIniDataEx(RootDir, FileName, ASection) + else if Assigned(fOnGetIniData) then + fOnGetIniData(FileName, ASection); + AIniFileName := BuildIniFileName(RootDir, FileName); + if (ASection = '') then + ASection := 'Window_' + fWindow.Name; +end; + +function TPJWdwState.IniFilePath: string; + {Returns the fully specified file to the ini file used to store window state + information. + NOTE: This method will trigger the OnGetIniData and OnGetIniDataEx events. + } +var + DummySection: string; // section name returned from GetIniInfo (ignored) +begin + GetIniInfo(Result, DummySection); +end; + +function TPJWdwState.IniRootPath(const AIniRootDir: TPJWdwStateIniRootDir): + string; + {Returns the root path specified by the given root directory ID. This root + directory is used for any ini file names that are relative paths. + @param AIniRootDir [in] ID of require root directory. + @return Required path. This is always a rooted path. + } + + function WindowsFolder: string; + {Gets the Windows installation directory. + @return Required directory. + } + begin + SetLength(Result, MAX_PATH); + SetLength( + Result, GetWindowsDirectory(PChar(Result), MAX_PATH) + ); + end; + + function SpecialFolderPath(CSIDL: Integer): string; + {Gets a specified special folder path. + @param CSIDL [in] CSDIL_* identifier of required special folder. + @return Required path. + } + var + PIDL: PItemIDList; // PIDL of the special folder + begin + Result := ''; + if Succeeded(SHGetSpecialFolderLocation(0, CSIDL, PIDL)) then + begin + try + SetLength(Result, MAX_PATH); + if SHGetPathFromIDList(PIDL, PChar(Result)) then + Result := PChar(Result) + else + Result := ''; + finally + CoTaskMemFree(PIDL); + end; + end + end; + +const + CSIDL_APPDATA = $001a; + CSIDL_COMMON_APPDATA = $0023; +begin + case AIniRootDir of + rdWindowsDir: + Result := WindowsFolder; + rdExeDir: + Result := ExtractFileDir(ParamStr(0)); + rdAppDataDir: + Result := SpecialFolderPath(CSIDL_APPDATA); + rdProgramDataDir: + Result := SpecialFolderPath(CSIDL_COMMON_APPDATA); + end; + Result := IncludeTrailingPathDelimiter(Result); +end; + +procedure TPJWdwState.ReadWdwState(var Left, Top, Width, Height, + State: Integer); + {Reads window state from ini file. + @param Left [in/out] Left side of window. Default passed in. Value read from + ini file passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read from + ini file passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value read + from ini file passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from ini file passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state passed + in. Value read from ini file passed out, or default if no value read. This + value is the ordinal value of a TWindowState value. + } +var + Ini: TIniFile; // instance of ini file class used to read info + AIniFileName: string; // name of ini file from which to read window state + ASection: string; // section of ini file from which to read window state +begin + // Get name of ini file name and section to read window state from + GetIniInfo(AIniFileName, ASection); + // Open ini file and read window info from it + Ini := TIniFile.Create(AIniFileName); + try + Left := Ini.ReadInteger(ASection, 'Left', Left); + Top := Ini.ReadInteger(ASection, 'Top', Top); + Width := Ini.ReadInteger(ASection, 'Width', Width); + Height := Ini.ReadInteger(ASection, 'Height', Height); + State := Ini.ReadInteger(ASection, 'State', State); + finally + Ini.Free; + end; +end; + +procedure TPJWdwState.SaveWdwState(const Left, Top, Width, Height, + State: Integer); + {Writes window state to ini file. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } +var + Ini: TIniFile; // instance of ini file class used to write info + AIniFileName: string; // name of ini file in which to save window state + ASection: string; // section of ini file in which to save window state + ADir: string; // directory containing ini file +begin + // Get name of ini file name and section to save window state to + GetIniInfo(AIniFileName, ASection); + // Ensure path to ini file exists + ADir := ExtractFileDir(AIniFileName); + if ADir <> '' then + ForceDirectories(ADir); + // Open ini file and write window info to it + Ini := TIniFile.Create(AIniFileName); + try + Ini.WriteInteger(ASection, 'Left', Left); + Ini.WriteInteger(ASection, 'Top', Top); + Ini.WriteInteger(ASection, 'Width', Width); + Ini.WriteInteger(ASection, 'Height', Height); + Ini.WriteInteger(ASection, 'State', State); + finally + Ini.Free; + end; +end; + +{ TPJRegWdwState } + +resourcestring + // Error messages + sErrBadHKEY = '%d is not a valid HKEY value.'; + +const + // Map of supported HKEY_ constants onto corresponding TPJRegRootKey values. + RegRootKeyMap: array[TPJRegRootKey] of HKEY = ( + HKEY_CLASSES_ROOT, // hkClassesRoot + HKEY_CURRENT_USER, // hkCurrentUser + HKEY_LOCAL_MACHINE, // hkLocalMachine + HKEY_USERS, // hkUsers + HKEY_PERFORMANCE_DATA, // hkPerformanceData + HKEY_CURRENT_CONFIG, // hkCurrentConfig + HKEY_DYN_DATA // hkDynData + ); + +function TryHKEYToCode(const RootKey: HKEY; var Value: TPJRegRootKey): Boolean; + {Attempts to convert a HKEY value into the corresponding TPJRegRootKey value. + @param RootKey [in] HKEY value to convert. + @param Value [in/out] Set to TPJRegRootKey value corresponding to RootKey. + Value is undefined if RootKey has no corresponding TPJRegRootKey value. + @return True if RootKey is valid and has corresponding TPJRegRootKey value + or False of not. + } +var + Code: TPJRegRootKey; +begin + Result := True; + for Code := Low(TPJRegRootKey) to High(TPJRegRootKey) do + if RegRootKeyMap[Code] = RootKey then + begin + Value := Code; + Exit; + end; + Result := False; +end; + +function ReadRegInt(const Reg: TRegistry; const AName: string; + const ADefault: Integer): Integer; + {Reads integer value from current sub key in registry, using a default value + if value doesn't exist in sub key. + @param Reg [in] Object used to read registry. + @param AName [in] Name of registry value to read. + @param ADefault [in] Value to use if AName does not exist. + @return Value read from registry or default if value doesn't exist. + } +begin + if Reg.ValueExists(AName) then + Result := Reg.ReadInteger(AName) + else + Result := ADefault; +end; + +procedure WriteRegInt(const Reg: TRegistry; const AName: string; + const AnInt: Integer); + {Writes an integer value to current registry key. + @param Reg [in] Object used to write registry. + @param AName [in] Name of registry value. + @param Value [in] Value to be written. + } +begin + Reg.WriteInteger(AName, AnInt); +end; + +function SafeCreateReg: TRegistry; + {Safely open registry for read/write, using 64 bit registry view on 64 bits if + possible. + NOTE: Versions of Delphi where TRegistry does not permit access flags to be + changed cannot support using the 64 bit reqistry view. + @return New TRegistry instance. The user is responsible for freeing this + object. + } +{$IFDEF REGACCESSFLAGS} +const + KEY_WOW64_64KEY = $0100; // registry access flag not defined in all Delphis +{$ENDIF} +begin + Result := TRegistry.Create; + {$IFDEF RegAccessFlags} + // We use the KEY_WOW64_64KEY access flag to force 32 bit applications running + // on 64 bit Windows to ue the 64 bit registry view. This flag is ignored by + // when running on 32 bit Windows from Windows XP (v5.1), but is not supported + // by Windows 2000 and earlier. + if (Win32MajorVersion > 5) or + ((Win32MajorVersion = 5) and (Win32MinorVersion >= 1)) then + // XP or later + Result.Access := Result.Access or KEY_WOW64_64KEY; + {$ENDIF} +end; + +constructor TPJRegWdwState.Create(AOwner: TComponent); + {Class constructor. Sets default property values. + @param AOwner [in] Owning component. Must be a TForm. + @except EPJCustomWdwState raised if Owner is not a TForm. + @except EPJCustomWdwState raised if there is already a TPJCustomWdwState + component on the form. + } +begin + inherited Create(AOwner); + fRootKeyEx := hkCurrentUser; + SetSubKey(''); +end; + +procedure TPJRegWdwState.GetRegInfo(var ARootKey: TPJRegRootKey; + var ASubKey: string); + {Triggers the OnGetRegDateEx event or, if that is not assigned, the + OnGetRegData event, to get registry root key and sub key to be used when + restoring / saving window state. + @param ARootKey [in/out] Required root key value. Set to value of RootKey + property by default. May be changed in event handler. + @param ASubKey [in/ou] Required sub key. Set to value of SubKey property + when called. May be changed in event handler. + } +var + RootHKey: HKEY; // used to get root key via its HKEY value +begin + // Use RootKeyEx and SubKey property values by default + ARootKey := RootKeyEx; + ASubKey := SubKey; + // Allow user to change these by handling either OnGetRegDataEx or + // OnGetRegData event + if Assigned(fOnGetRegDataEx) then + fOnGetRegDataEx(ARootKey, ASubKey) + else if Assigned(fOnGetRegData) then + begin + RootHKey := RegRootKeyMap[ARootKey]; + fOnGetRegData(RootHKey, ASubKey); + if not TryHKEYToCode(RootHKey, ARootKey) then + raise ERangeError.CreateFmt(sErrBadHKEY, [RootHKey]); + end; +end; + +function TPJRegWdwState.GetRootKey: HKEY; + {Read accessor for RootKey property. + @return Required property value. + } +begin + Result := RegRootKeyMap[fRootKeyEx]; +end; + +procedure TPJRegWdwState.ReadWdwState(var Left, Top, Width, Height, + State: Integer); + {Reads window state from registry. + @param Left [in/out] Left side of window. Default passed in. Value read from + registry passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read from + registry passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value read + from registry passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from registry passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state passed + in. Value read from registry passed out, or default if no value read. This + value is the ordinal value of a TWindowState value. + } +var + Reg: TRegistry; // instance of registry object used to read info + ARootKey: TPJRegRootKey; // registry root key where window state is stored + ASubKey: string; // registry sub key from which to read window state +begin + // Get registry keys from which to read window state + GetRegInfo(ARootKey, ASubKey); + // Open registry at required key + Reg := SafeCreateReg; + try + Reg.RootKey := RegRootKeyMap[ARootKey]; + if Reg.OpenKey(ASubKey, False) then + begin + // Read position, size and state of window + Left := ReadRegInt(Reg, 'Left', Left); + Top := ReadRegInt(Reg, 'Top', Top); + Width := ReadRegInt(Reg, 'Width', Width); + Height := ReadRegInt(Reg, 'Height', Height); + State := ReadRegInt(Reg, 'State', State); + // Trigger event to enable user to read further data if required + if Assigned(fOnGettingRegData) then // Added by BJM + fOnGettingRegData(Reg); + end; + finally + Reg.Free; + end; +end; + +procedure TPJRegWdwState.SaveWdwState(const Left, Top, Width, Height, + State: Integer); + {Writes window state to registry. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } +var + Reg: TRegistry; // instance of registry object used to write info + ARootKey: TPJRegRootKey; // registry root key where window state is stored + ASubKey: string; // sub key of registry in which to save window state +begin + // Get registry keys in which to save window state + GetRegInfo(ARootKey, ASubKey); + // Open registry at required key + Reg := SafeCreateReg; + try + Reg.RootKey := RegRootKeyMap[ARootKey]; + if Reg.OpenKey(ASubKey, True) then + begin + // Write window size, position and state from registry + WriteRegInt(Reg, 'Left', Left); + WriteRegInt(Reg, 'Top', Top); + WriteRegInt(Reg, 'Width', Width); + WriteRegInt(Reg, 'Height', Height); + WriteRegInt(Reg, 'State', State); + // Trigger event to enable user to write further data if required + if Assigned(fOnPuttingRegData) then // Added by BJM + fOnPuttingRegData(Reg); + end; + finally + Reg.Free; + end; +end; + +procedure TPJRegWdwState.SetRootKey(const Value: HKEY); + {Write accessor for RootKey property. + @param Value [in] New property value. + @exception ERangeError raised if value is not a recognised HKEY_* value. + } +begin + if not TryHKEYToCode(Value, fRootKeyEx) then + begin + fRootKeyEx := hkCurrentUser; + raise ERangeError.CreateFmt(sErrBadHKEY, [Value]); + end; +end; + +procedure TPJRegWdwState.SetSubKey(const Value: string); + {Write accessor method for SubKey property. + @param Value [in] New property value. If Value='' then the property is set + to \Software\\Window\. + } +begin + if (Value = '') and not (csDesigning in ComponentState) then + fSubKey := Format( + '\Software\%s\Window\%s', + [ExtractFileName(ParamStr(0)), fWindow.Name] + ) + else + fSubKey := Value; +end; + +{ TPJUserWdwState } + +procedure TPJUserWdwState.ReadWdwState(var Left, Top, Width, Height, + State: Integer); + {Gets window state information from OnReadData event. If no event handler is + assigned default window state is used. + @param Left [in/out] Left side of window. Default passed in. Value read from + storage passed out, or default if no value read. + @param Top [in/out] Top size of window. Default passed in. Value read from + storage passed out, or default if no value read. + @param Width [in/out] Width of window. Default width passed in. Value read + from storage passed out, or default if no value read. + @param Height [in/out] Height of window. Default height passed in. Value + read from storage passed out, or default if no value read. + @param State [in/out] Code describing state of window. Default state passed + in. Value read from storage passed out, or default if no value read. This + value is the ordinal value of a TWindowState value. + } +var + Data: TPJWdwStateData; // record containing window state data +begin + if Assigned(fOnReadData) then + begin + // Record default window data + Data.Left := Left; + Data.Top := Top; + Data.Width := Width; + Data.Height := Height; + Data.State := State; + // Trigger event handler + fOnReadData(Self, Data); + // Record window data set in event handler + Left := Data.Left; + Top := Data.Top; + Height := Data.Height; + Width := Data.Width; + State := Data.State; + end; +end; + +procedure TPJUserWdwState.SaveWdwState(const Left, Top, Width, + Height, State: Integer); + {Triggers OnSaveData event to request handler to store window state. If no + event handler is assigned window state is not recorded. + @param Left [in] Left side of window. + @param Top [in] Top side of window. + @param Width [in] Width of window. + @param Height [in] Height of window. + @param State [in] Code representing state of window. This is the ordinal + value of a TWindowState value. + } +var + Data: TPJWdwStateData; // record containing window state data +begin + if Assigned(fOnSaveData) then + begin + // Record window state information in record + Data.Left := Left; + Data.Top := Top; + Data.Width := Width; + Data.Height := Height; + Data.State := State; + // Trigger event + fOnSaveData(Self, Data); + end; +end; + +end. + diff --git a/Src/GUI/Imported/ReadMe.txt b/Src/GUI/Imported/ReadMe.txt new file mode 100644 index 0000000..e25a472 --- /dev/null +++ b/Src/GUI/Imported/ReadMe.txt @@ -0,0 +1,5 @@ +This directory contains 3rd party source code required to build PasHiGUI. + +Currently it contains only the DelphiDabbler Window State Components. + +The Window State Components are MPL 2.0 licensed. \ No newline at end of file From 6340c7844f2254cb3afb2375af2e93d601d7fef4 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 01:54:02 +0000 Subject: [PATCH 08/80] Deleted unused Src/3rdParty directory and its explanatory read-me file. --- Src/3rdParty/ReadMe.txt | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 Src/3rdParty/ReadMe.txt diff --git a/Src/3rdParty/ReadMe.txt b/Src/3rdParty/ReadMe.txt deleted file mode 100644 index ca0f945..0000000 --- a/Src/3rdParty/ReadMe.txt +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains 3rd party source code required to build PasHi, including -files from other DelphiDabbler projects. - -Currently it contains no files. From ab6bd8644b195a4b2fb397760e2094f334625b9f Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 01:57:48 +0000 Subject: [PATCH 09/80] Noted dependency of GUI program on DelphiDabbler Window State Components and updated directory structures. --- Build.html | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Build.html b/Build.html index 5557911..62bf698 100644 --- a/Build.html +++ b/Build.html @@ -133,7 +133,7 @@

- No libraries are required to build PasHi + No libraries are required to build PasHi

@@ -141,7 +141,9 @@

- No libraries are required to build PasHiGUI + PasHiGUI requires PJWdwState.pas from the DelphiDabbler + Window State Components, v5.6.1 or later. A copy of the required file is + included in the Src\GUI\Imported directory.

@@ -396,12 +398,12 @@

| +-- Src - source code for PasHi | | - | +-- 3rdParty - any third party source code required by PasHi - | | | +-- Assets - assets required to build PasHi's resources | | | +-- GUI - source code of the GUI application, PasHiGUI | | | + | | +-- Imported - 3rd party source code used for GUI application + | | | | | +-- Resources - assets required to build PasHiGUI's resources | | | +-- Install - install program scripts @@ -462,12 +464,12 @@

| +-- Src - source code for PasHi | | - | +-- 3rdParty - any third party source code required by PasHi - | | | +-- Assets - assets required to build PasHi's resources | | | +-- GUI - source code of the GUI application, PasHiGUI | | | + | | +-- Imported - 3rd party source code used for GUI application + | | | | | +-- Resources - assets required to build PasHiGUI's resources | | | +-- Install - install program scripts @@ -511,12 +513,12 @@

| +-- Src - source code for PasHi | | - | +-- 3rdParty - any third party source code required by PasHi - | | | +-- Assets - assets required to build PasHi's resources | | | +-- GUI - source code of the GUI application, PasHiGUI | | | + | | +-- Imported - 3rd party source code used for GUI application + | | | | | +-- Resources - assets required to build PasHiGUI's resources | | | +-- Install - install program scripts From 8492150d83b4653660573a126373137766c40a4c Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 02:00:12 +0000 Subject: [PATCH 10/80] Added 3rd party Window State Components file to GUI project --- Src/GUI/PasHiGUI.dpr | 3 ++- Src/GUI/PasHiGUI.dproj | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Src/GUI/PasHiGUI.dpr b/Src/GUI/PasHiGUI.dpr index 637e396..ea61461 100644 --- a/Src/GUI/PasHiGUI.dpr +++ b/Src/GUI/PasHiGUI.dpr @@ -58,7 +58,8 @@ uses FrOptions.ULineStyle in 'FrOptions.ULineStyle.pas' {LineStyleOptionsFrame: TFrame}, FrOptions.UCSS in 'FrOptions.UCSS.pas' {CSSOptionsFrame: TFrame}, FrOptions.UMisc in 'FrOptions.UMisc.pas' {MiscOptionsFrame: TFrame}, - UVersionInfo in '..\UVersionInfo.pas'; + UVersionInfo in '..\UVersionInfo.pas', + PJWdwState in 'Imported\PJWdwState.pas'; {$R Resources.res} // main program resources, including icon {$R VersionInfo.res} // version information resource diff --git a/Src/GUI/PasHiGUI.dproj b/Src/GUI/PasHiGUI.dproj index 35f9bfe..6416f8c 100644 --- a/Src/GUI/PasHiGUI.dproj +++ b/Src/GUI/PasHiGUI.dproj @@ -72,6 +72,7 @@ TFrame + Base From 84da061bd7130e209bd835b01df9f659ab28be1a Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 02:22:28 +0000 Subject: [PATCH 11/80] Added some file extensions for compiler generated files not wanted in version control. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index a750b13..80ac1bf 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ Release/ __history Src/GUI/PasHiGUI.cfg Src/PasHi.cfg +.local +.identcache +.todo From b87c1924c37cff2b259a6141313fd826844ff09d Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 02:24:01 +0000 Subject: [PATCH 12/80] Added support for persisting window size and position. --- Src/GUI/FmMain.pas | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Src/GUI/FmMain.pas b/Src/GUI/FmMain.pas index 5c2e27f..a848f18 100644 --- a/Src/GUI/FmMain.pas +++ b/Src/GUI/FmMain.pas @@ -18,6 +18,8 @@ interface // Delphi ExtActns, ImgList, Controls, ActnList, StdActns, Classes, Menus, Forms, ExtCtrls, StdCtrls, OleCtrls, SHDocVw, ComCtrls, ToolWin, ActiveX, Windows, + // 3rd Party + PJWdwState, // Project IntfDropDataHandler, UOptions, UDocument, UWBContainer, UInputData, FrOptions.UBase, FrOptions.UDocType, FrOptions.ULineStyle, FrOptions.UCSS, @@ -113,6 +115,8 @@ TMainForm = class(TForm, IDropDataHandler) TLoadProc = reference to procedure; private fOptions: TOptions; + // Saves and restores window's size and position. + fWdwState: TPJWdwState; fDocLoaded: Boolean; fDocument: TDocument; {Currently loaded document} @@ -205,7 +209,8 @@ implementation // Delphi SysUtils, ComObj, Messages, // Project - UClipFmt, UDataObjectAdapter, UOutputData, UUtils, UDropTarget, UVersionInfo; + UClipFmt, UConfigFiles, UDataObjectAdapter, UOutputData, UUtils, UDropTarget, + UVersionInfo; {$R *.dfm} @@ -501,6 +506,12 @@ procedure TMainForm.FormCreate(Sender: TObject); fWBContainer.DropTarget := fDropTarget; fWBContainer.OnTranslateAccel := TranslateAccelHandler; + fWdwState := TPJWdwState.CreateStandAlone(Self); + fWdwState.Options := [woFitWorkArea, woIgnoreState]; + fWdwState.IniFileName := TConfigFiles.UserConfigDir + '\gui-state'; + fWdwState.Section := 'MainWindow'; + fWdwState.Restore; + fOptions := TOptions.Create; DisplayOptions; end; @@ -510,6 +521,7 @@ procedure TMainForm.FormDestroy(Sender: TObject); @param Sender [in] Not used. } begin + fWdwState.Save; // Unregister drag drop RevokeDragDrop(Handle); fDropTarget := nil; From 9851d31fbc437cd42e1ce4fdc984e525d8026be1 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 02:30:49 +0000 Subject: [PATCH 13/80] Modified to expect and use Delphi XE as default compiler instead of Delphi 2010 --- Src/Common.mak | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Src/Common.mak b/Src/Common.mak index d880347..11573db 100644 --- a/Src/Common.mak +++ b/Src/Common.mak @@ -3,21 +3,21 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/ # -# Copyright (C) 2010-2012, Peter Johnson (www.delphidabbler.com). +# Copyright (C) 2010-2014, Peter Johnson (www.delphidabbler.com). # # Common code for inclusion in all make files. Defines common macros and rules. # Files that require Common.mak must include it using the !include directive. # ------------------------------------------------------------------------------ -# The preferred compiler is Delphi 2010. If the DELPHI2010 evironment variable -# is set, it will be used and expected to reference the Delphi 2010 install +# The preferred compiler is Delphi XE. If the DELPHIXE environment variable is +# set, it will be used and expected to reference the Delphi XE install # directory. -# If DELPHI2010 is not set then the DELPHIROOT environment variable is examined. -# This can be set to any Delphi compiler. If neither DELPHI2010 nor DELPHIROOT -# is set then an error is reported -!ifdef DELPHI2010 -DELPHIROOT = $(DELPHI2010) +# If DELPHIXE is not set then the DELPHIROOT environment variable is examined. +# This can be set to any Delphi compiler. If neither DELPHIXE nor DELPHIROOT is +# set then an error is reported. +!ifdef DELPHIXE +DELPHIROOT = $(DELPHIXE) !endif # Requires the following macros: From 66cbccce2e95a5ac2ec6ca0f2c8f3f0a3ad8e729 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 02:32:38 +0000 Subject: [PATCH 14/80] Revised re change of default compiler to Delphi XE --- Build.html | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Build.html b/Build.html index 62bf698..5d9aac1 100644 --- a/Build.html +++ b/Build.html @@ -80,7 +80,7 @@

- The programs are written in Object Pascal and are targetted at Delphi 2010. + The programs are written in Object Pascal and are targeted at Delphi XE.

@@ -141,7 +141,7 @@

- PasHiGUI requires PJWdwState.pas from the DelphiDabbler + PasHiGUI requires PJWdwState.pas from the DelphiDabbler Window State Components, v5.6.1 or later. A copy of the required file is included in the Src\GUI\Imported directory.

@@ -167,8 +167,8 @@

- A copy of Delphi is required to build the object Pascal code. Delphi 2010 - is the preferred compiler. + A copy of Delphi is required to build the object Pascal code. Delphi XE is the + preferred compiler.

@@ -205,8 +205,7 @@

- DELPHIROOT - required unless DELPHI2010 is - set. + DELPHIROOT - required unless DELPHIXE is set.
Should be set to the install directory of the version of Delphi being @@ -214,13 +213,13 @@

the Bin sub-directory of DELPHIROOT.

- DELPHI2010 - optional + DELPHIXE - optional
- If you are using Delphi 2010 this environment variable should be set - to the Delphi install directory. When DELPHI2010 is specified + If you are using Delphi XE this environment variable should be set to the + Delphi install directory. When DELPHIXE is specified DELPHIROOT will ignore its own value and use the value of - DELPHI2010 instead. + DELPHIXE instead.
@@ -298,7 +297,7 @@

The first step is to configure the required DELPHIROOT or - DELPHI2010 environment variables. + DELPHIXE environment variables.

@@ -438,7 +437,7 @@

or

-
Src> %DELPHI2010%\Bin\Make config
+
Src> %DELPHIXE%\Bin\Make config

depending on which environment variable you have set. From b0ec9f4bb6f309eb172d4c23659eeb8b03eafb8b Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 02:51:58 +0000 Subject: [PATCH 15/80] Updated re change of source control from SubVersion to Git --- Build.html | 89 +++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 64 deletions(-) diff --git a/Build.html b/Build.html index 5d9aac1..5a75df0 100644 --- a/Build.html +++ b/Build.html @@ -6,7 +6,7 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2009-2012, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2009-2014, Peter Johnson (www.delphidabbler.com). * * Instructions for building PasHi and PasHiGUI. --> @@ -317,65 +317,28 @@

- If you don't already have it, download or checkout the PasHi source - code, which should include the source for PasHiGUI. There are - several options: -

- -
    -
  1. -
    - If you are a Subversion user you can: -
    -
      -
    • -
      - Check out the source using the following command: -
      -
      > svn checkout http://pas-hi.googlecode.com/svn/trunk/ PATH
      -
      - Where PATH is the directory where you want to - place the working copy. You will not be able to commit - changes unless you join the project as a contributor. -
      -
    • -
    • -
      - Export the code using this command: -
      -
      > svn export http://pas-hi.googlecode.com/svn/trunk/ PATH
      -
      - where PATH is the directory where you wish to - store the code. -
      -
    • -
    -
    - These commands get code from the current development tree. To get - the code of a suitable stable release replace trunk - with tags/XXXX where XXX specifies the - version. -
    -
  2. -
  3. - Download a suitable source zip file from Google Code. -
  4. -
  5. - Grab the source code of the latest release from DelphiDabbler.com. -
  6. -
+ If you don't already have it, you need to get the PasHi source code, + (which includes the source for PasHiGUI). +

+ +

+ The source code is maintained in the delphidabbler/pashi Git repository on GitHub. Either clone or fork the + repo into a directory on your computer. +

+ +

+ PasHi's latest stable source code can be found in the master + branch while development code is maintained in the develop branch. + You can also download the code of one of the releases by selecting the + relevant tag. +

- If you modify the code and want to submit it for inclusion in the repository - please raise a new issue in the issue tracker, select a type (defect, enhancement etc.) and attach a - zip file or tarball containing your enhancment, preferably including a patch - file. + If you want to submit any modifications to the source code, please create a + new feature branch off the develop branch, commit your modifications + to it and then submit a pull request on GitHub.

@@ -412,9 +375,6 @@

If, by chance, you also have Bin, Exe and Release directories don't worry - all will become clear. - Subversion users may also see the usual .svn "hidden" - directories or directory. If you have done some editing you may also have - occasional "hidden" __history folders.

@@ -428,7 +388,8 @@

You may need to replace Make with the full path to Make if it isn't on the path, or if the Make that - runs isn't the Borland / CodeGear version. If this is the case try: + runs isn't the Borland / CodeGear / Embarcadero version. If this is the case + try:

Src> %DELPHIROOT%\Bin\Make config
@@ -478,7 +439,7 @@

Make will have created a .cfg file from the template in the Src folder. .cfg files are needed for DCC32 - to run correctly. This new file will be ignored by Subversion. + to run correctly. This new file will be ignored by Git.

@@ -713,7 +674,7 @@

Src> Make deepclean

- Once again this command deep operates on both the Src and + Once again this command operates on both the Src and Src\GUI directories.

From 7c3c68456a1a95b46f75d30f9cb21b6ae02cd2a7 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 03:03:41 +0000 Subject: [PATCH 16/80] Added missing trailing backslash to ignored directory. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 80ac1bf..418013b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ Bin/ Exe/ Release/ -__history +__history/ Src/GUI/PasHiGUI.cfg Src/PasHi.cfg .local From 6cc98acb31c53127e718c739799671ca9243e2a8 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Thu, 30 Oct 2014 11:41:22 +0000 Subject: [PATCH 17/80] Added missing * wildcard to ignored file extensions. --- .gitignore | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 418013b..3541c89 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,6 @@ Release/ __history/ Src/GUI/PasHiGUI.cfg Src/PasHi.cfg -.local -.identcache -.todo +*.local +*.identcache +*.todo From 3a75b6c4782a270e74295dc1d90101e44a1e4bc5 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 02:39:31 +0000 Subject: [PATCH 18/80] Renamed ReadMe.html in Docs directory as UserGuide.html --- Docs/{ReadMe.html => UserGuide.html} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Docs/{ReadMe.html => UserGuide.html} (100%) diff --git a/Docs/ReadMe.html b/Docs/UserGuide.html similarity index 100% rename from Docs/ReadMe.html rename to Docs/UserGuide.html From 990dbb1524f125e1bf46173afbefa8c7637c5d06 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 03:01:18 +0000 Subject: [PATCH 19/80] Moved License.txt from Docs directory into project root and renamed as LICENSE. --- Docs/License.txt => LICENSE | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Docs/License.txt => LICENSE (100%) diff --git a/Docs/License.txt b/LICENSE similarity index 100% rename from Docs/License.txt rename to LICENSE From e3a0485061dc34b1af5f7b134064f084c3a370d6 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 03:08:37 +0000 Subject: [PATCH 20/80] Created ReadMe file for inclusion in zip file with installer. --- Docs/ReadMe.txt | 170 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 Docs/ReadMe.txt diff --git a/Docs/ReadMe.txt b/Docs/ReadMe.txt new file mode 100644 index 0000000..6580837 --- /dev/null +++ b/Docs/ReadMe.txt @@ -0,0 +1,170 @@ +PasHi Pascal Highlighter - ReadMe File +====================================== + +Introduction +------------ + +PasHi is a fully featured command line program that highlights Pascal source +code. It reads the original source code from standard input, files or the +clipboard and writes the highlighted code as HTML to standard output, a file, +or the clipboard. + +HTML 4, XHTML and HTML 5 are all supported. CSS is used for styling. Style +sheets may be external or can be embedded in the HTML document. Several +predefined style sheets are installed with the program. You can also create your +own. + +PasHi can either generate complete HTML documents or just fragments of HTML +code. HTML fragments make it easy to embed highlighted code in existing web +pages. Web page authors simply need to ensure that the necessary CSS classes are +available. The easiest way to do this is to use an external style sheet. + +PasHiGUI, a GUI front end for PasHi, is included in the release. This provides a +point and click way of using PasHi. Most, but not all, command line options are +supported. Files and text can be dragged and dropped onto the window to +highlight them. + + +Why another Pascal highlighter? +------------------------------- + +Simple, I wanted an easy to use tool to format Pascal code for the DelphiDabbler +website. I wanted the following: + +* Conformant XHTML and later HTML 5. +* Styling by means of cascading style sheets. +* Full control over the appearance of the output code. +* Ability to highlight via the clipboard. +* The option to generate HTML fragments for inserting into existing documents. + +On checking the available free tools I found that they were either too complex +or they didn't provide one or more of the features I wanted. + +I had already written highlighter code for my CodeSnip program, so I extracted +that, tweaked it and wrapped it up in a command line program. Having made it I +thought I'd release it in case anyone else found it useful. Since then it's been +greatly enhanced. + + +Installation +------------ + +PasHi requires Windows 2000 or later to run. You need to have administrative +privileges to install it. Elevation may be required to install on Windows Vista and later. + +If you have PasHi v1.x or earlier you need to remove it before installing this +version. These early versions of the program have no setup program, so you must +uninstall manually. Simply find the program (and PasHiGUI if you have it) and +delete the executable file(s) along with any support files you installed. If you +included the v1.x install directory on the system path you should remove it. + +PasHi is provided in a zip file that contains a setup program, +PasHi-Setup-xxx.exe (where xxx is the program's version number). The zip file +also contains this read-me file. + +Extract the setup program from the zip file and run it, following the on-screen +instructions. + +You will need to accept the license before configuring and completing the +installation. The license is permissive and lets you copy and share PasHi +freely. You can also modify it providing you make the source code of your +changes freely available. + +After agreeing to the license the installer you choose the installation +directory followed by the name of the start menu program group. Following that +you have three options, all of which are selected by default: + +1. Add PasHi's directory to the system path for all users: + + This lets you run PasHi simply by typing its name on the command line, + without specifying the path to the program. The installer modifies the + system PATH environment variable. This option is recommended for everyone. + +2. Install sample style sheets and config file templates: + + This option installs various CSS style sheets and config file templates. + These files will appear in your %AppData%\DelphiDabbler\PasHi directly + immediately after you first run PasHi. The files take up very little disk + space so this option is recommended unless you are sure you will never need + to use the files. + +3. Install GUI front end program, PasHiGUI: + + This installs the PasHiGUI program alongside PasHi. This program is worth + installing if you prefer to use PasHi from a GUI rather than mastering the + command line. Most, but not all, of PasHi's options are available from + PasHiGUI. + +Once you have made your choices, you can review them then either go back to make +changes or commit to installing. Once installation is complete then the last +page is displayed. It gives an option to display this ReadMe file. If you have +installed PasHiGUI you are given the option to run it. + +The installer makes the following changes to your system: + + * The main program's executable files and documentation are installed into the + chosen install folder (%ProgramFiles%\DelphiDabbler\PasHi by default). If + you chose to install it, PasHiGUI will also be placed in this directory. + + * Files required by the uninstaller are stored in the main installation's + Uninst sub-folder. + + * The program's uninstall information is registered with the Programs and + Features (aka Add / Remove Programs) control panel applet. + + * The system path may be updated if you chose the relevant option. + + * A program group will be created in the start menu. + + * Sample .css and config files are installed in + %ProgramData%\DelphiDabbler\PasHi. The first time that PasHi is run by each + user, these files are also copied to that users's + %AppData%\DelphiDabbler\PasHi directory. + + +Uninstallation +-------------- + +Open the Programs and Features (aka Add / Remove Programs) applet from the +Control Panel, navigate to the DelphiDabbler PasHi entry and click the Remove or +Uninstall button. You will be asked to confirm removal of the program. Click Yes +to proceed. + +PasHi, PasHiGUI (if installed) and all documentation will be removed. + +The directory %ProgramData%\DelphiDabbler\PasHi will be removed but each user's %AppData%\DelphiDabbler\PasHi directory and all its files will be left behind. + +PasHi's install directory will be removed from the system path if present. + + +Documentation +------------- + +Details of how to use both the command line and GUI programs can be found in the +file UserGuide.html that is installed with the program. + + +Bug Reports +----------- + +Please report any bugs using the program's issue tracker on GitHub at +. You will need a free GitHub +account in order to create an issue. + + +Source Code +----------- + +Source code is available from the program's GitHub repository at +. Please read the file ReadMe.md that +is stored in the root of the reposity for details of how to contribute. + +Source code of each release of the program going back to v1.0.0 is available for +download from . + + +License +------- + +For details please see the file LICENSE that is installed in the same directory +where PasHi was installed. From 7c5ac344a48218031c7eb47fd9e31e3830e7e21f Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 03:22:39 +0000 Subject: [PATCH 21/80] Updated documents included in release zip Names of both documents that are included in release zip with installer have been changed. --- Src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Makefile b/Src/Makefile index 9a5d738..4a73c94 100644 --- a/Src/Makefile +++ b/Src/Makefile @@ -64,7 +64,7 @@ release: @cd .. -@if exist $(OUTFILE) del $(OUTFILE) @$(ZIP) -j -9 $(OUTFILE) Exe\PasHi-Setup-*.exe - @$(ZIP) -j -9 $(OUTFILE) Docs\ReadMe.html Docs\License.txt + @$(ZIP) -j -9 $(OUTFILE) Docs\ReadMe.txt LICENSE @cd Src # Clean up unwanted files From 91b1b8c8e8587bc355a8a4ee904ec101f6b88b35 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 03:28:00 +0000 Subject: [PATCH 22/80] Updated installer re renaming of some documentation files and addition of separate user guide. --- Src/Install/Install.iss | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Src/Install/Install.iss b/Src/Install/Install.iss index ded7976..61b7135 100644 --- a/Src/Install/Install.iss +++ b/Src/Install/Install.iss @@ -3,7 +3,7 @@ ; v. 2.0. If a copy of the MPL was not distributed with this file, You can ; obtain one at http://mozilla.org/MPL/2.0/ ; -; Copyright (C) 2012, Peter Johnson (www.delphidabbler.com). +; Copyright (C) 2012-2015, Peter Johnson (www.delphidabbler.com). ; ; PasHi install file generation script for use with Inno Setup 5 Unicode. ;=============================================================================== @@ -21,9 +21,11 @@ ; GetFileProductVersion - gets product version info string from an executable #define ExeFile "PasHi.exe" +#define GUIExeFile = "PasHiGUI.exe" #define LicenseFile "License.rtf" -#define LicenseTextFile "License.txt" -#define ReadmeFile "ReadMe.html" +#define LicenseTextFile "LICENSE" +#define ReadmeFile "ReadMe.txt" +#define UserGuide "UserGuide.html" #define InstUninstDir "Uninst" #define OutDir SourcePath + "..\..\Exe" #define SrcExePath SourcePath + "..\..\Exe\" @@ -83,9 +85,10 @@ ChangesEnvironment=true [Files] Source: {#SrcExePath}{#ExeFile}; DestDir: {app}; Flags: uninsrestartdelete replacesameversion -Source: {#SrcExePath}PasHiGUI.exe; DestDir: {app}; Tasks: gui; Flags: uninsrestartdelete replacesameversion -Source: {#SrcDocsPath}{#LicenseTextFile}; DestDir: {app}; Flags: ignoreversion +Source: {#SrcExePath}{#GUIExeFile}; DestDir: {app}; Tasks: gui; Flags: uninsrestartdelete replacesameversion +Source: {#LicenseTextFile}; DestDir: {app}; Flags: ignoreversion Source: {#SrcDocsPath}{#ReadmeFile}; DestDir: {app}; Flags: ignoreversion +Source: {#SrcDocsPath}{#UserGuide}; DestDir: {app}; Flags: ignoreversion Source: {#SrcConfigPath}version; DestDir: {#AppDataDir}; Flags: ignoreversion Source: {#SrcConfigPath}config-template; DestDir: {#AppDataDir}; Flags: ignoreversion Source: {#SrcConfigPath}config-v1; DestDir: {#AppDataDir}; Tasks: samples; Flags: ignoreversion @@ -103,7 +106,7 @@ Source: {#SrcConfigPath}mono.css; DestDir: {#AppDataDir}; Tasks: samples; Flags: [Icons] Name: {group}\Read Me File; Filename: {app}\{#ReadmeFile} -Name: {group}\Run PasHiGUI; Tasks: gui; Filename: {app}\PasHiGUI.exe +Name: {group}\Run PasHiGUI; Tasks: gui; Filename: {app}\{#GUIExeFile} Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe} [Tasks] From 7af22d1f123782bbece0602d65b9533183de78e5 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 10:55:03 +0000 Subject: [PATCH 23/80] Added Windows compatibility info + fixed version number --- Src/Assets/PasHi.manifest | 20 +++++++++++++++++--- Src/GUI/Resources/PasHiGUI.manifest | 16 +++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Src/Assets/PasHi.manifest b/Src/Assets/PasHi.manifest index e14ef56..9012cce 100644 --- a/Src/Assets/PasHi.manifest +++ b/Src/Assets/PasHi.manifest @@ -5,10 +5,10 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2014, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2014-2015, Peter Johnson (www.delphidabbler.com). * * Manifest file for PasHi Pascal Highlighter. Specifies required execution - * level. + * level and supported OSs. --> @@ -16,7 +16,7 @@ @@ -26,5 +26,19 @@ + + + + + + + + + + + + + + diff --git a/Src/GUI/Resources/PasHiGUI.manifest b/Src/GUI/Resources/PasHiGUI.manifest index 56d68dd..7c28e0f 100644 --- a/Src/GUI/Resources/PasHiGUI.manifest +++ b/Src/GUI/Resources/PasHiGUI.manifest @@ -5,7 +5,7 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2014, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2014-2015, Peter Johnson (www.delphidabbler.com). * * Manifest file for PasHiGUI. Specifies themed UI and execution level. --> @@ -35,4 +35,18 @@ + + + + + + + + + + + + + + From 4514aad1d1107ba8ec508569800b5c1b61401fff Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 10:59:27 +0000 Subject: [PATCH 24/80] Renamed PasHiGUI's Resources directory as Assets --- Src/GUI/{Resources => Assets}/MainIcon.ico | Bin Src/GUI/{Resources => Assets}/PasHiGUI.manifest | 0 Src/GUI/{Resources => Assets}/fragment-tplt.html | 0 Src/GUI/Resources.rc | 12 ++++++------ 4 files changed, 6 insertions(+), 6 deletions(-) rename Src/GUI/{Resources => Assets}/MainIcon.ico (100%) rename Src/GUI/{Resources => Assets}/PasHiGUI.manifest (100%) rename Src/GUI/{Resources => Assets}/fragment-tplt.html (100%) diff --git a/Src/GUI/Resources/MainIcon.ico b/Src/GUI/Assets/MainIcon.ico similarity index 100% rename from Src/GUI/Resources/MainIcon.ico rename to Src/GUI/Assets/MainIcon.ico diff --git a/Src/GUI/Resources/PasHiGUI.manifest b/Src/GUI/Assets/PasHiGUI.manifest similarity index 100% rename from Src/GUI/Resources/PasHiGUI.manifest rename to Src/GUI/Assets/PasHiGUI.manifest diff --git a/Src/GUI/Resources/fragment-tplt.html b/Src/GUI/Assets/fragment-tplt.html similarity index 100% rename from Src/GUI/Resources/fragment-tplt.html rename to Src/GUI/Assets/fragment-tplt.html diff --git a/Src/GUI/Resources.rc b/Src/GUI/Resources.rc index 65ceefc..7ed56e5 100644 --- a/Src/GUI/Resources.rc +++ b/Src/GUI/Resources.rc @@ -3,17 +3,17 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2006-2012, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2006-2015, Peter Johnson (www.delphidabbler.com). * * Application's resources. */ -/* Template for displaying higfhlighted HTML fragments */ -FRAGMENTTPLT RCDATA "Resources\fragment-tplt.html" +/* Template for displaying highlighted HTML fragments */ +FRAGMENTTPLT RCDATA "Assets\fragment-tplt.html" /* Program's icon */ -MAINICON ICON "Resources/MainIcon.ico" +MAINICON ICON "Assets\MainIcon.ico" -/* Manifest file for themed UI and execution level */ -1 24 Resources\PasHiGUI.manifest +/* Manifest file */ +1 24 "Assets\PasHiGUI.manifest" From f6fb79431bc213bcc9662e45371c9c1ca69b3c5f Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 11:37:46 +0000 Subject: [PATCH 25/80] Fixed file not found error for LICENSE file + tweaked defines --- Src/Install/Install.iss | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Src/Install/Install.iss b/Src/Install/Install.iss index 61b7135..910af31 100644 --- a/Src/Install/Install.iss +++ b/Src/Install/Install.iss @@ -27,10 +27,11 @@ #define ReadmeFile "ReadMe.txt" #define UserGuide "UserGuide.html" #define InstUninstDir "Uninst" -#define OutDir SourcePath + "..\..\Exe" -#define SrcExePath SourcePath + "..\..\Exe\" -#define SrcDocsPath SourcePath + "..\..\Docs\" -#define SrcConfigPath SourcePath + "..\..\Config\" +#define SrcRootPath SourcePath + "..\..\" +#define OutDir SrcRootPath + "Exe" +#define SrcExePath SrcRootPath + "Exe\" +#define SrcDocsPath SrcRootPath + "Docs\" +#define SrcConfigPath SrcRootPath + "Config\" #define ExeProg SrcExePath + ExeFile #define Company "DelphiDabbler.com" #define AppPublisher "DelphiDabbler" @@ -86,7 +87,7 @@ ChangesEnvironment=true [Files] Source: {#SrcExePath}{#ExeFile}; DestDir: {app}; Flags: uninsrestartdelete replacesameversion Source: {#SrcExePath}{#GUIExeFile}; DestDir: {app}; Tasks: gui; Flags: uninsrestartdelete replacesameversion -Source: {#LicenseTextFile}; DestDir: {app}; Flags: ignoreversion +Source: {#SrcRootPath}{#LicenseTextFile}; DestDir: {app}; Flags: ignoreversion Source: {#SrcDocsPath}{#ReadmeFile}; DestDir: {app}; Flags: ignoreversion Source: {#SrcDocsPath}{#UserGuide}; DestDir: {app}; Flags: ignoreversion Source: {#SrcConfigPath}version; DestDir: {#AppDataDir}; Flags: ignoreversion From 5181ff9dc71ff10784d3a6042247cb1b0699c884 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 11:39:38 +0000 Subject: [PATCH 26/80] Updated About box Changed name of license file and updated copyright date. --- Src/GUI/FmMain.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/GUI/FmMain.pas b/Src/GUI/FmMain.pas index a848f18..adf2f34 100644 --- a/Src/GUI/FmMain.pas +++ b/Src/GUI/FmMain.pas @@ -233,10 +233,10 @@ procedure TMainForm.actAboutExecute(Sender: TObject); + #10#10 + 'A GUI front end for the PasHi Syntax Highlighter v2.' + #10#10 - + 'Copyright (c) 2006-2014 by Peter D Johnson (www.delphidabbler.com).' + + 'Copyright (c) 2006-2015 by Peter D Johnson (www.delphidabbler.com).' + #10#10 + 'Released under the terms of the Mozilla Public License v2.0. ' - + 'See the file License.txt for full details.' + + 'See the LICENSE file for full details.' ), 'About', MB_OK From 2990d58d1dcdd99f60da55c2cc661487b70ebbe9 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 11:49:04 +0000 Subject: [PATCH 27/80] Changed to use RC to compile main resources, keeping BRCC32 for version information. --- Src/Common.mak | 19 ++++++++++++++----- Src/GUI/Makefile | 3 +-- Src/Makefile | 3 +-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Src/Common.mak b/Src/Common.mak index 11573db..1860bc2 100644 --- a/Src/Common.mak +++ b/Src/Common.mak @@ -37,6 +37,7 @@ DELPHIROOT = $(DELPHIXE) MAKE = "$(MAKEDIR)\Make.exe" -$(MAKEFLAGS) DCC32 = "$(DELPHIROOT)\Bin\DCC32.exe" BRCC32 = "$(DELPHIROOT)\Bin\BRCC32.exe" +RC = "$(DELPHIROOT)\Bin\RC.exe" !ifdef VIEDROOT VIED = "$(VIEDROOT)\VIEd.exe" -makerc !else @@ -64,10 +65,18 @@ ZIP = Zip.exe # Resource files are compiled to the directory specified by BIN macro, which # must have been set by the caller. .rc.res: - @echo +++ Compiling Resource file $< +++ - @$(BRCC32) $< -fo$(BIN)\$(@F) + @echo +++ Compiling Resource file $< to $(@F) +++ + @$(RC) -fo$(BIN)\$(@F) $< -# Version info files are compiled by VIEd. A temporary .rc file is left behind -.vi.rc: - @echo +++ Compiling Version Info file $< +++ +# Temporary resource files with special extension .tmp-rcx are compiled to the +# Bin directory using BRCC32 +.tmp-rcx.res: + @echo +++ Compiling Resource file $< to $(@F) +++ + @$(BRCC32) -fo$(BIN)\$(@F) $< + -@del $( Date: Sat, 28 Nov 2015 12:02:52 +0000 Subject: [PATCH 28/80] Updated to note use of RC resource compiler --- Build.html | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Build.html b/Build.html index 5a75df0..bac2c6d 100644 --- a/Build.html +++ b/Build.html @@ -190,15 +190,28 @@

The Delphi command line compiler.
+
+ RC +
+
+ The Microsoft resource compiler. Used to compile the main resource file. +
BRCC32
- The Borland resource compiler. Used to compile various resource source - (.rc) files. + The Borland resource compiler. Used to compile version information resources + from temporary resource files emitted by VIEd (see below)
+
+ We use two different resource compilers because RC fails to + compile resource files emitted by the Version Information Editor while + BRCC32 can fail to compile .manifest files + correctly. +
+

The following environment variables are associated with these tools:

From 106bac4aeed2cbb879d1f1cd62a3f8891f7e49e3 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 13:38:59 +0000 Subject: [PATCH 29/80] Changed to compile output to Build folder and its sub-folders instead of separate Exe, Bin and Release folders. --- .gitignore | 4 +--- Src/Common.mak | 39 ++++++++++++++++++++++++-------- Src/GUI/Makefile | 16 ++++++------- Src/GUI/PasHiGUI.cfg.tplt | 12 +++++----- Src/GUI/PasHiGUI.dproj | 35 ++++++++++++++++------------- Src/Install/Install.iss | 5 +++-- Src/Makefile | 47 +++++++++++++++++++-------------------- Src/PasHi.cfg.tplt | 12 +++++----- Src/PasHi.dproj | 38 +++++++++++++++++-------------- 9 files changed, 118 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index 3541c89..0a71ab3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -Bin/ -Exe/ -Release/ +Build/ __history/ Src/GUI/PasHiGUI.cfg Src/PasHi.cfg diff --git a/Src/Common.mak b/Src/Common.mak index 1860bc2..2a1bc77 100644 --- a/Src/Common.mak +++ b/Src/Common.mak @@ -3,7 +3,7 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/ # -# Copyright (C) 2010-2014, Peter Johnson (www.delphidabbler.com). +# Copyright (C) 2010-2015, Peter Johnson (www.delphidabbler.com). # # Common code for inclusion in all make files. Defines common macros and rules. # Files that require Common.mak must include it using the !include directive. @@ -21,17 +21,39 @@ DELPHIROOT = $(DELPHIXE) !endif # Requires the following macros: -# BIN - set to the directory that is to receive .res and .dcu output. -# DELPHIROOT - install directory of Delphi compiler to be used +# ROOT +# Set to the root project relative to current directory. Must not have +# trailing path delimiter. +# BINREL +# Set to the directory relative to the base Bin directory that is to +# receive .res and .dcu output. Must not have trailing path delimiter. May +# be empty, but must be defined. +# DELPHIROOT +# Install directory of Delphi compiler to be used. # Check for required macros + !ifndef DELPHIROOT !error DELPHIROOT environment variable required. !endif -!ifndef BIN -!error BIN macro must be defined in calling script. + +!ifndef ROOT +!error ROOT macro must be defined in calling script. !endif +!ifndef BINREL +!error BINREL macro must be defined in calling script. +!endif + +# Set required directory macros +SRC = $(ROOT)\Src +DOCS = $(ROOT)\Docs +BUILD = $(ROOT)\Build +EXE = $(BUILD)\Exe +BINBASE = $(BUILD)\Bin +BIN = $(BINBASE)\$(BINREL) +RELEASE = $(BUILD)\Release + # Define common macros that access required build tools MAKE = "$(MAKEDIR)\Make.exe" -$(MAKEFLAGS) @@ -62,20 +84,19 @@ ZIP = Zip.exe @echo +++ Compiling Delphi Project $< +++ @$(DCC32) $< -B -# Resource files are compiled to the directory specified by BIN macro, which -# must have been set by the caller. +# Resource files are compiled to the Bin directory using RC. .rc.res: @echo +++ Compiling Resource file $< to $(@F) +++ @$(RC) -fo$(BIN)\$(@F) $< # Temporary resource files with special extension .tmp-rcx are compiled to the -# Bin directory using BRCC32 +# Bin directory using BRCC32. .tmp-rcx.res: @echo +++ Compiling Resource file $< to $(@F) +++ @$(BRCC32) -fo$(BIN)\$(@F) $< -@del $(PasHiGUI.dpr Base DCC32 - 12.0 + 12.3 + True + Win32 + Application + VCL true - ..\..\Bin\GUI;$(DCC_UnitSearchPath) + ..\..\Build\Bin\GUI;$(DCC_UnitSearchPath) ..\..\Exe\PasHiGUI.exe false - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - ..\..\Exe + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) + ..\..\Build\Exe 00400000 true true true x86 - ..\..\Bin\GUI + ..\..\Build\Bin\GUI 1 @@ -78,7 +82,8 @@ Base - + + Delphi.Personality.12 VCLApplication @@ -89,9 +94,6 @@ -localhost - False - True - False False @@ -121,14 +123,17 @@ - Embarcadero InterBase Express Components - Embarcadero ADO DB Components - Embarcadero WebSnap Components - Embarcadero InternetExpress Components - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Embarcadero InterBase Express Components + Embarcadero ADO DB Components + Embarcadero WebSnap Components + Embarcadero InternetExpress Components + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + True + 12 diff --git a/Src/Install/Install.iss b/Src/Install/Install.iss index 910af31..7059fa8 100644 --- a/Src/Install/Install.iss +++ b/Src/Install/Install.iss @@ -28,8 +28,9 @@ #define UserGuide "UserGuide.html" #define InstUninstDir "Uninst" #define SrcRootPath SourcePath + "..\..\" -#define OutDir SrcRootPath + "Exe" -#define SrcExePath SrcRootPath + "Exe\" +#define BuildPath SrcRootPath + "Build\" +#define OutDir BuildPath + "Exe" +#define SrcExePath BuildPath + "Exe\" #define SrcDocsPath SrcRootPath + "Docs\" #define SrcConfigPath SrcRootPath + "Config\" #define ExeProg SrcExePath + ExeFile diff --git a/Src/Makefile b/Src/Makefile index b88224a..b60ff6d 100644 --- a/Src/Makefile +++ b/Src/Makefile @@ -3,18 +3,25 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/ # -# Copyright (C) 2005-2014, Peter Johnson (www.delphidabbler.com). +# Copyright (C) 2005-2015, Peter Johnson (www.delphidabbler.com). # # Makefile for the PasHi project. # ------------------------------------------------------------------------------ -# Set bin output path -BIN = ..\Bin +# Set required output paths for Common.mak +ROOT = .. +BINREL = # Include common macros and rules !include Common.mak +# Store name and path of release file +!ifndef RELEASEFILENAME +RELEASEFILENAME = dd-pashi +!endif +RELEASEFILEPATH = $(RELEASE)\$(RELEASEFILENAME).zip + # Default target is to configure and build the PasHi executable program default: pashi @@ -36,11 +43,10 @@ config: # Create .cfg file from templates @copy /Y PasHi.cfg.tplt PasHi.cfg # Create build folders if necessary - @cd .. - @if not exist Bin @mkdir Bin - @if not exist Exe @mkdir Exe - @if not exist Release @mkdir Release - @cd Src + @if not exist $(BUILD) @mkdir $(BUILD) + @if not exist $(BIN) @mkdir $(BIN) + @if not exist $(EXE) @mkdir $(EXE) + @if not exist $(RELEASE) @mkdir $(RELEASE) # Compiles the resources resources: VerInfo.res Resources.res @@ -50,21 +56,15 @@ pascal: PasHi.exe # Builds setup program setup: - @del ..\Exe\PasHi-Setup-* + @del $(EXE)\PasHi-Setup-* @$(ISCC) Install\Install.iss # Build release files (.zip) -!ifndef RELEASEFILENAME -RELEASEFILENAME = dd-pashi -!endif -OUTFILE = Release\$(RELEASEFILENAME).zip release: - @echo Creating Release File $(OUTFILE) - @cd .. - -@if exist $(OUTFILE) del $(OUTFILE) - @$(ZIP) -j -9 $(OUTFILE) Exe\PasHi-Setup-*.exe - @$(ZIP) -j -9 $(OUTFILE) Docs\ReadMe.txt LICENSE - @cd Src + @echo Creating Release File $(RELEASEFILENAME) + -@if exist $(RELEASEFILEPATH) del $(RELEASEFILEPATH) + @$(ZIP) -j -9 $(RELEASEFILEPATH) $(EXE)\PasHi-Setup-*.exe + @$(ZIP) -j -9 $(RELEASEFILEPATH) $(DOCS)\ReadMe.txt $(ROOT)\LICENSE # Clean up unwanted files clean: @@ -82,11 +82,10 @@ clean: @cd Src deepclean: clean - @cd .. # remove files created by make config -@del /S *.cfg 2>nul # remove folders created by make config - -@if exist Bin rmdir /S /Q Bin - -@if exist Exe rmdir /S /Q Exe - -@if exist Release rmdir /S /Q Release - @cd Src + -@if exist $(BIN)\GUI rmdir /S /Q $(BIN)\GUI + -@if exist $(BIN) rmdir /S /Q $(BIN) + -@if exist $(EXE) rmdir /S /Q $(EXE) + -@if exist $(RELEASE) rmdir /S /Q $(RELEASE) diff --git a/Src/PasHi.cfg.tplt b/Src/PasHi.cfg.tplt index 1a31056..51b59bd 100644 --- a/Src/PasHi.cfg.tplt +++ b/Src/PasHi.cfg.tplt @@ -30,14 +30,14 @@ -M -$M16384,1048576 -K$00400000 --E"..\Exe" --N"..\Bin" +-E"..\Build\Exe" +-N"..\Build\Bin" -LE"." -LN"." --U"..\Bin" --O"..\Bin" --I"..\Bin" --R"..\Bin" +-U"..\Build\Bin" +-O"..\Build\Bin" +-I"..\Build\Bin" +-R"..\Build\Bin" -w-SYMBOL_PLATFORM -w+EXPLICIT_STRING_CAST_LOSS -w+CVT_WIDENING_STRING_LOST diff --git a/Src/PasHi.dproj b/Src/PasHi.dproj index 4fd4bf9..b47cb86 100644 --- a/Src/PasHi.dproj +++ b/Src/PasHi.dproj @@ -4,23 +4,27 @@ PasHi.dpr Base DCC32 - 12.0 + 12.3 + True + Win32 + Console + None true false - ..\Bin;$(DCC_UnitSearchPath) + ..\Build\Bin;$(DCC_UnitSearchPath) ..\Exe\PasHi.exe - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - ..\Exe + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) + ..\Build\Exe 00400000 true true true x86 - ..\Bin + ..\Build\Bin 1 @@ -70,7 +74,8 @@ Base - + + Delphi.Personality.12 VCLApplication @@ -79,11 +84,7 @@ PasHi.dpr - - False - True - False - + False False @@ -112,14 +113,17 @@ - Embarcadero InterBase Express Components - Embarcadero ADO DB Components - Embarcadero WebSnap Components - Embarcadero InternetExpress Components - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components + Embarcadero InterBase Express Components + Embarcadero ADO DB Components + Embarcadero WebSnap Components + Embarcadero InternetExpress Components + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + True + 12 From ed1bdab3e6815c371e5eef54b3e6c98fcf4d7e1c Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sat, 28 Nov 2015 14:15:10 +0000 Subject: [PATCH 30/80] Updated re changes in file locations and required utility programs. --- Build.html | 124 ++++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 64 deletions(-) diff --git a/Build.html b/Build.html index bac2c6d..9edb184 100644 --- a/Build.html +++ b/Build.html @@ -93,29 +93,8 @@

Note: - These instructions do not apply to the following versions of the program: -

- -
    -
  • - Release 1.1.0. See the version of Build.html in the - tags/version-1.1.0 branch of the repository. -
  • -
  • - PasH - release 1.0.0 or earlier or - PasHGUI - release 0.1.0. - For instructions on how to build these versions please refer to the - ReadMe-Src.txt files that are to be found in the - Docs or root directories of the relevant source code trees. -
  • -
- -

- PasH - and PasHGUI are the old names for PasHi and - PasHiGUI. + These instructions do not apply to versions of the program before release + v2.0.0.

@@ -188,30 +167,39 @@

DCC32
- The Delphi command line compiler. +

+ The Delphi command line compiler. +

+
+ Not available with starter editions of Delphi. +
RC
- The Microsoft resource compiler. Used to compile the main resource file. +

+ The Microsoft resource compiler. Used to compile the main resource file. +

BRCC32
- The Borland resource compiler. Used to compile version information resources - from temporary resource files emitted by VIEd (see below) +

+ The Borland resource compiler. Used to compile version information + resources from temporary resource files emitted by VIEd (see below). +

- We use two different resource compilers because RC fails to - compile resource files emitted by the Version Information Editor while - BRCC32 can fail to compile .manifest files + We use two different resource compilers because RC fails to + compile resource files emitted by the Version Information Editor while + BRCC32 can fail to compile .manifest files correctly.
- +

The following environment variables are associated with these tools:

@@ -221,18 +209,22 @@

DELPHIROOT - required unless DELPHIXE is set.
- Should be set to the install directory of the version of Delphi being - used. DCC32 and BRCC32 are expected to be in - the Bin sub-directory of DELPHIROOT. +

+ Should be set to the install directory of the version of Delphi being + used. DCC32 and BRCC32 are expected to be in + the Bin sub-directory of DELPHIROOT. +

DELPHIXE - optional
- If you are using Delphi XE this environment variable should be set to the - Delphi install directory. When DELPHIXE is specified - DELPHIROOT will ignore its own value and use the value of - DELPHIXE instead. +

+ If you are using Delphi XE this environment variable should be set to the + Delphi install directory. When DELPHIXE is specified + DELPHIROOT will ignore its own value and use the value of + DELPHIXE instead. +

@@ -343,9 +335,10 @@

PasHi's latest stable source code can be found in the master - branch while development code is maintained in the develop branch. - You can also download the code of one of the releases by selecting the - relevant tag. + branch while development code is maintained in the develop branch and + new features are developed in branches whose name begins with + feature. You can also download the code of one of the releases by + selecting the relevant tag.

@@ -379,15 +372,15 @@

| | | | | +-- Imported - 3rd party source code used for GUI application | | | - | | +-- Resources - assets required to build PasHiGUI's resources + | | +-- Assets - assets required to build PasHiGUI's resources | | | +-- Install - install program scripts | +-- Test - contains test file

- If, by chance, you also have Bin, Exe and - Release directories don't worry - all will become clear. + If, by chance, don't worry if you also have a Build directory and + sub-directories - all will become clear.

@@ -423,18 +416,20 @@

./
-  +-- Bin                   - receives object files and .res files for PasHi
+  +-- Build                 - receives all files created by the build process
+  |   |
+  |   +-- Bin               - receives object files and .res files for PasHi
+  |   |
+  |   +-- Exe               - receives executable code
+  |   |
+  |   +-- Release           - receives release files
   |
   +-- Config                - config files to be installed with PasHi
   |
   +-- Docs                  - documentation
-  |
-  +-- Exe                   - receives executable code
-  |
+  |
   +-- Masters               - documents used to generate some project files
-  |
-  +-- Release               - receives release files
-  |
+  |
   +-- Src                   - source code for PasHi
   |   |
   |   +-- Assets            - assets required to build PasHi's resources
@@ -443,7 +438,7 @@ 

| | | | | +-- Imported - 3rd party source code used for GUI application | | | - | | +-- Resources - assets required to build PasHiGUI's resources + | | +-- Assets - assets required to build PasHiGUI's resources | | | +-- Install - install program scripts | @@ -470,20 +465,22 @@

./
-  +-- Bin                   - receives object files and .res files for PasHi
-  |   |
-  |   +-- GUI               - receives object files and .res files for PasHiGUI
-  |
+  +-- Build                 - receives all files created by the build process
+  |   |
+  |   +-- Bin               - receives object files and .res files for PasHi
+  |   |   |
+  |   |   +-- GUI           - receives object files and .res files for PasHiGUI
+  |   |
+  |   +-- Exe               - receives executable code
+  |   |
+  |   +-- Release           - receives release files
+  |
   +-- Config                - config files to be installed with PasHi
   |
   +-- Docs                  - documentation
   |
-  +-- Exe                   - receives executable code
-  |
   +-- Masters               - documents used to generate some project files
   |
-  +-- Release               - receives release files
-  |
   +-- Src                   - source code for PasHi
   |   |
   |   +-- Assets            - assets required to build PasHi's resources
@@ -492,13 +489,12 @@ 

| | | | | +-- Imported - 3rd party source code used for GUI application | | | - | | +-- Resources - assets required to build PasHiGUI's resources + | | +-- Assets - assets required to build PasHiGUI's resources | | | +-- Install - install program scripts | +-- Test - contains test file

-

Make will also have created the required .cfg file in the Src\GUI directory. @@ -582,8 +578,8 @@

So, to build PasHi and PasHiGUI and place - PasHi.exe and PasHiGUI.exe in the Exe - folder do this: + PasHi.exe and PasHiGUI.exe in the + Build\Exe folder do this:

Src> Make

From 69155d0434403f3db2cdcabf9b11b0bc8f2c87be Mon Sep 17 00:00:00 2001
From: DelphiDabbler 
Date: Sat, 28 Nov 2015 14:15:56 +0000
Subject: [PATCH 31/80] Updated re changes in 3rd party code, source tree and
 documentation.

---
 Docs/SourceCodeLicenses.txt | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/Docs/SourceCodeLicenses.txt b/Docs/SourceCodeLicenses.txt
index fb0233f..d2d9c16 100644
--- a/Docs/SourceCodeLicenses.txt
+++ b/Docs/SourceCodeLicenses.txt
@@ -12,6 +12,7 @@ PasHiGUI source.
 The source code includes:
 
 + Original Source Code written by Peter Johnson.
++ Some third party code.
 + Documentation.
 + Image files.
 + Sample files.
@@ -33,7 +34,7 @@ Original source files are stored in the the following directories:
 + Src
 + Src\Assets
 + Src\GUI
-+ Src\GUI\Resources
++ Src\GUI\Assets
 
 Any original source code file that is governed by a license has a comment to
 that effect in the source file.
@@ -49,15 +50,16 @@ copy of this license can be found in MPL-2.txt in the Docs directory.
 3rd Party Source Code
 --------------------------------------------------------------------------------
 
-3rd Party source code is stored in the Src\3rdParty directory. At the time of
-writing there is no 3rd party code.
+3rd Party source code required by PasHiGUI is stored in the Src\GUI\Imported
+directory. At the time of writing the only such code is PJWdwState.pas which is
+licensed under the Mozilla Public License v2.0.
 
 --------------------------------------------------------------------------------
 Documentation
 --------------------------------------------------------------------------------
 
-Documentation files are maintained in the Docs directory. In addition the
-Build.html file is maintained in the root directory.
+Documentation files are maintained in the Docs directory. In addition
+Build.html, LICENSE and README.md are maintained in the root directory.
 
 Terms and conditions apply to the following files. For other files please refer
 to the document, or, in the case of HTML files, the source code. Where no
@@ -68,8 +70,8 @@ ChangeLog.txt
 May only be updated to describe changes made to the release of any derivative
 work. You are urged to maintain this file, but it may be removed if desired.
 
-License.txt
------------
+LICENSE
+-------
 May not be changed.
 
 MPL-2.txt
@@ -77,9 +79,15 @@ MPL-2.txt
 This file may not be modified and should be distributed with any derivative
 work.
 
-ReadMe.html
------------
-Restrictions apply. See the comments contained in the HTML source for details.
+README.md
+---------
+The file can be modified to reflect any changes to the project that need to be
+mentioned here.
+
+ReadMe.txt
+----------
+This file should be modified re any changes made to the program that need to be
+reflected here.
 
 SourceCodeLicenses.txt
 ----------------------
@@ -87,6 +95,10 @@ May be updated to provide license information that applies to any additional
 source files. Information pertaining to unmodified existing files must be
 retained.
 
+UserGuide.html
+--------------
+Restrictions apply. See the comments contained in the HTML source for details.
+
 --------------------------------------------------------------------------------
 Image Files
 --------------------------------------------------------------------------------

From fb9c93bdca0948dc75a4df557ae3040763c22dc6 Mon Sep 17 00:00:00 2001
From: DelphiDabbler 
Date: Sat, 28 Nov 2015 16:53:36 +0000
Subject: [PATCH 32/80] Removed content that is now in ReadMe.txt and made some
 corrections / clarifications.

---
 Docs/UserGuide.html | 345 ++++++--------------------------------------
 1 file changed, 41 insertions(+), 304 deletions(-)

diff --git a/Docs/UserGuide.html b/Docs/UserGuide.html
index 60d747b..2fdbd41 100644
--- a/Docs/UserGuide.html
+++ b/Docs/UserGuide.html
@@ -2,14 +2,14 @@
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
 
 
@@ -18,7 +18,7 @@
 
 
   
-    DelphiDabbler || PasHi Pascal Highlighter
+    PasHi Pascal Highlighter User Guide
   
 
   
   
PasHi Pascal Highlighter
-
Read Me Document
+
User Guide

@@ -245,10 +245,7 @@

Introduction
  • - Why another Pascal highlighter? -
  • -
  • - Installation + Installation
  • Using PasHi @@ -262,12 +259,6 @@

  • Using PasHiGUI
  • -
  • - Bugs & Feature Requests -
  • -
  • - Source code -
  • @@ -309,215 +300,17 @@

    and dropped onto the window to highlight them.

    -

    - Check Hallvard's Blog for an example of a site using PasHi. - PasHi has also been used to highlight example source code on the - DelphiDabbler Delphi Tips and - Articles pages. -

    -

    » Contents

    -

    - Why another Pascal highlighter? -

    - -

    - Simple, I wanted an easy to use tool to format Pascal code for the - DelphiDabbler website. I wanted the following: -

    - -
      -
    1. - Conformant XHTML and later HTML 5. -
    2. -
    3. - Styling by means of cascading style sheets. -
    4. -
    5. - Full control over the appearance of the output code. -
    6. -
    7. - Ability to highlight via the clipboard. -
    8. -
    9. - The option to generate HTML fragments for inserting into existing - documents. -
    10. -
    - -

    - On checking the available free tools I found that they were either too complex - or they didn't provide one or more of the features I wanted. -

    - -

    - I had already written highlighter code for my CodeSnip program, so I extracted that, tweaked it and wrapped it up - in a command line program. Having made it I thought I'd release it in case - anyone else found it useful. Since then it's been greatly enhanced. -

    - -

    - » Contents -

    - -

    +

    Installation

    -
    -

    - PasHi requires Windows 2000 or later to run. You need to have - administrative privileges to install it. Elevation may be required to - install on Windows Vista and later. -

    -

    - If you have PasHi v1.x or earlier you need to remove it before - installing this version. These early versions of the program have no setup - program, so you must uninstall manually. Simply find the program (and - PasHiGUI if you have it) and delete the executable file(s) along - with any support files you installed. If you included the v1.x install - directory on the system path you should remove it. -

    -
    - -

    - PasHi is provided in a zip file that contains a setup program, - PasHi-Setup-xxx.exe (where xxx is the program's version number). - The zip file also contains this read-me file. -

    - -

    - Extract the setup program from the zip file and run it, following the - on-screen instructions. -

    - -

    - You will need to accept the license before configuring and completing the - installation. The license is permissive and lets you copy and share - PasHi freely. You can also modify it providing you make the source - code of your changes freely available. -

    -

    - After agreeing to the license the installer you choose the installation - directory followed by the name of the start menu program group. Following that - you have three options, all of which are selected by default: -

    - -
      - -
    1. - Add PasHi's directory to the system path for all users:
      - This lets - you run PasHi simply by typing its name on the command line, - without specifying the path to the program. The installer modifies the - system PATH environment variable. This option is recommended for everyone. -
    2. -
    3. - Install sample style sheets and config file templates:
      - This option installs various CSS style sheets and config file templates. These files will appear in your - %AppData%\DelphiDabbler\PasHi directly immediately after you - first run PasHi. The files take up very little disk space so this - option is recommended unless you are sure you will never need to use the - files. -
    4. -
    5. - Install GUI front end program, PasHiGUI:
      - This installs the PasHiGUI program alongside PasHi. This program is - worth installing if you prefer to use PasHi from a GUI rather than - mastering the command line. Most, but not all, of PasHi's options - are available from PasHiGUI. -
    6. -
    - -

    - Once you have made your choices, you can review them then either go back to - make changes or commit to installing. Once installation is complete then the - last page is displayed. It gives an option to display this ReadMe file. If you - have installed PasHiGUI you are given the option to run it. -

    - -

    - The installer makes the following changes to your system: -

    - -
      -
    • - The main program's executable files and documentation are installed into the - chosen install folder (%ProgramFiles%\DelphiDabbler\PasHi by - default). If you chose to install it, PasHiGUI will also be placed - in this directory. -
    • -
    • - Files required by the uninstaller are stored in the main installation's - Uninst sub-folder. -
    • -
    • - The program's uninstall information is registered with the Add / Remove - Programs (aka Programs and Features) control panel applet. -
    • -
    • - The system path may be updated if you chose the relevant option. -
    • -
    • - A program group will be created in the start menu. -
    • -
    • - Sample .css and config files are installed in - %ProgramData%\DelphiDabbler\PasHi. The first time that - PasHi is run by each user, these files are also copied to that - users's %AppData%\DelphiDabbler\PasHi directory. -
    • -
    - -

    - Uninstallation -

    - -

    - Open the Add / Remove Programs (Programs and Features) applet from the Control - Panel, navigate to the DelphiDabbler PasHi entry and click the - Remove or Uninstall button. You will be asked to confirm - removal of the program. Click Yes to proceed. -

    - -

    - PasHi, PasHiGUI (if installed) and all documentation will - be removed. -

    - -

    - The directory %ProgramData%\DelphiDabbler\PasHi will be removed - but each user's %AppData%\DelphiDabbler\PasHi directory and all - its files will be left behind. -

    - -

    - PasHi's install directory will be removed from the system path if - present. -

    - -

    - » Contents + Details of how to install PasHi and PasHiGUI are provided in + the file ReadMe.txt that is included in the program download.

    @@ -529,7 +322,7 @@

    - By default PashHi reads input from standard input and writes + By default PasHi reads input from standard input and writes highlighted output to standard output. You can process a single file and write output to another file using shell redirection. For example, to highlight source.pas and output to source.html use: @@ -557,7 +350,7 @@

    - PashHi's behaviour can be modified by specifying one or more file + PahHi's behaviour can be modified by specifying one or more file names and / or commands on the command line. File names and commands can be intermixed.

    @@ -848,8 +641,8 @@

    When using the --embed-css or --link-css you should be careful to ensure that the class names in the CSS file you are embedding or linking provides the correct class names.
    - This command is provided mainly when you are committed to using the old - CSS style names. + This command is provided for when you are committed to using the old CSS + style names. @@ -916,8 +709,8 @@

    Specifies the number of blank lines to insert between the contents of each source file. The required number of lines is given in the following parameter and must be in the range 0..16. The default value is 1.
    - This command is ignored unless more than file is specified on the command - line. + This command is ignored unless more than one file is specified on the + command line. @@ -1118,7 +911,7 @@

    - PasHi uses the following exit code: + PasHi uses the following exit codes:

      @@ -1131,10 +924,6 @@

    -

    - When PasHi exits normally then the exit code is 0. -

    -

    Usage example

    @@ -1188,9 +977,9 @@

    - PasHi reads any config file that is present in the - %AppData%\DelphiDabbler\PasHi directory when it starts up. Any - commands it finds in that file can be used to change the program's default + If PasHi finds a file named config in the + %AppData%\DelphiDabbler\PasHi directory when it starts up, it is + read. Any commands found in that file are used to change the program's default state.

    @@ -1249,9 +1038,8 @@

    Some example config scripts are optionally installed in - %AppData%\DelphiDabbler\PasHi. (If you installed them you may - need to run PasHi once for the files to appear). The sample scripts - are: + %AppData%\DelphiDabbler\PasHi. The files may not appear in that + folder until after PasHi has been run once. The sample scripts are:

    @@ -1266,7 +1054,7 @@

    config-v1
    - Emulates, as far as possible the actions of PasHi. This script + Emulates, as far as possible the actions of PasHi v1. This script requires that the file v1-default.css (provided) is present in the same directory.
    @@ -1297,16 +1085,21 @@

    on its own on the command line and it will perform the required actions by - default. Be warned that if you do this, you will need to use the + default.

    + +

    + Be warned that if you do this, you will need to specify the --input-stdin, --output-stdout and - --doc-type xhtml commands to revert to normal default behaviour. + --doc-type xhtml commands on the command line to revert to + default behaviour.

    Another useful example is if you provide your own CSS file containing your - desired highlighting style that you always want to use. To save you having - to specify this file on the command line each time, simply put a suitable - command in config. For example, to embed CSS use something like: + desired highlighting style that you always want to embed in your highlighted + document. To save you having to specify this file on the command line each + time, simply put a suitable command in config. For example, to + embed CSS use something like:

    embed-css C:\CSS\my-style.css
    @@ -1320,7 +1113,8 @@

    embed-css twilight.css

    - You can also link to your CSS file. For example: + If you prefer to link to your CSS file instead of embedding it, you can add + the following line to config:

    link-css http://example.com/css/my-style.css
    @@ -1896,7 +1690,7 @@

    dropped file(s). Folders are ignored.

  • - Drag and drop selected text from a suitable text editor: the selected text + Drag and drop selected text from a compatible text editor: the selected text is syntax highlighted and is assumed to be valid Pascal source code.
  • @@ -1906,79 +1700,22 @@

    - PasHiGUI will not work unless a suitable version of PasHi is - installed in the same directory and is the correct version. Using the - installer to install both programs is the best means of ensuring that - everything is set up correctly. -

    - -

    - » Contents -

    - -

    - Bugs & Feature Requests -

    - -

    - Please do report bugs and request new features. To do this please use the issue tracker. Do review any existing reports before raising a new - issue. -

    - -

    - » Contents -

    - -

    - Source code -

    - -

    - The source code for PasHi and PasHiGUI is hosted in - Subversion repository on GoogleCode. The repository can be viewed at http://code.google.com/p/pas-hi/source/browse/. -

    - -

    - Zip files containing source code are hosted on the project's GoogleCode download tab. -

    - -

    - Finally, the latest release of the source code is always available via the - PasHi home page. -

    - -

    - You will find a file named Build.html in the root directory of - each source code distribution that explains how to build the programs. + PasHiGUI will not work unless PasHi is installed in the same + directory and is the correct version. Using the installer to install both + programs is the best means of ensuring that everything is set up correctly.

    -
    - If you have any comments about this program please get in touch via my - website. But do please use the issue tracker - mentioned above to report bugs rather than contacting me direct. -
    -
    From 0d95dbbfd12fc217d4f0b8009bde381c98189aec Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Sun, 29 Nov 2015 00:28:13 +0000 Subject: [PATCH 33/80] Changed style of tag so it's text doesn't line break. Removed redundant   attributes from text in tags. --- Docs/UserGuide.html | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/Docs/UserGuide.html b/Docs/UserGuide.html index 2fdbd41..c7af359 100644 --- a/Docs/UserGuide.html +++ b/Docs/UserGuide.html @@ -225,6 +225,9 @@ border: 1px silver solid; padding: 2px 6px; } + code { + display: inline-block; + } @@ -502,7 +505,7 @@

    follows this command. The code is not checked. If this command is not supplied then no language information is included in the output file.
    - This command has no effect if the --doc-type fragment + This command has no effect if the --doc-type fragment command is used. @@ -523,7 +526,7 @@

    Sets the title of the output document. The title text must be supplied in the parameter immediately follow the command. Titles containing spaces must be enclosed in double quotes.
    - This command has no effect if the --doc-type fragment + This command has no effect if the --doc-type fragment command is also used. @@ -536,7 +539,7 @@

    restore that behaviour if it has been overridden in the config file. This command has no effect if the - --doc-type fragment command is also used. + --doc-type fragment command is also used. @@ -555,7 +558,7 @@

    Do not combine this command with --link-css or default-css because the commands are mutually exclusive. --embed-css is ignored if the - --doc-type fragment command is also used. + --doc-type fragment command is also used. @@ -566,7 +569,7 @@

    HTML file. The URL must be given in the parameter immediately following this command. The URL can be relative or absolute. The linked CSS file must define the styles described below.
    - This command is ignored if --doc-type fragment is also + This command is ignored if --doc-type fragment is also used. Since no CSS is embedded in the output file the --hide-css command does nothing if used with this command. Do not combine -link-css with --embed-css or @@ -584,7 +587,7 @@

    This command negates both the --embed-css and --link-css commands and should not be combined with them. --default-css is ignored if the - --doc-type fragment command is also used. + --doc-type fragment command is also used. @@ -614,7 +617,7 @@

    -c+ and -c1 hide the CSS in comments while -c- and -c0 do not.
    --hide-css is ignored when either the - --doc-type fragment or --link-css commands + --doc-type fragment or --link-css commands are used. @@ -829,7 +832,7 @@

    --quiet -q - Alias for the --verbosity quiet command. + Alias for the --verbosity quiet command. @@ -873,13 +876,13 @@

    -frag - Alias for the --doc-type fragment command. + Alias for the --doc-type fragment command. -hidecss - Alias for -c+ or the --hide-css yes + Alias for -c+ or the --hide-css yes command. @@ -1286,7 +1289,7 @@

  • Include a code fragment generated by the - --doc-type fragment command in another HTML file. + --doc-type fragment command in another HTML file.
  • @@ -1425,8 +1428,8 @@

    remaining classes had pas- prepended to the class name, for example .kwd was .pas-kwd. If you want PasHi to revert to using the old style names pass - "--legacy-css on" on the command line or place - "legacy-css on" in the config file + "--legacy-css on" on the command line or place + "legacy-css on" in the config file if you want to use the old style names by default.

    From d70c31d38801b2d5fb102b60424c85bbe586e0e9 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 2 Mar 2016 16:08:20 +0000 Subject: [PATCH 34/80] Rationalised all license info into single LICENSE file. --- Docs/SourceCodeLicenses.txt | 124 ------------------------------------ LICENSE | 4 ++ 2 files changed, 4 insertions(+), 124 deletions(-) delete mode 100644 Docs/SourceCodeLicenses.txt diff --git a/Docs/SourceCodeLicenses.txt b/Docs/SourceCodeLicenses.txt deleted file mode 100644 index d2d9c16..0000000 --- a/Docs/SourceCodeLicenses.txt +++ /dev/null @@ -1,124 +0,0 @@ -================================================================================ - -PASHI SOURCE CODE LICENSING - -================================================================================ - -This document discusses and presents the relevant licenses governing the PasHi -source code as maintained in the PasHi Subversion code repository and provided -for download in compressed archives. The PasHi source code also includes the -PasHiGUI source. - -The source code includes: - -+ Original Source Code written by Peter Johnson. -+ Some third party code. -+ Documentation. -+ Image files. -+ Sample files. - -Please refer to the relevant section below fo details of licensing. - -The download does not include all the source code required to rebuild the PasHi -project. Explicitly it doesn't include: - -+ Source files from the Delphi 2010 VCL. You must have Delphi in order to access - these files. - --------------------------------------------------------------------------------- -Original Source Code --------------------------------------------------------------------------------- - -Original source files are stored in the the following directories: - -+ Src -+ Src\Assets -+ Src\GUI -+ Src\GUI\Assets - -Any original source code file that is governed by a license has a comment to -that effect in the source file. - -Any other source code files that contain no copyright or license information can -be used without restriction. The exception is .dfm files which are licensed -under then same terms as .pas files with the same name. - -Many source code files are licensed under the Mozilla Public License v2. A full -copy of this license can be found in MPL-2.txt in the Docs directory. - --------------------------------------------------------------------------------- -3rd Party Source Code --------------------------------------------------------------------------------- - -3rd Party source code required by PasHiGUI is stored in the Src\GUI\Imported -directory. At the time of writing the only such code is PJWdwState.pas which is -licensed under the Mozilla Public License v2.0. - --------------------------------------------------------------------------------- -Documentation --------------------------------------------------------------------------------- - -Documentation files are maintained in the Docs directory. In addition -Build.html, LICENSE and README.md are maintained in the root directory. - -Terms and conditions apply to the following files. For other files please refer -to the document, or, in the case of HTML files, the source code. Where no -licensing or restrictions apply the files can be used freely. - -ChangeLog.txt -------------- -May only be updated to describe changes made to the release of any derivative -work. You are urged to maintain this file, but it may be removed if desired. - -LICENSE -------- -May not be changed. - -MPL-2.txt ---------- -This file may not be modified and should be distributed with any derivative -work. - -README.md ---------- -The file can be modified to reflect any changes to the project that need to be -mentioned here. - -ReadMe.txt ----------- -This file should be modified re any changes made to the program that need to be -reflected here. - -SourceCodeLicenses.txt ----------------------- -May be updated to provide license information that applies to any additional -source files. Information pertaining to unmodified existing files must be -retained. - -UserGuide.html --------------- -Restrictions apply. See the comments contained in the HTML source for details. - --------------------------------------------------------------------------------- -Image Files --------------------------------------------------------------------------------- - -The only images provided are the icons for PasHi and PasHiGUI: PasHi.ico and -MainIcon.ico respectively. These files are copyright 2009 and 2006 respectively -by Peter Johnson (www.delphidabbler.com). - -The files may not be altered in any way and may not be used in any other -programs, including programs derived from the PasHi or PasHiGUI source code, -unless explicit permission is given by the author. - -This means that if you modify the source and publish your changes then you must -remove the icon or replace it with you own. - --------------------------------------------------------------------------------- -Sample Files --------------------------------------------------------------------------------- - -Sample files are found in the Config and Test directories. These files may be -used freely, without warranty of any kind. - --------------------------------------------------------------------------------- diff --git a/LICENSE b/LICENSE index 97e49ad..5ce9bba 100644 --- a/LICENSE +++ b/LICENSE @@ -26,6 +26,10 @@ Mozilla Public License v2.0. Most source files will contain a comment to this effect. Any file without such a comment should be treated as being covered by this license unless it is mentioned below. +Third party code can be found in the `Src/GUI/Imported` directory. This code +carries its own license. Licensing information will be found in the `ReadMe.txt` +file in the same directory. + Exceptions ---------- From eaf72cd10d86b6ec3daa13338f4679c2fe8184f6 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 2 Mar 2016 16:09:13 +0000 Subject: [PATCH 35/80] Updated name of LICENSE file. --- Docs/License.rtf | Bin 1483 -> 1438 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Docs/License.rtf b/Docs/License.rtf index 3d71b918e5e98834f07366cb9aa5b5b0f988d23e..a26f4ecc005fa1dd422c07c47db39f43eca64200 100644 GIT binary patch delta 275 zcmX@jJ&${W99Ld`X=ZYMZb4$nL|NB~?XHeNnaLTcDMkhgh6Z{DdWHt37G||EWtpkv z*_nAMCNZVSh6=n~F$IZ5DKW)~hK9y5X$CQA#fBC!If;4ch6cvQlX)4Hnbi|5C)+TZ zOwMPNo!rYP!K+YPTOE^@lTuWiQ&J5Q;fyKGF^EY{GpL<>iP4e+s9wRyz`$&>Bcnc1 zn$|LPfYr4#E1($;6hRoic{%ePMmA4pSHED_$-S&fGD$IMhCufk8GzkuWMFCz@(V9l IEiV@X0KD5*=>Px# delta 307 zcmbQoeVTiM+(b>6iC(1XHl{2ywLCjBFU2ILG}$nwAh9SVrZ~~i&^RV1F)!WFz}Pq@%^)VN*wA9)XJx@O z!sg5bliAhc~Q~=3L z-oR+dgRFb<8%7f%HHu80&QtdcCp>zMB_a%Co`<`t*vl~j~WPGD7% c0r|qnz|=e@2^bDQe;65n{K(5y%ge<804LL7*Z=?k From c9ea8c5a6ee242c5185c32fefa1ae5e2549775a1 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 2 Mar 2016 16:13:22 +0000 Subject: [PATCH 36/80] Changed link to PasHi license to GitHub. --- Docs/UserGuide.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Docs/UserGuide.html b/Docs/UserGuide.html index c7af359..7b3ee14 100644 --- a/Docs/UserGuide.html +++ b/Docs/UserGuide.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> @@ -362,8 +362,6 @@

    | +-- Docs - documentation | - +-- Masters - documents used to generate some project files - | +-- Src - source code for PasHi | | | +-- Assets - assets required to build PasHi's resources @@ -428,8 +426,6 @@

    | +-- Docs - documentation | - +-- Masters - documents used to generate some project files - | +-- Src - source code for PasHi | | | +-- Assets - assets required to build PasHi's resources @@ -479,8 +475,6 @@

    | +-- Docs - documentation | - +-- Masters - documents used to generate some project files - | +-- Src - source code for PasHi | | | +-- Assets - assets required to build PasHi's resources @@ -693,8 +687,8 @@

    If you are planning to re-use or modify any of the code, please see the - SourceCodeLicenses.txt file in the Docs directory - for an overview of the open source licenses that apply to the source code. + LICENSE file for an overview of the open source licenses that + apply to the source code.

    From 073213093459ab4f7831627502adedf5763efcea Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 2 Mar 2016 21:00:41 +0000 Subject: [PATCH 42/80] Updated copyright dates to include 2016 --- Docs/License.rtf | Bin 1438 -> 1438 bytes Docs/UserGuide.html | 2 +- LICENSE | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Docs/License.rtf b/Docs/License.rtf index a26f4ecc005fa1dd422c07c47db39f43eca64200..5eb3ea48f150cb66ddb186495e1b2a3690f6b906 100644 GIT binary patch delta 22 ecmbQoJ&${X4kM%4B&O+;k1$#@nr&j5#|!{ZfCjMu delta 22 ecmbQoJ&${X4kM$ Date: Wed, 2 Mar 2016 21:24:59 +0000 Subject: [PATCH 43/80] Updated about box copyright date to include 2016 --- Src/GUI/FmMain.pas | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/GUI/FmMain.pas b/Src/GUI/FmMain.pas index adf2f34..cfd6e72 100644 --- a/Src/GUI/FmMain.pas +++ b/Src/GUI/FmMain.pas @@ -3,7 +3,7 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2006-2014, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2006-2016, Peter Johnson (www.delphidabbler.com). * * Application's main form. Handles main user inteface interaction. } @@ -233,7 +233,7 @@ procedure TMainForm.actAboutExecute(Sender: TObject); + #10#10 + 'A GUI front end for the PasHi Syntax Highlighter v2.' + #10#10 - + 'Copyright (c) 2006-2015 by Peter D Johnson (www.delphidabbler.com).' + + 'Copyright (c) 2006-2016 by Peter D Johnson (www.delphidabbler.com).' + #10#10 + 'Released under the terms of the Mozilla Public License v2.0. ' + 'See the LICENSE file for full details.' From aa403a5e7cd5eae5645041b824d9895042f6fbb8 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Mon, 4 Apr 2016 12:31:25 +0100 Subject: [PATCH 44/80] Corrected name of command reference file --- Config/config-template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/config-template b/Config/config-template index efb07de..be07d3e 100644 --- a/Config/config-template +++ b/Config/config-template @@ -14,7 +14,7 @@ # commented and lists every available configuration option. # # Possible commands are noted below. For an explanation of each command, and its -# permitted parameters (if any) see the command reference in ReadMe.html. +# permitted parameters (if any) see the command reference in UserGuide.html. # # FILE FORMAT # ----------- From fd9126644f9491f0166aee9a873572f3c370421f Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Mon, 4 Apr 2016 12:31:43 +0100 Subject: [PATCH 45/80] Fixed typo --- Config/notebook.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/notebook.css b/Config/notebook.css index 17f4ec6..b4b635f 100644 --- a/Config/notebook.css +++ b/Config/notebook.css @@ -11,7 +11,7 @@ need a modified version of the file, make a copy in a different directory or with a different name and edit that. - Note that some older browser, particularly IE <=7 and Safari<=3, do not + Note that some older browsers, particularly IE <=7 and Safari<=3, do not support the last-child pseudo classes and so may not render this output as cleanly as conformant browsers. */ From b8e8050f820ff7b6e5fd9b9567f43fd83daf30d4 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Mon, 4 Apr 2016 12:33:09 +0100 Subject: [PATCH 46/80] Bumped Config folder version This ensures that user's config folder gets updated with new files on installation. --- Config/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/version b/Config/version index d8263ee..e440e5c 100644 --- a/Config/version +++ b/Config/version @@ -1 +1 @@ -2 \ No newline at end of file +3 \ No newline at end of file From ec89d1733aca152f47692dbf9e2f0e023f0485a5 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Tue, 5 Apr 2016 20:29:02 +0100 Subject: [PATCH 47/80] Tweaked layout and removed trailing spaces. --- Docs/ReadMe.txt | 119 +++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/Docs/ReadMe.txt b/Docs/ReadMe.txt index 6580837..9cc41d5 100644 --- a/Docs/ReadMe.txt +++ b/Docs/ReadMe.txt @@ -4,31 +4,31 @@ PasHi Pascal Highlighter - ReadMe File Introduction ------------ -PasHi is a fully featured command line program that highlights Pascal source -code. It reads the original source code from standard input, files or the -clipboard and writes the highlighted code as HTML to standard output, a file, +PasHi is a fully featured command line program that highlights Pascal source +code. It reads the original source code from standard input, files or the +clipboard and writes the highlighted code as HTML to standard output, a file, or the clipboard. -HTML 4, XHTML and HTML 5 are all supported. CSS is used for styling. Style -sheets may be external or can be embedded in the HTML document. Several -predefined style sheets are installed with the program. You can also create your +HTML 4, XHTML and HTML 5 are all supported. CSS is used for styling. Style +sheets may be external or can be embedded in the HTML document. Several +predefined style sheets are installed with the program. You can also create your own. -PasHi can either generate complete HTML documents or just fragments of HTML +PasHi can either generate complete HTML documents or just fragments of HTML code. HTML fragments make it easy to embed highlighted code in existing web -pages. Web page authors simply need to ensure that the necessary CSS classes are +pages. Web page authors simply need to ensure that the necessary CSS classes are available. The easiest way to do this is to use an external style sheet. -PasHiGUI, a GUI front end for PasHi, is included in the release. This provides a -point and click way of using PasHi. Most, but not all, command line options are -supported. Files and text can be dragged and dropped onto the window to +PasHiGUI, a GUI front end for PasHi, is included in the release. This provides a +point and click way of using PasHi. Most, but not all, command line options are +supported. Files and text can be dragged and dropped onto the window to highlight them. Why another Pascal highlighter? ------------------------------- -Simple, I wanted an easy to use tool to format Pascal code for the DelphiDabbler +Simple, I wanted an easy to use tool to format Pascal code for the DelphiDabbler website. I wanted the following: * Conformant XHTML and later HTML 5. @@ -37,97 +37,100 @@ website. I wanted the following: * Ability to highlight via the clipboard. * The option to generate HTML fragments for inserting into existing documents. -On checking the available free tools I found that they were either too complex +On checking the available free tools I found that they were either too complex or they didn't provide one or more of the features I wanted. -I had already written highlighter code for my CodeSnip program, so I extracted -that, tweaked it and wrapped it up in a command line program. Having made it I -thought I'd release it in case anyone else found it useful. Since then it's been +I had already written highlighter code for my CodeSnip program, so I extracted +that, tweaked it and wrapped it up in a command line program. Having made it I +thought I'd release it in case anyone else found it useful. Since then it's been greatly enhanced. Installation ------------ -PasHi requires Windows 2000 or later to run. You need to have administrative -privileges to install it. Elevation may be required to install on Windows Vista and later. +PasHi requires Windows 2000 or later to run. You need to have administrative +privileges to install it. Elevation may be required to install on Windows Vista +and later. -If you have PasHi v1.x or earlier you need to remove it before installing this -version. These early versions of the program have no setup program, so you must -uninstall manually. Simply find the program (and PasHiGUI if you have it) and -delete the executable file(s) along with any support files you installed. If you +If you have PasHi v1.x or earlier you need to remove it before installing this +version. These early versions of the program have no setup program, so you must +uninstall manually. Simply find the program (and PasHiGUI if you have it) and +delete the executable file(s) along with any support files you installed. If you included the v1.x install directory on the system path you should remove it. -PasHi is provided in a zip file that contains a setup program, -PasHi-Setup-xxx.exe (where xxx is the program's version number). The zip file +PasHi is provided in a zip file that contains a setup program, +PasHi-Setup-xxx.exe (where xxx is the program's version number). The zip file also contains this read-me file. Extract the setup program from the zip file and run it, following the on-screen instructions. -You will need to accept the license before configuring and completing the -installation. The license is permissive and lets you copy and share PasHi -freely. You can also modify it providing you make the source code of your +You will need to accept the license before configuring and completing the +installation. The license is permissive and lets you copy and share PasHi +freely. You can also modify it providing you make the source code of your changes freely available. -After agreeing to the license the installer you choose the installation -directory followed by the name of the start menu program group. Following that +After agreeing to the license the installer you choose the installation +directory followed by the name of the start menu program group. Following that you have three options, all of which are selected by default: 1. Add PasHi's directory to the system path for all users: - This lets you run PasHi simply by typing its name on the command line, - without specifying the path to the program. The installer modifies the + This lets you run PasHi simply by typing its name on the command line, + without specifying the path to the program. The installer modifies the system PATH environment variable. This option is recommended for everyone. 2. Install sample style sheets and config file templates: - - This option installs various CSS style sheets and config file templates. - These files will appear in your %AppData%\DelphiDabbler\PasHi directly - immediately after you first run PasHi. The files take up very little disk - space so this option is recommended unless you are sure you will never need + + This option installs various CSS style sheets and config file templates. + These files will appear in your %AppData%\DelphiDabbler\PasHi directly + immediately after you first run PasHi. The files take up very little disk + space so this option is recommended unless you are sure you will never need to use the files. 3. Install GUI front end program, PasHiGUI: - This installs the PasHiGUI program alongside PasHi. This program is worth - installing if you prefer to use PasHi from a GUI rather than mastering the - command line. Most, but not all, of PasHi's options are available from + This installs the PasHiGUI program alongside PasHi. This program is worth + installing if you prefer to use PasHi from a GUI rather than mastering the + command line. Most, but not all, of PasHi's options are available from PasHiGUI. - -Once you have made your choices, you can review them then either go back to make + +Once you have made your choices, you can review them then either go back to make changes or commit to installing. Once installation is complete then the last -page is displayed. It gives an option to display this ReadMe file. If you have +page is displayed. It gives an option to display this ReadMe file. If you have installed PasHiGUI you are given the option to run it. The installer makes the following changes to your system: - * The main program's executable files and documentation are installed into the - chosen install folder (%ProgramFiles%\DelphiDabbler\PasHi by default). If - you chose to install it, PasHiGUI will also be placed in this directory. + * The main program's executable files and documentation are installed into the + chosen install folder (%ProgramFiles%\DelphiDabbler\PasHi or + %ProgramFiles(x86)%\DelphiDabbler\PasHi by default on 32 bit and 64 bit + Windows respectively). If you chose to install it, PasHiGUI will also be + placed in the same directory. - * Files required by the uninstaller are stored in the main installation's + * Files required by the uninstaller are stored in the main installation's Uninst sub-folder. - * The program's uninstall information is registered with the Programs and + * The program's uninstall information is registered with the Programs and Features (aka Add / Remove Programs) control panel applet. * The system path may be updated if you chose the relevant option. * A program group will be created in the start menu. - * Sample .css and config files are installed in - %ProgramData%\DelphiDabbler\PasHi. The first time that PasHi is run by each - user, these files are also copied to that users's + * Sample .css and config files are installed in + %ProgramData%\DelphiDabbler\PasHi. The first time that PasHi is run by each + user, these files are also copied to that users's %AppData%\DelphiDabbler\PasHi directory. Uninstallation -------------- -Open the Programs and Features (aka Add / Remove Programs) applet from the -Control Panel, navigate to the DelphiDabbler PasHi entry and click the Remove or -Uninstall button. You will be asked to confirm removal of the program. Click Yes +Open the Programs and Features (aka Add / Remove Programs) applet from the +Control Panel, navigate to the DelphiDabbler PasHi entry and click the Remove or +Uninstall button. You will be asked to confirm removal of the program. Click Yes to proceed. PasHi, PasHiGUI (if installed) and all documentation will be removed. @@ -140,15 +143,15 @@ PasHi's install directory will be removed from the system path if present. Documentation ------------- -Details of how to use both the command line and GUI programs can be found in the +Details of how to use both the command line and GUI programs can be found in the file UserGuide.html that is installed with the program. Bug Reports ----------- -Please report any bugs using the program's issue tracker on GitHub at -. You will need a free GitHub +Please report any bugs using the program's issue tracker on GitHub at +. You will need a free GitHub account in order to create an issue. @@ -166,5 +169,5 @@ download from . License ------- -For details please see the file LICENSE that is installed in the same directory -where PasHi was installed. +For details please see the file LICENSE that is installed in the directory where +PasHi was installed. From ac85288b946146a832cfb862166f5f60ff5cdd1e Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Tue, 5 Apr 2016 20:29:23 +0100 Subject: [PATCH 48/80] Clarifications and corrections --- Docs/UserGuide.html | 136 +++++++++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 53 deletions(-) diff --git a/Docs/UserGuide.html b/Docs/UserGuide.html index bab802d..3ed9d6b 100644 --- a/Docs/UserGuide.html +++ b/Docs/UserGuide.html @@ -82,6 +82,13 @@ font-size: 9pt; font-weight: bold; } + h4 { + margin: 0.5em 0 0 0; + padding: 0; + font-size: 9pt; + font-weight: normal; + font-style: italic; + } p { margin: 0.5em 0 0 0; padding: 0; @@ -362,7 +369,7 @@

    If one or more file names are entered on the command line then input is taken from the files. Source code is read from each named file in turn and concatenated before being highlighted. Standard input is ignored. Specifying - one file name has the same effect as redirecting standard input from that + a single file name has the same effect as redirecting standard input from that file.

    @@ -377,7 +384,7 @@

    long form. They are explained in the following table.

    - +
    @@ -552,11 +559,11 @@

    below.
    If the file name includes no path information, e.g. delphi2006.css, then the file will be expected to be found in - %AppData%\DelphiDabbler\PasHi. To read a file from the - working directory, prepend .\ to it, e.g. + the %AppData%\DelphiDabbler\PasHi directory. To read a file + from the working directory, prepend .\ to it, e.g. .\delphi2006.css.
    Do not combine this command with --link-css or - default-css because the commands are mutually exclusive. + --default-css because the commands are mutually exclusive. --embed-css is ignored if the --doc-type fragment command is also used. @@ -594,10 +601,10 @@

    @@ -654,9 +663,7 @@

    @@ -987,10 +996,10 @@

    - PasHi does not install a config file, so if you need one - you must create your own. You can do this either by creating a new file or by - copying and editing one of the sample scripts provided with PasHi - (providing you installed them). + PasHi does not install a config file by default, so if + you need one you must create your own. You can do this either by creating a + new file or by copying and editing one of the sample scripts provided with + PasHi (providing you installed them).

    @@ -1004,7 +1013,8 @@

  • Where a command takes a parameter the parameter should be placed on the same line as the command, separated from it by one or more spaces. Parameters - containing spaces should not be quoted (unlike on the command line). + containing spaces should not be quoted (unlike on the + command line).
  • All the long form commands listed in

    - Warning: Although PasHi accepts the help command in a - config file you should never use it or the program will do - nothing except display the help screen, no matter what commands you pass on - the command line. + Warning: Although PasHi accepts the + help command in a config file you should never + use it or the program will do nothing except display the help screen, no + matter what commands you pass on the command line.

    @@ -1040,9 +1050,8 @@

    - Some example config scripts are optionally installed in - %AppData%\DelphiDabbler\PasHi. The files may not appear in that - folder until after PasHi has been run once. The sample scripts are: + Some example config scripts are optionally installed in the + %AppData%\DelphiDabbler\PasHi directory. The sample scripts are:

    @@ -1051,26 +1060,37 @@

    This script does nothing, but is copiously commented with all possible - commands. It is a good starting point for your own config script. + commands. Used in conjunction with the command reference above it is a good starting point for your own config + script.
    config-v1
    - Emulates, as far as possible the actions of PasHi v1. This script - requires that the file v1-default.css (provided) is present in - the same directory. + Emulates, as far as possible, the functioning of PasHi v1. This + script requires that the file v1-default.css (provided) is + present in the same directory.

    +

    + The example config files, where installed, may not appear in the + %AppData%\DelphiDabbler\PasHi directory until after + PasHi has been run once. +

    +

    Examples

    +

    + Example 1 +

    +

    - As mentioned in Using PasHi, a common use for PasHi is to highlight + As mentioned above, a common use for PasHi is to highlight source code from the clipboard as an HTML fragment and place the HTML back on the clipboard. Instead of using the necessary commands each time you run PasHi you can add the following to the config file: @@ -1097,12 +1117,16 @@

    default behaviour.

    +

    + Example 2 +

    +

    - Another useful example is if you provide your own CSS file containing your - desired highlighting style that you always want to embed in your highlighted - document. To save you having to specify this file on the command line each - time, simply put a suitable command in config. For example, to - embed CSS use something like: + Another useful example is where you have a CSS file containing your desired + highlighting style that you always want to embed in your highlighted document. + To save you having to specify a --embed-css command each time you + run PasHi, simply put the command in config, something + like:

    embed-css C:\CSS\my-style.css
    @@ -1117,11 +1141,16 @@

    If you prefer to link to your CSS file instead of embedding it, you can add - the following line to config: + a line to config like:

    link-css http://example.com/css/my-style.css
    +

    + Should you now need to revert PasHi to using its default CSS you will + need to include --default-css on the command line. +

    +

    CSS styles used by PasHi

    @@ -1163,23 +1192,24 @@

    .odd-line
    - These classes are applied to <pre> tags in even and odd - numbered lines respectively when code striping is switched on (see the - --striping command above). .even-line and - .odd-line must be styled differently otherwise striping will - have no visible effect. The usual use is to provide a different background - colour for alternate lines – hence the name "striping". + These classes are applied to <pre> tags in place of the + .line class in even and odd numbered lines respectively when + code striping is switched on (see the --striping command + above). .even-line and .odd-line must be styled + differently otherwise striping will have no visible effect. It is usual to + provide a different background colour for alternate lines – hence the + name "striping".
    .linenum
    This class is applied to any line numbers that may be prepended to the start - of a line (see --line-numbering and related commands). - .linenum can be used to set line number font style and colour + of a line (see --line-numbering and related commands above). + .linenum can be used to set line number, font style and colour along with the margin between the line number and source code, and any - separating border, for example. The font used should be mono spaced - otherwise the numbers may not line up correctly. + separating border. The font used should be mono spaced otherwise the numbers + may not line up correctly.
    From 743d98059fd0b8a7aee09852028646f2870175f6 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 6 Apr 2016 03:28:35 +0100 Subject: [PATCH 49/80] Clarifications and corrections --- Build.html | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Build.html b/Build.html index eaa5a31..43b1b64 100644 --- a/Build.html +++ b/Build.html @@ -122,7 +122,8 @@

    PasHiGUI requires PJWdwState.pas from the DelphiDabbler Window State Components, v5.6.1 or later. A copy of the required file is - included in the Src\GUI\Imported directory. + included in the Src\GUI\Imported directory. There is no need to + install the components into the DelphiIDE.

    @@ -211,8 +212,9 @@

    Should be set to the install directory of the version of Delphi being - used. DCC32 and BRCC32 are expected to be in - the Bin sub-directory of DELPHIROOT. + used. DCC32, BRCC32 and RC are + expected to be in the Bin sub-directory of + DELPHIROOT.

    @@ -220,10 +222,10 @@

    - If you are using Delphi XE this environment variable should be set to the - Delphi install directory. When DELPHIXE is specified - DELPHIROOT will ignore its own value and use the value of - DELPHIXE instead. + If you are using Delphi XE this environment variable may be set to its + install directory. When DELPHIXE is specified + DELPHIROOT will be ignored and DELPHIXE will be + used instead.

    @@ -352,8 +354,8 @@

    - After checking out or downloading and extracting the source code you should - have the following directory structure: + After obtaining the source code you should have the following directory + structure:

    ./
    @@ -377,7 +379,7 @@ 

    +-- Test - contains test file

    - If, by chance, don't worry if you also have a Build directory and + Don't worry if you also have a Build directory and sub-directories - all will become clear.

    From 2e178d7aa1bc3e158ec84d25f312c0836613f045 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 6 Apr 2016 03:28:55 +0100 Subject: [PATCH 50/80] Corrected header comment --- Src/Assets/Default.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Assets/Default.css b/Src/Assets/Default.css index a35dbb3..55093fb 100644 --- a/Src/Assets/Default.css +++ b/Src/Assets/Default.css @@ -3,9 +3,9 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2009-2012, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2009-2016, Peter Johnson (www.delphidabbler.com). * - * Contains default CSS applied to complete XHTML documents. + * Contains default CSS applied to complete HTML documents. * * Many classes have two names: the first name is that used by default in PasHi * v2 and later while the second name is the older PasHi v1 class name that is From 69ad1c9e81601d28588b8819658f50f7d5b1e5e9 Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 6 Apr 2016 03:29:26 +0100 Subject: [PATCH 51/80] Correction and clarification --- Src/Assets/Help.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Assets/Help.txt b/Src/Assets/Help.txt index a715aa9..cba2cbf 100644 --- a/Src/Assets/Help.txt +++ b/Src/Assets/Help.txt @@ -38,7 +38,7 @@ PasHi supports the following commands: tag in the output HTML document. The name of the CSS file must be supplied in the next parameter. File names containing no path information are read - from PasHi's application data directory. + from PasHi's per-user application data directory. --encoding -e Specifies the output encoding. The next parameter must provide one of the following values: utf-8 [default] @@ -70,7 +70,7 @@ PasHi supports the following commands: following values: yes - use PasHi v1 CSS class names no - use current CSS class names [default]. ---line-numbering -n Switches line numebring on or off. --line-numbering +--line-numbering -n Switches line numbering on or off. --line-numbering requires the next parameter to supply one of the following values: on - number each line of source code From 932ce63489722271bd0276354d69cfe4e7fea00b Mon Sep 17 00:00:00 2001 From: DelphiDabbler Date: Wed, 6 Apr 2016 03:29:42 +0100 Subject: [PATCH 52/80] Corrected generator name --- Src/GUI/Assets/fragment-tplt.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/GUI/Assets/fragment-tplt.html b/Src/GUI/Assets/fragment-tplt.html index 0044af3..c463eee 100644 --- a/Src/GUI/Assets/fragment-tplt.html +++ b/Src/GUI/Assets/fragment-tplt.html @@ -7,7 +7,7 @@ * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/ * - * Copyright (C) 2006-2012, Peter Johnson (www.delphidabbler.com). + * Copyright (C) 2006-2016, Peter Johnson (www.delphidabbler.com). * * Page used as template for highlighted code fragments. --> @@ -15,7 +15,7 @@ - + PasHiGUI - Delphi Code Fragment

  • Command--hide-css -c - Determines if the CSS code embedded in a <style> tag is - wrapped in HTML comment tags (<!-- ... - -->). This command is provided because some old browsers - will render the CSS as text unless it is enclosed in comment tags.
    + Determines if embedded CSS code is wrapped in HTML comment tags + (<!-- ... -->). This command is provided + because some old browsers will render the CSS as text unless it is + enclosed in comment tags.
    In the case of --hide-css the parameter following the command determines whether the CSS is hidden in comments or not. This parameter must be one of the following: @@ -633,7 +640,7 @@

  • True, 1, Y, yes or on: - Use legacy (PasHi v1 style class names. + Use legacy (PasHi v1) style class names.
  • False, 0, N, no or @@ -641,11 +648,13 @@

    Use new CSS class names (the default).

  • - When using the --embed-css or --link-css you - should be careful to ensure that the class names in the CSS file you are - embedding or linking provides the correct class names.
    - This command is provided for when you are committed to using the old CSS - style names. + This command is provided for when you have to maintain code that uses the + old CSS style names. New code should use the new class names.
    + When using the --embed-css or --link-css + commands you should be careful to ensure that the CSS file you are + embedding or linking defines the correct class names. The CSS files that + are optionally installed with PasHi define both legacy and new + CSS classes.

    Sets the character encoding used for output to the encoding specified in next parameter. HTML documents are marked with the chosen format and the - resulting file may include byte order marks. This command is ignored if - the --output-clipboard command is specified, because data is - always written to the clipboard in Unicode. Valid encoding parameters are: + resulting file may include byte order marks. Valid encoding parameters are:
    • utf-8 or utf8: Encodes in Unicode using @@ -677,6 +684,8 @@

      latin1: Encodes in ISO-8859-1 format.

    + This command is ignored if the --output-clipboard command is + specified, because data is always written to the clipboard in Unicode.