Memory leaks fixed

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5697 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
gbamber
2017-01-25 09:33:15 +00:00
parent 7b7bf9aa54
commit ca3030d268
7 changed files with 440 additions and 360 deletions

View File

@ -23,10 +23,10 @@
<VersionInfo> <VersionInfo>
<UseVersionInfo Value="True"/> <UseVersionInfo Value="True"/>
<MinorVersionNr Value="1"/> <MinorVersionNr Value="1"/>
<RevisionNr Value="13"/> <RevisionNr Value="14"/>
<StringTable CompanyName="minesadorada" FileDescription="Tray app that works with LazAutoUpdate apps" InternalName="lazautoupdater" LegalCopyright="LGPLv2" LegalTrademarks="(c)2014 Gordon Bamber" OriginalFilename="trayupdater" ProductName="Lazarus 1.x FPC 2.6.x" ProductVersion="0.1.11.2"/> <StringTable CompanyName="minesadorada" FileDescription="Tray app that works with LazAutoUpdate apps" InternalName="lazautoupdater" LegalCopyright="LGPLv2" LegalTrademarks="(c)2014 Gordon Bamber" OriginalFilename="trayupdater" ProductName="Lazarus 1.x FPC 2.6.x" ProductVersion="0.1.11.2"/>
</VersionInfo> </VersionInfo>
<BuildModes Count="4"> <BuildModes Count="5">
<Item1 Name="Win32 Release" Default="True"/> <Item1 Name="Win32 Release" Default="True"/>
<Item2 Name="Win64 Release"> <Item2 Name="Win64 Release">
<CompilerOptions> <CompilerOptions>
@ -101,6 +101,9 @@
</Linking> </Linking>
<Other> <Other>
<CustomOptions Value="-FcUTF8"/> <CustomOptions Value="-FcUTF8"/>
<OtherDefines Count="1">
<Define0 Value="DEBUGMODE"/>
</OtherDefines>
</Other> </Other>
</CompilerOptions> </CompilerOptions>
</Item3> </Item3>
@ -143,6 +146,58 @@
</Other> </Other>
</CompilerOptions> </CompilerOptions>
</Item4> </Item4>
<Item5 Name="Win64 Debug">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="compiled\win64debug\lautraynotifywin64"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\packagesource"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<IncludeAssertionCode Value="True"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
<VerifyObjMethodCallValidity Value="True"/>
<TargetCPU Value="x86_64"/>
<TargetOS Value="win64"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking>
<Debugging>
<UseHeaptrc Value="True"/>
</Debugging>
<LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
<Other>
<CustomOptions Value="-FcUTF8
-dDEBUGMODE"/>
<OtherDefines Count="1">
<Define0 Value="DEBUGMODE"/>
</OtherDefines>
</Other>
</CompilerOptions>
</Item5>
</BuildModes> </BuildModes>
<PublishOptions> <PublishOptions>
<Version Value="2"/> <Version Value="2"/>

View File

@ -3,16 +3,17 @@
<ProjectSession> <ProjectSession>
<PathDelim Value="\"/> <PathDelim Value="\"/>
<Version Value="10"/> <Version Value="10"/>
<BuildModes Active="Win64 Release"/> <BuildModes Active="Win64 Debug"/>
<Units Count="30"> <Units Count="30">
<Unit0> <Unit0>
<Filename Value="trayupdater.lpr"/> <Filename Value="trayupdater.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="2"/> <EditorIndex Value="2"/>
<WindowIndex Value="1"/> <WindowIndex Value="1"/>
<TopLine Value="21"/> <TopLine Value="3"/>
<CursorPos X="58" Y="41"/> <CursorPos X="19" Y="10"/>
<UsageCount Value="181"/> <UsageCount Value="182"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit0> </Unit0>
<Unit1> <Unit1>
@ -21,14 +22,18 @@
<ComponentName Value="mainform"/> <ComponentName Value="mainform"/>
<HasResources Value="True"/> <HasResources Value="True"/>
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<IsVisibleTab Value="True"/>
<WindowIndex Value="1"/> <WindowIndex Value="1"/>
<TopLine Value="540"/> <CursorPos Y="23"/>
<CursorPos X="50" Y="552"/> <ExtraEditorCount Value="1"/>
<ExtraEditor1>
<IsVisibleTab Value="True"/>
<TopLine Value="92"/>
<CursorPos X="52" Y="119"/>
</ExtraEditor1>
<ComponentState Value="1"/> <ComponentState Value="1"/>
<UsageCount Value="181"/> <UsageCount Value="182"/>
<Bookmarks Count="1"> <Bookmarks Count="1">
<Item0 X="3" Y="480" ID="2"/> <Item0 X="3" Y="481" ID="2"/>
</Bookmarks> </Bookmarks>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
@ -41,9 +46,8 @@
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
<EditorIndex Value="3"/> <EditorIndex Value="3"/>
<WindowIndex Value="1"/> <WindowIndex Value="1"/>
<TopLine Value="150"/> <CursorPos X="2" Y="22"/>
<CursorPos X="37" Y="224"/> <UsageCount Value="178"/>
<UsageCount Value="177"/>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
</Unit2> </Unit2>
@ -251,126 +255,129 @@
<OtherDefines Count="1"> <OtherDefines Count="1">
<Define0 Value="DEBUGMODE"/> <Define0 Value="DEBUGMODE"/>
</OtherDefines> </OtherDefines>
<General>
<ActiveWindowIndexAtStart Value="1"/>
</General>
<JumpHistory Count="30" HistoryIndex="29"> <JumpHistory Count="30" HistoryIndex="29">
<Position1> <Position1>
<Filename Value="trayupdater.lpr"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="63" TopLine="14"/> <Caret Column="17"/>
</Position1> </Position1>
<Position2> <Position2>
<Filename Value="trayupdater.lpr"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="57" Column="30" TopLine="19"/> <Caret Line="852" Column="20" TopLine="814"/>
</Position2> </Position2>
<Position3> <Position3>
<Filename Value="umainform.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="593" Column="31" TopLine="587"/> <Caret Line="932" Column="16" TopLine="894"/>
</Position3> </Position3>
<Position4> <Position4>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1482" Column="40" TopLine="1460"/> <Caret Line="1120" Column="18" TopLine="1083"/>
</Position4> </Position4>
<Position5> <Position5>
<Filename Value="umainform.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="137" TopLine="109"/> <Caret Line="1327" Column="18" TopLine="1290"/>
</Position5> </Position5>
<Position6> <Position6>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="2296" Column="87" TopLine="2285"/> <Caret Line="1460" Column="16" TopLine="1422"/>
</Position6> </Position6>
<Position7> <Position7>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Column="17"/> <Caret Line="1528" Column="16" TopLine="1490"/>
</Position7> </Position7>
<Position8> <Position8>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="852" Column="20" TopLine="814"/> <Caret Line="1572" Column="20" TopLine="1535"/>
</Position8> </Position8>
<Position9> <Position9>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="932" Column="16" TopLine="894"/> <Caret Line="1611" Column="20" TopLine="1573"/>
</Position9> </Position9>
<Position10> <Position10>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1120" Column="18" TopLine="1083"/> <Caret Line="1696" Column="16" TopLine="1659"/>
</Position10> </Position10>
<Position11> <Position11>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1327" Column="18" TopLine="1290"/> <Caret Line="1729" Column="20" TopLine="1692"/>
</Position11> </Position11>
<Position12> <Position12>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1460" Column="16" TopLine="1422"/> <Caret Line="1820" Column="22" TopLine="1783"/>
</Position12> </Position12>
<Position13> <Position13>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1528" Column="16" TopLine="1490"/> <Caret Line="1857" Column="25" TopLine="1820"/>
</Position13> </Position13>
<Position14> <Position14>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1572" Column="20" TopLine="1535"/> <Caret Line="1892" Column="27" TopLine="1855"/>
</Position14> </Position14>
<Position15> <Position15>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1611" Column="20" TopLine="1573"/> <Caret Line="1976" Column="22" TopLine="1939"/>
</Position15> </Position15>
<Position16> <Position16>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1696" Column="16" TopLine="1659"/> <Caret Line="2030" Column="25" TopLine="1993"/>
</Position16> </Position16>
<Position17> <Position17>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="..\ulazautoupdate.pas"/>
<Caret Line="1729" Column="20" TopLine="1692"/> <Caret Line="2071" Column="27" TopLine="2034"/>
</Position17> </Position17>
<Position18> <Position18>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="1820" Column="22" TopLine="1783"/> <Caret Line="407" Column="36" TopLine="386"/>
</Position18> </Position18>
<Position19> <Position19>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="1857" Column="25" TopLine="1820"/> <Caret Line="496" Column="46" TopLine="468"/>
</Position19> </Position19>
<Position20> <Position20>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="1892" Column="27" TopLine="1855"/> <Caret Line="497" Column="37" TopLine="468"/>
</Position20> </Position20>
<Position21> <Position21>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="1976" Column="22" TopLine="1939"/> <Caret Line="502" Column="46" TopLine="468"/>
</Position21> </Position21>
<Position22> <Position22>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="2030" Column="25" TopLine="1993"/> <Caret Line="73" Column="12" TopLine="50"/>
</Position22> </Position22>
<Position23> <Position23>
<Filename Value="..\ulazautoupdate.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="2071" Column="27" TopLine="2034"/> <Caret Line="563" Column="9" TopLine="540"/>
</Position23> </Position23>
<Position24> <Position24>
<Filename Value="umainform.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="407" Column="36" TopLine="386"/> <Caret Line="572" Column="15" TopLine="540"/>
</Position24> </Position24>
<Position25> <Position25>
<Filename Value="umainform.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="496" Column="46" TopLine="468"/> <Caret Line="735" Column="27" TopLine="715"/>
</Position25> </Position25>
<Position26> <Position26>
<Filename Value="umainform.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="497" Column="37" TopLine="468"/> <Caret Line="77" Column="73" TopLine="50"/>
</Position26> </Position26>
<Position27> <Position27>
<Filename Value="umainform.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="502" Column="46" TopLine="468"/> <Caret Line="664" Column="3" TopLine="677"/>
</Position27> </Position27>
<Position28> <Position28>
<Filename Value="umainform.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="73" Column="12" TopLine="50"/> <Caret Line="746" Column="26" TopLine="715"/>
</Position28> </Position28>
<Position29> <Position29>
<Filename Value="umainform.pas"/> <Filename Value="trayupdater.lpr"/>
<Caret Line="563" Column="9" TopLine="540"/> <Caret Line="36" Column="30" TopLine="21"/>
</Position29> </Position29>
<Position30> <Position30>
<Filename Value="umainform.pas"/> <Filename Value="umainform.pas"/>
<Caret Line="572" Column="15" TopLine="540"/> <Caret Line="743" Column="48" TopLine="719"/>
</Position30> </Position30>
</JumpHistory> </JumpHistory>
</ProjectSession> </ProjectSession>

View File

@ -172,7 +172,6 @@ object configform: Tconfigform
ClientHeight = 223 ClientHeight = 223
ClientWidth = 600 ClientWidth = 600
TabOrder = 1 TabOrder = 1
OnClick = grp_updateintervalClick
object cmd_Close: TBitBtn object cmd_Close: TBitBtn
Left = 228 Left = 228
Height = 30 Height = 30

View File

@ -1,77 +1,96 @@
unit uconfigform; unit uconfigform;
{ LazAutoUpdater Tray Updater
Copyright (C)2014 Gordon Bamber minesadorada@charcodelvalle.com
An example of using LazAutoUpdate as a silent updater
This source is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This code is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
A copy of the GNU General Public License is available on the World Wide Web
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
}
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
interface interface
uses uses
Classes, SysUtils, FileUtil, Forms, Controls, Dialogs, Buttons, SysUtils, Forms, Controls, Dialogs, Buttons,
StdCtrls, EditBtn; StdCtrls, EditBtn;
type type
{ Tconfigform } { Tconfigform }
Tconfigform = class(TForm) Tconfigform = class(TForm)
cmd_DeleteAppProfile: TButton; cmd_DeleteAppProfile: TButton;
cmd_SaveChanges: TBitBtn; cmd_SaveChanges: TBitBtn;
chk_Update: TCheckBox; chk_Update: TCheckBox;
cmb_IntervalDate: TComboBox; cmb_IntervalDate: TComboBox;
cmb_IntervalHour: TComboBox; cmb_IntervalHour: TComboBox;
cmb_IntervalDay: TComboBox; cmb_IntervalDay: TComboBox;
cmd_Close: TBitBtn; cmd_Close: TBitBtn;
cmd_NewAppProfile: TButton; cmd_NewAppProfile: TButton;
cmb_AppProfile: TComboBox; cmb_AppProfile: TComboBox;
cmb_IntervalType: TComboBox; cmb_IntervalType: TComboBox;
edt_INIPath: TEdit; edt_INIPath: TEdit;
edt_AppPath: TFileNameEdit; edt_AppPath: TFileNameEdit;
edt_AppVersion: TEdit; edt_AppVersion: TEdit;
edt_SFUpdatesDirectory: TEdit; edt_SFUpdatesDirectory: TEdit;
edt_ZipPath: TEdit; edt_ZipPath: TEdit;
edt_SFProjectName: TEdit; edt_SFProjectName: TEdit;
grp_updateinterval: TGroupBox; grp_updateinterval: TGroupBox;
grp_configapp: TGroupBox; grp_configapp: TGroupBox;
lbl_LastUpdated: TLabel; lbl_LastUpdated: TLabel;
lbl_AppVersion: TLabel; lbl_AppVersion: TLabel;
lbl_AppProfile: TLabel; lbl_AppProfile: TLabel;
lbl_AppPath: TLabel; lbl_AppPath: TLabel;
lbl_INIPath: TLabel; lbl_INIPath: TLabel;
lbl_IntervalDate: TLabel; lbl_IntervalDate: TLabel;
lbl_SFUpdatesDirectory: TLabel; lbl_SFUpdatesDirectory: TLabel;
lbl_IntervalType: TLabel; lbl_IntervalType: TLabel;
lbl_SFUpdatesDirectory2: TLabel; lbl_SFUpdatesDirectory2: TLabel;
lbl_IntervalDay: TLabel; lbl_IntervalDay: TLabel;
lbl_ZipPath: TLabel; lbl_ZipPath: TLabel;
lbl_SFProjectName: TLabel; lbl_SFProjectName: TLabel;
procedure chk_UpdateClick(Sender: TObject); procedure chk_UpdateClick(Sender: TObject);
procedure cmb_AppProfileClick(Sender: TObject); procedure cmb_AppProfileClick(Sender: TObject);
procedure cmb_AppProfileCloseUp(Sender: TObject); procedure cmb_AppProfileCloseUp(Sender: TObject);
procedure cmd_CloseClick(Sender: TObject); procedure cmd_CloseClick(Sender: TObject);
procedure cmd_DeleteAppProfileClick(Sender: TObject); procedure cmd_DeleteAppProfileClick(Sender: TObject);
procedure cmd_NewAppProfileClick(Sender: TObject); procedure cmd_NewAppProfileClick(Sender: TObject);
procedure cmd_SaveChangesClick(Sender: TObject); procedure cmd_SaveChangesClick(Sender: TObject);
procedure cmb_IntervalTypeChange(Sender: TObject); procedure cmb_IntervalTypeChange(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure grp_updateintervalClick(Sender: TObject); private
private { private declarations }
{ private declarations } procedure DoInitialiseCombobox;
procedure DoInitialiseCombobox; procedure DoDisplayProfile(AIndex: integer);
procedure DoDisplayProfile(AIndex: integer); procedure DoSaveAllChanges;
procedure DoSaveAllChanges; procedure DoEnableDisableIntervalCombos;
procedure DoEnableDisableIntervalCombos; public
public { public declarations }
{ public declarations } bDetailsChanged: boolean;
bDetailsChanged: boolean; end;
end;
var var
configform : Tconfigform; configform: Tconfigform;
implementation implementation
uses uses
umainform; umainform;
{$R *.lfm} {$R *.lfm}
@ -79,14 +98,14 @@ umainform;
procedure Tconfigform.FormCreate(Sender: TObject); procedure Tconfigform.FormCreate(Sender: TObject);
begin begin
Icon := Application.Icon; Icon := Application.Icon;
Caption := 'Configure ' + Application.Title; Caption := 'Configure ' + Application.Title;
end; end;
procedure Tconfigform.DoSaveAllChanges; procedure Tconfigform.DoSaveAllChanges;
begin begin
with mainform.AppRecArray[cmb_AppProfile.ItemIndex] do with mainform.AppRecArray[cmb_AppProfile.ItemIndex] do
begin begin
AppPath := edt_AppPath.Text; AppPath := edt_AppPath.Text;
AppVersion := edt_AppVersion.Text; AppVersion := edt_AppVersion.Text;
INIPath := edt_INIPath.Text; INIPath := edt_INIPath.Text;
@ -99,50 +118,50 @@ begin
IntervalHour := cmb_IntervalHour.ItemIndex; IntervalHour := cmb_IntervalHour.ItemIndex;
Update := chk_Update.Checked; Update := chk_Update.Checked;
bDetailsChanged := True; bDetailsChanged := True;
end; end;
end; end;
procedure Tconfigform.DoDisplayProfile(AIndex: integer); procedure Tconfigform.DoDisplayProfile(AIndex: integer);
begin begin
with mainform.AppRecArray[AIndex] do with mainform.AppRecArray[AIndex] do
begin begin
edt_AppPath.Text := AppPath; edt_AppPath.Text := AppPath;
edt_AppVersion.Text := AppVersion; edt_AppVersion.Text := AppVersion;
edt_INIPath.Text := INIPath; edt_INIPath.Text := INIPath;
edt_ZipPath.Text := ZipPath; edt_ZipPath.Text := ZipPath;
edt_SFProjectName.Text := SFProjectName; edt_SFProjectName.Text := SFProjectName;
edt_SFUpdatesDirectory.Text := SFUpdatesDirectory; edt_SFUpdatesDirectory.Text := SFUpdatesDirectory;
cmb_IntervalType.ItemIndex := IntervalType; cmb_IntervalType.ItemIndex := IntervalType;
cmb_IntervalDay.ItemIndex := IntervalDay; cmb_IntervalDay.ItemIndex := IntervalDay;
cmb_IntervalDate.ItemIndex := IntervalDate; cmb_IntervalDate.ItemIndex := IntervalDate;
cmb_IntervalHour.ItemIndex := IntervalHour; cmb_IntervalHour.ItemIndex := IntervalHour;
chk_Update.Checked := Update; chk_Update.Checked := Update;
lbl_LastUpdated.Caption := lbl_LastUpdated.Caption :=
Format('Last successful update was %s', Format('Last successful update was %s',
[FormatDateTime('c', LastCheckDateTime)]); [FormatDateTime('c', LastCheckDateTime)]);
DoEnableDisableIntervalCombos; DoEnableDisableIntervalCombos;
end; end;
end; end;
procedure Tconfigform.DoEnableDisableIntervalCombos; procedure Tconfigform.DoEnableDisableIntervalCombos;
begin begin
case cmb_IntervalType.ItemIndex of case cmb_IntervalType.ItemIndex of
0: 0:
begin begin
cmb_IntervalDay.Enabled := False; cmb_IntervalDay.Enabled := False;
cmb_IntervalDate.Enabled := False; cmb_IntervalDate.Enabled := False;
end; end;
1: 1:
begin begin
cmb_IntervalDay.Enabled := True; cmb_IntervalDay.Enabled := True;
cmb_IntervalDate.Enabled := False; cmb_IntervalDate.Enabled := False;
end; end;
2: 2:
begin begin
cmb_IntervalDay.Enabled := False; cmb_IntervalDay.Enabled := False;
cmb_IntervalDate.Enabled := True; cmb_IntervalDate.Enabled := True;
end; end;
end; end;
end; end;
procedure Tconfigform.cmd_SaveChangesClick(Sender: TObject); procedure Tconfigform.cmd_SaveChangesClick(Sender: TObject);
@ -164,7 +183,7 @@ end;
procedure Tconfigform.chk_UpdateClick(Sender: TObject); procedure Tconfigform.chk_UpdateClick(Sender: TObject);
begin begin
mainform.AppRecArray[cmb_AppProfile.ItemIndex].Update := chk_Update.Checked; mainform.AppRecArray[cmb_AppProfile.ItemIndex].Update := chk_Update.Checked;
// mainform.LongTimerArray[cmb_AppProfile.ItemIndex].Enabled := chk_Update.Checked; // mainform.LongTimerArray[cmb_AppProfile.ItemIndex].Enabled := chk_Update.Checked;
end; end;
procedure Tconfigform.cmb_AppProfileClick(Sender: TObject); procedure Tconfigform.cmb_AppProfileClick(Sender: TObject);
@ -187,16 +206,16 @@ procedure Tconfigform.cmd_DeleteAppProfileClick(Sender: TObject);
// Copy the temp copy back to AppRecArray // Copy the temp copy back to AppRecArray
// Delete the INIFile section // Delete the INIFile section
var var
TempAppRecArray : array of TAppRec; TempAppRecArray: array of TAppRec;
i, iLastIndex : integer; i, iLastIndex: integer;
begin begin
if High(mainform.AppRecArray) = 0 then if High(mainform.AppRecArray) = 0 then
begin begin
MessageDlg(Application.Title, MessageDlg(Application.Title,
'You cannot delete the only profile left', 'You cannot delete the only profile left',
mtError, [mbOK], 0); mtError, [mbOK], 0);
exit; exit;
end; end;
// Delete INI section // Delete INI section
mainform.INI.EraseSection( mainform.INI.EraseSection(
@ -206,15 +225,15 @@ begin
iLastIndex := -1; iLastIndex := -1;
for i := Low(mainform.AppRecArray) to High(mainform.AppRecArray) do for i := Low(mainform.AppRecArray) to High(mainform.AppRecArray) do
if (i <> cmb_AppProfile.ItemIndex) then if (i <> cmb_AppProfile.ItemIndex) then
begin begin
Inc(iLastIndex); Inc(iLastIndex);
TempAppRecArray[iLastIndex] := mainform.AppRecArray[i]; TempAppRecArray[iLastIndex] := mainform.AppRecArray[i];
end; end;
SetLength(mainform.AppRecArray, High(TempAppRecArray) + 1); SetLength(mainform.AppRecArray, High(TempAppRecArray) + 1);
mainform.AppRecArray := TempAppRecArray; mainform.AppRecArray := TempAppRecArray;
DoInitialiseCombobox; DoInitialiseCombobox;
cmb_AppProfile.ItemIndex := 0; cmb_AppProfile.ItemIndex := 0;
mainform.iCurrentRecIndex := 0; mainform.iCurrentRecIndex := 0;
mainform.INI.WriteInteger('ProgramInfo', 'CurrentProfileIndex', mainform.INI.WriteInteger('ProgramInfo', 'CurrentProfileIndex',
mainform.iCurrentRecIndex); mainform.iCurrentRecIndex);
@ -225,25 +244,25 @@ end;
procedure Tconfigform.cmd_NewAppProfileClick(Sender: TObject); procedure Tconfigform.cmd_NewAppProfileClick(Sender: TObject);
var var
szProfileName : string; szProfileName: string;
iLastIndex : integer; iLastIndex: integer;
begin begin
if InputQuery('New Profile', 'New Profile', False, szProfileName) then if InputQuery('New Profile', 'New Profile', False, szProfileName) then
begin begin
iLastIndex := High(mainform.AppRecArray); iLastIndex := High(mainform.AppRecArray);
SetLength(mainform.AppRecArray, iLastIndex + 2); SetLength(mainform.AppRecArray, iLastIndex + 2);
iLastIndex := High(mainform.AppRecArray); iLastIndex := High(mainform.AppRecArray);
mainform.AppRecArray[iLastIndex] := mainform.AppRecArray[iLastIndex - 1]; mainform.AppRecArray[iLastIndex] := mainform.AppRecArray[iLastIndex - 1];
mainform.AppRecArray[iLastIndex].AppPrettyName := szProfileName; mainform.AppRecArray[iLastIndex].AppPrettyName := szProfileName;
DoInitialiseCombobox; DoInitialiseCombobox;
cmb_AppProfile.ItemIndex := iLastIndex; cmb_AppProfile.ItemIndex := iLastIndex;
mainform.iCurrentRecIndex := iLastIndex; mainform.iCurrentRecIndex := iLastIndex;
mainform.INI.WriteInteger('ProgramInfo', 'CurrentProfileIndex', mainform.INI.WriteInteger('ProgramInfo', 'CurrentProfileIndex',
mainform.iCurrentRecIndex); mainform.iCurrentRecIndex);
mainform.INI.UpdateFile; mainform.INI.UpdateFile;
bDetailsChanged := True; bDetailsChanged := True;
mainform.DoWriteAppRecArrayIntoINI; mainform.DoWriteAppRecArrayIntoINI;
end; end;
end; end;
procedure Tconfigform.cmb_IntervalTypeChange(Sender: TObject); procedure Tconfigform.cmb_IntervalTypeChange(Sender: TObject);
@ -253,24 +272,24 @@ end;
procedure Tconfigform.DoInitialiseCombobox; procedure Tconfigform.DoInitialiseCombobox;
var var
i : integer; i: integer;
begin begin
if (Length(mainform.AppRecArray) = 0) then if (Length(mainform.AppRecArray) = 0) then
begin begin
ShowMessage('There are no profiles to configure!'); ShowMessage('There are no profiles to configure!');
ModalResult := mrOk; ModalResult := mrOk;
end; end;
cmb_AppProfile.Clear; cmb_AppProfile.Clear;
with mainform do with mainform do
begin begin
for i := Low(AppRecArray) to High(AppRecArray) do for i := Low(AppRecArray) to High(AppRecArray) do
begin begin
cmb_AppProfile.Items.Add(AppRecArray[i].AppPrettyName); cmb_AppProfile.Items.Add(AppRecArray[i].AppPrettyName);
end; end;
end; end;
mainform.iCurrentRecIndex := mainform.iCurrentRecIndex :=
mainform.INI.ReadInteger('ProgramInfo', 'CurrentProfileIndex', 0); mainform.INI.ReadInteger('ProgramInfo', 'CurrentProfileIndex', 0);
cmb_AppProfile.ItemIndex := mainform.iCurrentRecIndex; cmb_AppProfile.ItemIndex := mainform.iCurrentRecIndex;
DoDisplayProfile(mainform.iCurrentRecIndex); DoDisplayProfile(mainform.iCurrentRecIndex);
end; end;
@ -280,9 +299,4 @@ begin
bDetailsChanged := False; bDetailsChanged := False;
end; end;
procedure Tconfigform.grp_updateintervalClick(Sender: TObject);
begin
end;
end. end.

View File

@ -7,7 +7,6 @@ object mainform: Tmainform
Caption = 'mainform' Caption = 'mainform'
OnCloseQuery = FormCloseQuery OnCloseQuery = FormCloseQuery
OnCreate = FormCreate OnCreate = FormCreate
OnShow = FormShow
OnWindowStateChange = FormWindowStateChange OnWindowStateChange = FormWindowStateChange
Position = poScreenCenter Position = poScreenCenter
ShowInTaskBar = stNever ShowInTaskBar = stNever
@ -80,7 +79,7 @@ object mainform: Tmainform
Left = 128 Left = 128
Top = 16 Top = 16
end end
object EventLog1: TEventLog object Logger: TEventLog
AppendContent = False AppendContent = False
LogType = ltFile LogType = ltFile
Active = False Active = False

View File

@ -39,93 +39,94 @@ VERSION HISTORY
0.1.12: Commit to svn 0.1.12: Commit to svn
0.1.13: Updated January 2017 0.1.13: Updated January 2017
Ini filename uses C_PFX Ini filename uses C_PFX
0.1.14: Memory leaks fixed
0.1.15: ??
} }
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
interface interface
uses uses
Classes, SysUtils, FileUtil, LazFileUtils,Forms, Controls, Graphics, Dialogs, ExtCtrls, Classes, SysUtils, FileUtil, LazFileUtils, Forms, Dialogs, ExtCtrls,
Menus, uLongTimer, ulazautoupdate, inifiles, eventlog, strUtils, uconfigform Menus, uLongTimer, ulazautoupdate, inifiles, eventlog, strUtils, uconfigform
{$IFDEF WINDOWS}, registry{$ENDIF}; {$IFDEF WINDOWS}, registry{$ENDIF};
type type
{ TAppRec - in-memory storage for all settings } { TAppRec - in-memory storage for all settings }
TAppRec = record TAppRec = record
AppPrettyName: string; AppPrettyName: string;
AppPath: string; AppPath: string;
INIPath: string; INIPath: string;
ZipPath: string; ZipPath: string;
AppVersion: string; AppVersion: string;
SFProjectName: string; SFProjectName: string;
SFUpdatesDirectory: string; SFUpdatesDirectory: string;
Location: string; Location: string;
IntervalType: word; IntervalType: word;
IntervalDay: word; IntervalDay: word;
IntervalDate: word; IntervalDate: word;
IntervalHour: word; IntervalHour: word;
Update: boolean; Update: boolean;
LastCheckDateTime: TDateTime; LastCheckDateTime: TDateTime;
end; end;
{ Tmainform } { Tmainform }
Tmainform = class(TForm) Tmainform = class(TForm)
Logger: TEventLog; Logger: TEventLog;
idleReminder: TIdleTimer; idleReminder: TIdleTimer;
LazAutoUpdate1: TLazAutoUpdate; LazAutoUpdate1: TLazAutoUpdate;
mnu_About: TMenuItem; mnu_About: TMenuItem;
mnu_SelfCheck: TMenuItem; mnu_SelfCheck: TMenuItem;
mnu_startAtOSStartUp: TMenuItem; mnu_startAtOSStartUp: TMenuItem;
mnu_configure: TMenuItem; mnu_configure: TMenuItem;
mnu_fileExit: TMenuItem; mnu_fileExit: TMenuItem;
PopupMenu1: TPopupMenu; PopupMenu1: TPopupMenu;
TrayIcon1: TTrayIcon; TrayIcon1: TTrayIcon;
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormWindowStateChange(Sender: TObject);
procedure FormWindowStateChange(Sender: TObject); procedure idleReminderTimer(Sender: TObject);
procedure idleReminderTimer(Sender: TObject); procedure LazAutoUpdate1DebugEvent(Sender: TObject; WhereAt, Message: string);
procedure LazAutoUpdate1DebugEvent(Sender: TObject; WhereAt, Message: string); procedure mnu_AboutClick(Sender: TObject);
procedure mnu_AboutClick(Sender: TObject); procedure mnu_configureClick(Sender: TObject);
procedure mnu_configureClick(Sender: TObject); procedure mnu_fileExitClick(Sender: TObject);
procedure mnu_fileExitClick(Sender: TObject); procedure mnu_startAtOSStartUpClick(Sender: TObject);
procedure mnu_startAtOSStartUpClick(Sender: TObject); procedure mnu_SelfCheckClick(Sender: TObject);
procedure mnu_SelfCheckClick(Sender: TObject); procedure TrayIcon1Click(Sender: TObject);
procedure TrayIcon1Click(Sender: TObject); function UT_DateTimeToStr(TheDate: TDateTime): string;
function UT_DateTimeToStr(TheDate: TDateTime): string; function UT_StrToDate(str: string): TDateTime;
function UT_StrToDate(str: string): TDateTime;
private private
{ private declarations } { private declarations }
szImportINIPath: string; szImportINIPath: string;
DebugMode: boolean; DebugMode: boolean;
procedure DoAlert(aAppname, aVersion: string); procedure DoAlert(aAppname, aVersion: string);
// Transfers info from lauimport.ini to local ini // Transfers info from lauimport.ini to local ini
function ImportINIFile: boolean; function ImportINIFile: boolean;
// When first run, Populates INI and AppRecArray with default entry // When first run, Populates INI and AppRecArray with default entry
procedure PopulateOwnProfile; procedure PopulateOwnProfile;
// Transfers info from local INI to AppRecArray // Transfers info from local INI to AppRecArray
procedure DoReadINIIntoAppRecArray; procedure DoReadINIIntoAppRecArray;
// Re-initialises a LongTimer array from AppRecArray info // Re-initialises a LongTimer array from AppRecArray info
procedure DoSetupLongTimerArray; procedure DoSetupLongTimerArray;
// All LongTimers use this for their OnTimer event // All LongTimers use this for their OnTimer event
procedure DoLongTimerEvent(Sender: TObject); procedure DoLongTimerEvent(Sender: TObject);
// Do a silent check/install for this AppRecArray member // Do a silent check/install for this AppRecArray member
procedure CheckAndUpdate(ARecIndex: integer); procedure CheckAndUpdate(ARecIndex: integer);
public public
{ public declarations } { public declarations }
INI: TIniFile; INI: TIniFile;
AppRecArray: array of TAppRec; // Dynamic array AppRecArray: array of TAppRec; // Dynamic array
LongTimerArray: array of TLongTimer; // Dynamic array LongTimerArray: array of TLongTimer; // Dynamic array
iCurrentRecIndex: integer; iCurrentRecIndex: integer;
// Transfers info from AppRecArray to local INI // Transfers info from AppRecArray to local INI
procedure DoWriteAppRecArrayIntoINI; procedure DoWriteAppRecArrayIntoINI;
end; end;
var var
mainform : Tmainform; mainform: Tmainform;
Const const
{$IFDEF WINDOWS} {$IFDEF WINDOWS}
C_OS = 'win'; C_OS = 'win';
{$ELSE} {$ELSE}
@ -137,16 +138,16 @@ Const
C_BITNESS = '64'; C_BITNESS = '64';
{$ENDIF} {$ENDIF}
C_PFX = C_OS + C_BITNESS; C_PFX = C_OS + C_BITNESS;
C_LAUTRayINI = 'lauimport.ini'; C_LAUTRayINI = 'lauimport.ini';
C_INIFilename = 'trayupdater' + C_PFX + '.ini'; C_INIFilename = 'trayupdater' + C_PFX + '.ini';
implementation implementation
resourcestring resourcestring
rs_balloontitle = '%s service'; rs_balloontitle = '%s service';
rs_trayloaded = '%s Loaded'; rs_trayloaded = '%s Loaded';
rs_newversionavailable = 'A new version of %s (v%s) is available'; rs_newversionavailable = 'A new version of %s (v%s) is available';
// TODO: Put all the other strings here // TODO: Put all the other strings here
{$R *.lfm} {$R *.lfm}
@ -154,15 +155,15 @@ rs_newversionavailable = 'A new version of %s (v%s) is available';
procedure Tmainform.DoWriteAppRecArrayIntoINI; procedure Tmainform.DoWriteAppRecArrayIntoINI;
// AppRecArray is an in-memory copy of the INI file // AppRecArray is an in-memory copy of the INI file
var var
i : integer; i: integer;
szSection : string; szSection: string;
begin begin
if High(AppRecArray) = 0 then if High(AppRecArray) = 0 then
Exit; Exit;
for i := Low(AppRecArray) to High(AppRecArray) do for i := Low(AppRecArray) to High(AppRecArray) do
begin begin
szSection := AppRecArray[i].AppPrettyName; szSection := AppRecArray[i].AppPrettyName;
try try
INI.WriteString(szSection, 'AppPrettyName', AppRecArray[i].AppPrettyName); INI.WriteString(szSection, 'AppPrettyName', AppRecArray[i].AppPrettyName);
INI.WriteString(szSection, 'AppPath', AppRecArray[i].AppPath); INI.WriteString(szSection, 'AppPath', AppRecArray[i].AppPath);
INI.WriteString(szSection, 'INIPath', AppRecArray[i].INIPath); INI.WriteString(szSection, 'INIPath', AppRecArray[i].INIPath);
@ -181,25 +182,25 @@ begin
INI.WriteString(szSection, 'LastCheckDateTime', INI.WriteString(szSection, 'LastCheckDateTime',
UT_DateTimeToStr(AppRecArray[i].LastCheckDateTime)); UT_DateTimeToStr(AppRecArray[i].LastCheckDateTime));
INI.UpdateFile; INI.UpdateFile;
except except
if DebugMode then if DebugMode then
Logger.Error('Failed to write AppRecArray to %s', [INI.Filename]) Logger.Error('Failed to write AppRecArray to %s', [INI.Filename])
end; end;
end; end;
end; end;
procedure Tmainform.DoLongTimerEvent(Sender: TObject); procedure Tmainform.DoLongTimerEvent(Sender: TObject);
// All LongTimerArray.OnTimer events go here // All LongTimerArray.OnTimer events go here
// The Tag property is the same as the AppRecArray entry it relates to // The Tag property is the same as the AppRecArray entry it relates to
var var
iTag : integer; iTag: integer;
begin begin
iTag := 0; iTag := 0;
// Assertion check // Assertion check
if Sender is TLongTimer then if Sender is TLongTimer then
begin begin
iTag := TLongTimer(Sender).Tag; iTag := TLongTimer(Sender).Tag;
end; end;
if DebugMode then if DebugMode then
Logger.Log('Timer for %s fired', [AppRecArray[iTag].AppPrettyName]); Logger.Log('Timer for %s fired', [AppRecArray[iTag].AppPrettyName]);
TrayIcon1.BalloonHint := TrayIcon1.BalloonHint :=
@ -217,29 +218,29 @@ procedure Tmainform.DoSetupLongTimerArray;
// 2. Iterate through the AppRecArray, setting up a new LongTimer for each element // 2. Iterate through the AppRecArray, setting up a new LongTimer for each element
// 3. Enable the LongTimers for which AppArray.Update=TRUE // 3. Enable the LongTimers for which AppArray.Update=TRUE
var var
i, iArrayElement : integer; i, iArrayElement: integer;
begin begin
// Start with an empty array // Start with an empty array
for i := Low(LongTimerArray) to High(LongTimerArray) do for i := Low(LongTimerArray) to High(LongTimerArray) do
if LongTimerArray[i] <> nil then if LongTimerArray[i] <> nil then
begin begin
LongTimerArray[i].Enabled := False; LongTimerArray[i].Enabled := False;
FreeAndNil(LongTimerArray[i]); FreeAndNil(LongTimerArray[i]);
end; end;
SetLength(LongTimerArray, 0); // Zeros the array SetLength(LongTimerArray, 0); // Zeros the array
iArrayElement := -1; iArrayElement := -1;
for i := Low(AppRecArray) to High(AppRecArray) do for i := Low(AppRecArray) to High(AppRecArray) do
begin begin
Inc(iArrayElement); // initially to zero Inc(iArrayElement); // initially to zero
SetLength(LongTimerArray, iArrayElement + 1); SetLength(LongTimerArray, iArrayElement + 1);
LongTimerArray[iArrayElement] := TLongTimer.Create(nil); LongTimerArray[iArrayElement] := TLongTimer.Create(nil);
with AppRecArray[i] do with AppRecArray[i] do
begin begin
case IntervalType of case IntervalType of
0: LongTimerArray[iArrayElement].IntervalType := lt1Daily; 0: LongTimerArray[iArrayElement].IntervalType := lt1Daily;
1: LongTimerArray[iArrayElement].IntervalType := lt2Weekly; 1: LongTimerArray[iArrayElement].IntervalType := lt2Weekly;
2: LongTimerArray[iArrayElement].IntervalType := lt3Monthly; 2: LongTimerArray[iArrayElement].IntervalType := lt3Monthly;
end; end;
case IntervalDay of case IntervalDay of
0: LongTimerArray[iArrayElement].WeeklyDay := lt1Monday; 0: LongTimerArray[iArrayElement].WeeklyDay := lt1Monday;
1: LongTimerArray[iArrayElement].WeeklyDay := lt2Tuesday; 1: LongTimerArray[iArrayElement].WeeklyDay := lt2Tuesday;
@ -248,21 +249,21 @@ begin
4: LongTimerArray[iArrayElement].WeeklyDay := lt5Friday; 4: LongTimerArray[iArrayElement].WeeklyDay := lt5Friday;
5: LongTimerArray[iArrayElement].WeeklyDay := lt6Saturday; 5: LongTimerArray[iArrayElement].WeeklyDay := lt6Saturday;
6: LongTimerArray[iArrayElement].WeeklyDay := lt7Sunday; 6: LongTimerArray[iArrayElement].WeeklyDay := lt7Sunday;
end; end;
LongTimerArray[iArrayElement].MonthlyDate := IntervalDate; LongTimerArray[iArrayElement].MonthlyDate := IntervalDate;
LongTimerArray[iArrayElement].Daily24Hour := IntervalHour; LongTimerArray[iArrayElement].Daily24Hour := IntervalHour;
LongTimerArray[iArrayElement].Tag := i; LongTimerArray[iArrayElement].Tag := i;
LongTimerArray[iArrayElement].OnTimer := @DoLongTimerEvent; LongTimerArray[iArrayElement].OnTimer := @DoLongTimerEvent;
// Make sure timer doesn't fire right after a self-update // Make sure timer doesn't fire right after a self-update
LongTimerArray[iArrayElement].SampleInterval := lt5Every45Minutes; LongTimerArray[iArrayElement].SampleInterval := lt5Every45Minutes;
LongTimerArray[iArrayElement].Enabled := Update; LongTimerArray[iArrayElement].Enabled := Update;
end; end;
end; end;
end; end;
function Tmainform.UT_DateTimeToStr(TheDate: TDateTime): string; function Tmainform.UT_DateTimeToStr(TheDate: TDateTime): string;
var var
frmstg : TFormatSettings; frmstg: TFormatSettings;
// Ensures consitent String dates across platforms // Ensures consitent String dates across platforms
begin begin
//GetLocaleFormatSettings(0, frmstg); //GetLocaleFormatSettings(0, frmstg);
@ -275,14 +276,14 @@ end;
function Tmainform.UT_StrToDate(str: string): TDateTime; function Tmainform.UT_StrToDate(str: string): TDateTime;
var var
frmstg : TFormatSettings; frmstg: TFormatSettings;
// Ensures consitent String dates across platforms // Ensures consitent String dates across platforms
begin begin
//GetLocaleFormatSettings(0, frmstg); //GetLocaleFormatSettings(0, frmstg);
frmstg.DateSeparator := '-'; frmstg.DateSeparator := '-';
frmstg.ShortDateFormat := 'yyyy-mm-dd'; frmstg.ShortDateFormat := 'yyyy-mm-dd';
frmstg.TimeSeparator := '-'; frmstg.TimeSeparator := '-';
frmstg.LongTimeFormat := 'hh-nn'; frmstg.LongTimeFormat := 'hh-nn';
if not TryStrToDateTime(str, Result, frmstg) then if not TryStrToDateTime(str, Result, frmstg) then
Result := Now(); Result := Now();
end; end;
@ -290,24 +291,24 @@ end;
procedure Tmainform.DoReadINIIntoAppRecArray; procedure Tmainform.DoReadINIIntoAppRecArray;
// AppRecArray is an in-memory copy of the INI file // AppRecArray is an in-memory copy of the INI file
var var
SectionStringList : TStringList; SectionStringList: TStringList;
szSection : string; szSection: string;
i, iArrayElement : integer; i, iArrayElement: integer;
begin begin
SetLength(AppRecArray, 0); // Zeros the array SetLength(AppRecArray, 0); // Zeros the array
SectionStringList := TStringList.Create; SectionStringList := TStringList.Create;
try try
try try
// Fetch all the section names // Fetch all the section names
INI.ReadSections(SectionStringList); INI.ReadSections(SectionStringList);
iArrayElement := -1; iArrayElement := -1;
if SectionStringList.Count > 0 then if SectionStringList.Count > 0 then
for i := 0 to SectionStringList.Count - 1 do for i := 0 to SectionStringList.Count - 1 do
begin // Loop through all the INI file sections begin // Loop through all the INI file sections
szSection := SectionStringList[i]; szSection := SectionStringList[i];
// Skip over the ProgramInfo section // Skip over the ProgramInfo section
if (szSection <> 'ProgramInfo') then if (szSection <> 'ProgramInfo') then
begin begin
Inc(iArrayElement); // initially to zero Inc(iArrayElement); // initially to zero
SetLength(AppRecArray, iArrayElement + 1); SetLength(AppRecArray, iArrayElement + 1);
AppRecArray[iArrayElement].AppPrettyName := AppRecArray[iArrayElement].AppPrettyName :=
@ -339,30 +340,30 @@ begin
AppRecArray[iArrayElement].LastCheckDateTime := AppRecArray[iArrayElement].LastCheckDateTime :=
UT_StrToDate(INI.ReadString(szSection, 'LastCheckDateTime', UT_StrToDate(INI.ReadString(szSection, 'LastCheckDateTime',
UT_DateTimeToStr(Now))); UT_DateTimeToStr(Now)));
end; end;
end; end;
except except
if DebugMode then if DebugMode then
Logger.Error('Failed to read AppRecArray from %s', [INI.Filename]) Logger.Error('Failed to read AppRecArray from %s', [INI.Filename])
end; end;
finally finally
FreeAndNil(SectionStringList); FreeAndNil(SectionStringList);
end; end;
// Low(AppRecArray) to High(AppRecArray) iterates the whole array // Low(AppRecArray) to High(AppRecArray) iterates the whole array
end; end;
procedure Tmainform.PopulateOwnProfile; procedure Tmainform.PopulateOwnProfile;
// Only called when app is first run // Only called when app is first run
var var
szSection, szOSsuffix : string; szSection, szOSsuffix: string;
begin begin
szSection := Application.Title; szSection := Application.Title;
szOSsuffix := LowerCase( szOSsuffix := LowerCase(
{$I %FPCTARGETOS%} {$I %FPCTARGETOS%}
); );
szSection += szOSsuffix; szSection += szOSsuffix;
with INI do with INI do
begin begin
WriteString(szSection, 'AppPrettyName', szSection); WriteString(szSection, 'AppPrettyName', szSection);
WriteString(szSection, 'AppPath', ParamStr(0)); WriteString(szSection, 'AppPath', ParamStr(0));
WriteString(szSection, 'Location', ProgramDirectory); WriteString(szSection, 'Location', ProgramDirectory);
@ -379,14 +380,14 @@ begin
WriteString(szSection, 'LastCheckDateTime', UT_DateTimeToStr(Now)); WriteString(szSection, 'LastCheckDateTime', UT_DateTimeToStr(Now));
WriteBool('ProgramInfo', 'IsVirgin', False); WriteBool('ProgramInfo', 'IsVirgin', False);
UpdateFile; UpdateFile;
end; end;
with LazAutoUpdate1 do with LazAutoUpdate1 do
begin begin
VersionsININame := 'lautraynotify' + szOSsuffix + '.ini'; VersionsININame := 'lautraynotify' + szOSsuffix + '.ini';
ZipFileName := 'lautraynotify' + szOSsuffix + '.zip'; ZipFileName := 'lautraynotify' + szOSsuffix + '.zip';
UpdatesFolder := 'updates'; UpdatesFolder := 'updates';
SFProjectName := 'lazautoupdate'; SFProjectName := 'lazautoupdate';
end; end;
DoReadINIIntoAppRecArray; DoReadINIIntoAppRecArray;
if not FileExistsUTF8(C_LAUTRayINI) then if not FileExistsUTF8(C_LAUTRayINI) then
LazAutoUpdate1.CreateLocalLauImportFile; LazAutoUpdate1.CreateLocalLauImportFile;
@ -399,10 +400,10 @@ function Tmainform.ImportINIFile: boolean;
// Sets Update=TRUE // Sets Update=TRUE
// into C_INIFilename then deletes source ini // into C_INIFilename then deletes source ini
var var
ImportINI : TIniFile; ImportINI: TIniFile;
SectionStringList, SectionContents : TStringList; SectionStringList, SectionContents: TStringList;
i : integer; i: integer;
szSection, szKey, szLocation, szAppPath : string; szSection, szKey, szLocation, szAppPath: string;
begin begin
{TODO: Preserve user Logtimer settings?} {TODO: Preserve user Logtimer settings?}
Result := False; Result := False;
@ -411,14 +412,14 @@ begin
ImportINI := TIniFile.Create(szImportINIPath); ImportINI := TIniFile.Create(szImportINIPath);
SectionStringList := TStringList.Create; SectionStringList := TStringList.Create;
SectionContents := TStringList.Create; SectionContents := TStringList.Create;
try try
ImportINI.ReadSections(SectionStringList); ImportINI.ReadSections(SectionStringList);
if SectionStringList.Count > 0 then if SectionStringList.Count > 0 then
begin begin
szSection := SectionStringList[0]; szSection := SectionStringList[0];
ImportINI.ReadSection(szSection, SectionContents); ImportINI.ReadSection(szSection, SectionContents);
for i := 0 to SectionContents.Count - 1 do for i := 0 to SectionContents.Count - 1 do
begin begin
szKey := SectionContents[i]; szKey := SectionContents[i];
if szKey = 'Location' then if szKey = 'Location' then
szLocation := ImportINI.ReadString(szSection, szKey, ''); szLocation := ImportINI.ReadString(szSection, szKey, '');
@ -426,7 +427,7 @@ begin
szAppPath := ImportINI.ReadString(szSection, szKey, ''); szAppPath := ImportINI.ReadString(szSection, szKey, '');
INI.WriteString(szSection, szKey, ImportINI.ReadString( INI.WriteString(szSection, szKey, ImportINI.ReadString(
szSection, szKey, '')); szSection, szKey, ''));
end; end;
// Append Location to AppPath // Append Location to AppPath
if ((szAppPath <> '') and (szLocation <> '')) then if ((szAppPath <> '') and (szLocation <> '')) then
INI.WriteString(szSection, 'AppPath', AppendPathDelim(szLocation) + INI.WriteString(szSection, 'AppPath', AppendPathDelim(szLocation) +
@ -436,19 +437,19 @@ begin
UT_DateTimeToStr(Now)); UT_DateTimeToStr(Now));
INI.UpdateFile; INI.UpdateFile;
Result := True; Result := True;
end; end;
finally finally
FreeAndNil(SectionContents); FreeAndNil(SectionContents);
FreeAndNil(SectionStringList); FreeAndNil(SectionStringList);
FreeAndNil(ImportINI); FreeAndNil(ImportINI);
end; end;
if (Result = True) then if (Result = True) then
begin begin
if DebugMode then if DebugMode then
Logger.Log('%s: Imported %s into %s', Logger.Log('%s: Imported %s into %s',
[Application.Title, szImportINIPath, INI.Filename]); [Application.Title, szImportINIPath, INI.Filename]);
DoReadINIIntoAppRecArray; DoReadINIIntoAppRecArray;
end; end;
end; end;
procedure Tmainform.DoAlert(aAppname, aVersion: string); procedure Tmainform.DoAlert(aAppname, aVersion: string);
@ -461,7 +462,7 @@ end;
procedure Tmainform.FormWindowStateChange(Sender: TObject); procedure Tmainform.FormWindowStateChange(Sender: TObject);
begin begin
if mainform.WindowState = wsMinimized then if mainform.WindowState = wsMinimized then
begin begin
// 2 lines below are ineffective at hiding the main form // 2 lines below are ineffective at hiding the main form
// Replaced with Application.ShowMainForm := false; in the lpr // Replaced with Application.ShowMainForm := false; in the lpr
// mainform.WindowState := wsNormal; // mainform.WindowState := wsNormal;
@ -473,7 +474,7 @@ begin
if DebugMode then if DebugMode then
Logger.Log('%s version %s started OK', Logger.Log('%s version %s started OK',
[Application.Title, LazAutoUpdate1.AppVersion]); [Application.Title, LazAutoUpdate1.AppVersion]);
end; end;
end; end;
procedure Tmainform.idleReminderTimer(Sender: TObject); procedure Tmainform.idleReminderTimer(Sender: TObject);
@ -481,28 +482,28 @@ procedure Tmainform.idleReminderTimer(Sender: TObject);
// If found, it is imported then deleted. // If found, it is imported then deleted.
begin begin
if LazAutoUpdate1.DownloadInprogress then if LazAutoUpdate1.DownloadInprogress then
begin begin
TrayIcon1.BalloonHint := 'Download in progress'; TrayIcon1.BalloonHint := 'Download in progress';
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
Exit; Exit;
end; end;
if FileExists(szImportINIPath) then if FileExists(szImportINIPath) then
begin begin
if DebugMode then if DebugMode then
Logger.Log('%s: Import file %s discovered', Logger.Log('%s: Import file %s discovered',
[Application.Title, szImportINIPath]); [Application.Title, szImportINIPath]);
if ImportINIFile then if ImportINIFile then
begin begin
if DebugMode then if DebugMode then
Logger.Log('%s: Import file %s successfully imported', Logger.Log('%s: Import file %s successfully imported',
[Application.Title, szImportINIPath]); [Application.Title, szImportINIPath]);
DeleteFileUTF8(szImportINIPath); DeleteFileUTF8(szImportINIPath);
end end
else else
if DebugMode then if DebugMode then
Logger.Error('%s: Failed to import file %s', Logger.Error('%s: Failed to import file %s',
[Application.Title, szImportINIPath]); [Application.Title, szImportINIPath]);
end; end;
end; end;
procedure Tmainform.LazAutoUpdate1DebugEvent(Sender: TObject; WhereAt, Message: string); procedure Tmainform.LazAutoUpdate1DebugEvent(Sender: TObject; WhereAt, Message: string);
@ -513,7 +514,7 @@ end;
procedure Tmainform.mnu_AboutClick(Sender: TObject); procedure Tmainform.mnu_AboutClick(Sender: TObject);
var var
sz : string; sz: string;
begin begin
LazAutoUpdate1.ResetAppVersion; LazAutoUpdate1.ResetAppVersion;
sz := Application.Title + ' system tray application' + LineEnding; sz := Application.Title + ' system tray application' + LineEnding;
@ -547,56 +548,56 @@ end;
procedure Tmainform.mnu_startAtOSStartUpClick(Sender: TObject); procedure Tmainform.mnu_startAtOSStartUpClick(Sender: TObject);
{$IFDEF WINDOWS} {$IFDEF WINDOWS}
var var
Reg : TRegistry; Reg: TRegistry;
{$ENDIF} {$ENDIF}
begin begin
{$IFDEF WINDOWS} {$IFDEF WINDOWS}
Reg := TRegistry.Create(KEY_ALL_ACCESS); Reg := TRegistry.Create(KEY_ALL_ACCESS);
try try
Reg.RootKey := HKEY_CURRENT_USER; Reg.RootKey := HKEY_CURRENT_USER;
Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Run', False); Reg.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Run', False);
if mnu_startAtOSStartUp.Checked then if mnu_startAtOSStartUp.Checked then
begin begin
Reg.WriteString(Application.Title, ParamStr(0)); Reg.WriteString(Application.Title, ParamStr(0));
INI.WriteBool('ProgramInfo', 'RunAtStartUp', True); INI.WriteBool('ProgramInfo', 'RunAtStartUp', True);
if DebugMode then if DebugMode then
Logger.Log('Run at OS startup Activated'); Logger.Log('Run at OS startup Activated');
MessageDlg(Application.Title, MessageDlg(Application.Title,
'Run at OS startup activated OK', mtInformation, [mbOK], 0); 'Run at OS startup activated OK', mtInformation, [mbOK], 0);
end end
else else
begin begin
Reg.DeleteValue(Application.Title); Reg.DeleteValue(Application.Title);
INI.WriteBool('ProgramInfo', 'RunAtStartUp', False); INI.WriteBool('ProgramInfo', 'RunAtStartUp', False);
if DebugMode then if DebugMode then
Logger.Log('Run at OS startup Deactivated'); Logger.Log('Run at OS startup Deactivated');
MessageDlg(Application.Title, MessageDlg(Application.Title,
'Run at OS startup deactivated OK', mtInformation, [mbOK], 0); 'Run at OS startup deactivated OK', mtInformation, [mbOK], 0);
end; end;
Reg.CloseKey; Reg.CloseKey;
finally finally
FreeAndNil(Reg); FreeAndNil(Reg);
end; end;
{$ELSE} {$ELSE}
if mnu_startAtOSStartUp.Checked then if mnu_startAtOSStartUp.Checked then
begin begin
ShowMessage('Sorry - not implemented in Linux in this version'); ShowMessage('Sorry - not implemented in Linux in this version');
mnu_startAtOSStartUp.Checked := False; mnu_startAtOSStartUp.Checked := False;
end; end;
{$ENDIF} {$ENDIF}
end; end;
procedure TmainForm.CheckAndUpdate(ARecIndex: integer); procedure TmainForm.CheckAndUpdate(ARecIndex: integer);
begin begin
if LazAutoUpdate1.DownloadInprogress then if LazAutoUpdate1.DownloadInprogress then
begin begin
if DebugMode then if DebugMode then
Logger.Error( Logger.Error(
'Tried to update whilst download in progress. Exiting CheckAndUpdate routine'); 'Tried to update whilst download in progress. Exiting CheckAndUpdate routine');
Exit; Exit;
end; end;
with AppRecArray[ARecIndex] do with AppRecArray[ARecIndex] do
begin begin
LazAutoUpdate1.AppFileWithPath := AppPath; LazAutoUpdate1.AppFileWithPath := AppPath;
LazAutoUpdate1.AppVersion := AppVersion; LazAutoUpdate1.AppVersion := AppVersion;
LazAutoUpdate1.ZipfileName := ZipPath; LazAutoUpdate1.ZipfileName := ZipPath;
@ -604,36 +605,36 @@ begin
LazAutoUpdate1.UpdatesFolder := SFUpdatesDirectory; LazAutoUpdate1.UpdatesFolder := SFUpdatesDirectory;
LazAutoUpdate1.VersionsININame := INIPath; LazAutoUpdate1.VersionsININame := INIPath;
LazAutoUpdate1.CopyTree := True; LazAutoUpdate1.CopyTree := True;
TrayIcon1.BalloonHint := TrayIcon1.BalloonHint :=
Format('Checking %s for updates', [AppPrettyName]); Format('Checking %s for updates', [AppPrettyName]);
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
// Debugging line // Debugging line
LazAutoUpdate1.DebugMode := True; // Logs everyting LazAutoUpdate1.DebugMode := True; // Logs everyting
if LazAutoUpdate1.NewVersionAvailable then if LazAutoUpdate1.NewVersionAvailable then
begin begin
TrayIcon1.BalloonHint := TrayIcon1.BalloonHint :=
Format('Found newer version %s. Downloading...', Format('Found newer version %s. Downloading...',
[LazAutoUpdate1.GUIOnlineVersion]); [LazAutoUpdate1.GUIOnlineVersion]);
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
if LazAutoUpdate1.DownloadNewVersion then if LazAutoUpdate1.DownloadNewVersion then
if LazAutoUpdate1.SilentUpdate then if LazAutoUpdate1.SilentUpdate then
begin begin
TrayIcon1.BalloonHint := TrayIcon1.BalloonHint :=
Format('Successfully updated %s to version %s', Format('Successfully updated %s to version %s',
[AppPrettyName, LazAutoUpdate1.GUIOnlineVersion]); [AppPrettyName, LazAutoUpdate1.GUIOnlineVersion]);
LastCheckDateTime := Now; LastCheckDateTime := Now;
end end
else else
TrayIcon1.BalloonHint := Format('Failed to update %s', [AppPrettyName]); TrayIcon1.BalloonHint := Format('Failed to update %s', [AppPrettyName]);
end end
else else
begin begin
TrayIcon1.BalloonHint := AppPrettyName + ' is up-to-date'; TrayIcon1.BalloonHint := AppPrettyName + ' is up-to-date';
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
end; end;
LazAutoUpdate1.ResetAppVersion; LazAutoUpdate1.ResetAppVersion;
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
end; end;
end; end;
procedure Tmainform.mnu_SelfCheckClick(Sender: TObject); procedure Tmainform.mnu_SelfCheckClick(Sender: TObject);
@ -653,10 +654,10 @@ end;
procedure Tmainform.TrayIcon1Click(Sender: TObject); procedure Tmainform.TrayIcon1Click(Sender: TObject);
begin begin
if LazAutoUpdate1.DownloadInprogress then if LazAutoUpdate1.DownloadInprogress then
begin begin
TrayIcon1.BalloonHint := 'Currently downloading...'; TrayIcon1.BalloonHint := 'Currently downloading...';
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
end; end;
end; end;
procedure Tmainform.FormCreate(Sender: TObject); procedure Tmainform.FormCreate(Sender: TObject);
@ -665,13 +666,15 @@ begin
DebugMode := True DebugMode := True
else else
DebugMode := False; DebugMode := False;
{$IFDEF DEBUGMODE}DebugMode := True;{$ENDIF} {$IFDEF DEBUGMODE}
DebugMode := True;
{$ENDIF}
// Initialise the App's main INI file // Initialise the App's main INI file
Try try
INI := TIniFile.Create(GetAppConfigDirUTF8(False) + C_INIFilename); INI := TIniFile.Create(GetAppConfigDirUTF8(False) + C_INIFilename);
Except except
sleep(4000); sleep(4000);
If (INI = Nil) then if (INI = nil) then
INI := TIniFile.Create(GetAppConfigDirUTF8(False) + C_INIFilename); INI := TIniFile.Create(GetAppConfigDirUTF8(False) + C_INIFilename);
end; end;
INI.CacheUpdates := False; INI.CacheUpdates := False;
@ -702,10 +705,11 @@ begin
// Logger.Identification := Application.Title; // Logger.Identification := Application.Title;
// Fetch the location of any trayicon INI on the users system // Fetch the location of any trayicon INI on the users system
szImportINIPath := GetAppConfigDirUTF8(False, True); szImportINIPath := GetAppConfigDirUTF8(False, True);
szImportINIPath := AnsiReplaceText(szImportINIPath, Application.Title, 'updatehm' + C_PFX); szImportINIPath := AnsiReplaceText(szImportINIPath, Application.Title,
'updatehm' + C_PFX);
szImportINIPath := AppendPathDelim(szImportINIPath) + C_LAUTRayINI; szImportINIPath := AppendPathDelim(szImportINIPath) + C_LAUTRayINI;
if DebugMode then if DebugMode then
Logger.Debug('szImportINIPath=' + szImportINIPath); Logger.Debug('szImportINIPath=' + szImportINIPath);
// Initialise the AppRecArray // Initialise the AppRecArray
DoReadINIIntoAppRecArray; DoReadINIIntoAppRecArray;
// Use last saved Profile at startup // Use last saved Profile at startup
@ -713,48 +717,50 @@ begin
'CurrentProfileIndex', 0); 'CurrentProfileIndex', 0);
DoSetupLongTimerArray; DoSetupLongTimerArray;
// Sort out the TrayIcon stuff // Sort out the TrayIcon stuff
TrayIcon1.Icon := Application.Icon; TrayIcon1.Icon := Application.Icon;
TrayIcon1.BalloonTitle := Format(rs_balloontitle, [Application.Title]); TrayIcon1.BalloonTitle := Format(rs_balloontitle, [Application.Title]);
TrayIcon1.Hint := Application.Title; TrayIcon1.Hint := Application.Title;
TrayIcon1.ShowIcon := True; TrayIcon1.ShowIcon := True;
TrayIcon1.Show; TrayIcon1.Show;
TrayIcon1.BalloonHint := Format(rs_trayloaded, [Application.Title]); TrayIcon1.BalloonHint := Format(rs_trayloaded, [Application.Title]);
TrayIcon1.ShowBalloonHint; TrayIcon1.ShowBalloonHint;
LazAutoUpdate1.DebugMode := DebugMode; LazAutoUpdate1.DebugMode := DebugMode;
mnu_SelfCheck.Visible := DebugMode; mnu_SelfCheck.Visible := DebugMode;
end;
procedure Tmainform.FormShow(Sender: TObject);
begin
end; end;
procedure Tmainform.FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure Tmainform.FormCloseQuery(Sender: TObject; var CanClose: boolean);
var var
i : integer; i: integer;
begin begin
if LazAutoUpdate1.DownloadInprogress then if LazAutoUpdate1.DownloadInprogress then
begin begin
ShowMessage('Please wait. Update in progress'); ShowMessage('Please wait. Update in progress');
CanClose := False; CanClose := False;
end end
else else
begin // Clean up memory No leaks (V0.1.14)
begin
if DebugMode then if DebugMode then
begin
Logger.Log('User closed application'); Logger.Log('User closed application');
if DebugMode then
Logger.Active := False; Logger.Active := False;
FreeAndNil(Logger);
end;
CanClose := True; CanClose := True;
end; end;
if CanClose then if CanClose then
begin begin
// Clean up any LongTimers // Clean up any LongTimers
for i := Low(LongTimerArray) to High(LongTimerArray) do for i := Low(LongTimerArray) to High(LongTimerArray) do
if LongTimerArray[i] <> nil then if LongTimerArray[i] <> nil then
begin begin
LongTimerArray[i].Enabled := False; LongTimerArray[i].Enabled := False;
FreeAndNil(LongTimerArray[i]); FreeAndNil(LongTimerArray[i]);
end; end;
end; SetLength(AppRecArray, 0);
FreeAndNil(AppRecArray);
FreeAndNil(INI);
end;
end; end;
end. end.