diff --git a/Packages/D7/X2Utils.cfg b/Packages/D7/X2Utils.cfg
index 44403d1..1f303c5 100644
--- a/Packages/D7/X2Utils.cfg
+++ b/Packages/D7/X2Utils.cfg
@@ -31,6 +31,7 @@
-M
-$M16384,1048576
-K$00400000
+-N"..\..\Lib\D7"
-LE"c:\program files\borland\delphi7\Projects\Bpl"
-LN"c:\program files\borland\delphi7\Projects\Bpl"
-w-SYMBOL_PLATFORM
diff --git a/Packages/D7/X2Utils.dof b/Packages/D7/X2Utils.dof
index 9ce9f66..52b0d32 100644
--- a/Packages/D7/X2Utils.dof
+++ b/Packages/D7/X2Utils.dof
@@ -91,7 +91,7 @@ ImageBase=4194304
ExeDescription=X2Utils
[Directories]
OutputDir=
-UnitOutputDir=
+UnitOutputDir=..\..\Lib\D7
PackageDLLOutputDir=
PackageDCPOutputDir=
SearchPath=
@@ -138,7 +138,13 @@ Count=2
Item0=..\..
Item1=F:\Development\VDarts\Packages
[HistoryLists\hlUnitOutputDirectory]
+Count=4
+Item0=..\..\Lib\D7
+Item1=..\..\Dcu
+Item2=..\..\..\Dcu
+Item3=Dcu
+[HistoryLists\hlBPLOutput]
Count=3
-Item0=..\..\Dcu
-Item1=..\..\..\Dcu
-Item2=Dcu
+Item0=..\..\Lib\D7
+Item1=Lib\D7
+Item2=..\Lib\D7
diff --git a/Packages/D7/X2Utils.dpk b/Packages/D7/X2Utils.dpk
index 7e58deb..ddb704a 100644
--- a/Packages/D7/X2Utils.dpk
+++ b/Packages/D7/X2Utils.dpk
@@ -31,7 +31,9 @@ requires
rtl,
vcl,
VirtualTreesD7,
- vclx;
+ vclx,
+ indy,
+ xmlrtl;
contains
X2UtVirtualTree in '..\..\X2UtVirtualTree.pas',
@@ -44,6 +46,7 @@ contains
X2UtMisc in '..\..\X2UtMisc.pas',
X2UtOS in '..\..\X2UtOS.pas',
X2UtSingleInstance in '..\..\X2UtSingleInstance.pas',
- X2UtStrings in '..\..\X2UtStrings.pas';
+ X2UtStrings in '..\..\X2UtStrings.pas',
+ X2UtInetVersion in '..\..\X2UtInetVersion.pas';
end.
diff --git a/X2UtInetVersion.pas b/X2UtInetVersion.pas
new file mode 100644
index 0000000..dae9ff1
--- /dev/null
+++ b/X2UtInetVersion.pas
@@ -0,0 +1,242 @@
+{** Provides internet version checking.
+ *
+ * Queries an URL for XML version information.
+ *
+ *
+ * Last changed: $Date$
+ * Revision: $Rev$
+ * Author: $Author$
+*}
+unit X2UtInetVersion;
+
+interface
+uses
+ Classes,
+
+ IdHTTPHeaderInfo,
+ XMLIntf;
+
+type
+ TX2InetVersionType = (vtUnknown, vtStable, vtBeta, vtReleaseCandidate);
+
+ TX2InetVersionInfo = class(TCollectionItem)
+ private
+ FMajor: Integer;
+ FMinor: Integer;
+ FRelease: Integer;
+ FBuild: Integer;
+ FNewer: Boolean;
+ FVersionType: TX2InetVersionType;
+ FVersionTypeString: String;
+ FWhatsNewTemp: String;
+ protected
+ procedure LoadFromNode(const ANode: IXMLNode);
+ public
+ property VersionType: TX2InetVersionType read FVersionType;
+ property VersionTypeString: String read FVersionTypeString;
+ property Major: Integer read FMajor;
+ property Minor: Integer read FMinor;
+ property Release: Integer read FRelease;
+ property Build: Integer read FBuild;
+ property Newer: Boolean read FNewer;
+ property WhatsNewTemp: String read FWhatsNewTemp;
+ end;
+
+ TX2InetVersions = class(TCollection)
+ private
+ function GetItem(Index: Integer): TX2InetVersionInfo;
+ procedure SetItem(Index: Integer; Value: TX2InetVersionInfo);
+ public
+ constructor Create();
+
+ function Add(): TX2InetVersionInfo;
+
+ property Items[Index: Integer]: TX2InetVersionInfo read GetItem
+ write SetItem; default;
+ end;
+
+ TX2InetVersion = class(TThread)
+ private
+ FAppID: String;
+ FURL: String;
+ FProxyParams: TIdProxyConnectionInfo;
+
+ FApplicationURL: String;
+ FVersions: TX2InetVersions;
+ protected
+ procedure Execute(); override;
+ public
+ constructor Create();
+ destructor Destroy(); override;
+
+ property AppID: String read FAppID write FAppID;
+ property URL: String read FURL write FURL;
+ property ProxyParams: TIdProxyConnectionInfo read FProxyParams;
+
+ property ApplicationURL: String read FApplicationURL;
+ property Versions: TX2InetVersions read FVersions;
+ end;
+
+implementation
+uses
+ ActiveX,
+ SysUtils,
+ XMLDoc,
+
+ IdURI,
+ IdHTTP,
+ X2UtApp;
+
+
+{ TX2InetVersionInfo }
+procedure TX2InetVersionInfo.LoadFromNode(const ANode: IXMLNode);
+ function GetVersion(const AName: String): Integer;
+ var
+ xmlVersion: IXMLNode;
+
+ begin
+ Result := 0;
+ xmlVersion := ANode.ChildNodes.FindNode(AName);
+ if Assigned(xmlVersion) then
+ Result := StrToIntDef(xmlVersion.Text, 0);
+ end;
+
+var
+ xmlItem: IXMLNode;
+ xmlWhatsNew: IXMLNode;
+
+begin
+ FVersionTypeString := ANode.Attributes['type'];
+ FVersionType := vtUnknown;
+
+ if FVersionTypeString = 'stable' then
+ FVersionType := vtStable
+ else if FVersionTypeString = 'beta' then
+ FVersionType := vtBeta
+ else if FVersionTypeString = 'releasecandidate' then
+ FVersionType := vtReleaseCandidate;
+
+ FMajor := GetVersion('major');
+ FMinor := GetVersion('minor');
+ FRelease := GetVersion('release');
+ FBuild := GetVersion('build');
+
+ with App.Version do
+ FNewer := (FMajor > Major) or
+ ((FMajor = Major) and (FMinor > Minor)) or
+ ((FMajor = Major) and (FMinor = Minor) and (FRelease > Release)) or
+ ((FMajor = Major) and (FMinor = Minor) and (FRelease = Release) and (FBuild > Build));
+
+ FWhatsNewTemp := '';
+ xmlWhatsNew := ANode.ChildNodes.FindNode('whatsnew');
+ if Assigned(xmlWhatsNew) then
+ begin
+ xmlItem := xmlWhatsNew.ChildNodes.First();
+ while Assigned(xmlItem) do
+ begin
+ if xmlItem.NodeName = 'item' then
+ begin
+ FWhatsNewTemp := FWhatsNewTemp + '- ' + xmlItem.Text + #13#10;
+ end;
+
+ xmlItem := xmlItem.NextSibling();
+ end;
+ end;
+end;
+
+
+{ TX2InetVersions }
+constructor TX2InetVersions.Create();
+begin
+ inherited Create(TX2InetVersionInfo);
+end;
+
+
+function TX2InetVersions.Add(): TX2InetVersionInfo;
+begin
+ Result := TX2InetVersionInfo(inherited Add());
+end;
+
+
+function TX2InetVersions.GetItem(Index: Integer): TX2InetVersionInfo;
+begin
+ Result := TX2InetVersionInfo(inherited GetItem(Index));
+end;
+
+procedure TX2InetVersions.SetItem(Index: Integer; Value: TX2InetVersionInfo);
+begin
+ inherited SetItem(Index, Value);
+end;
+
+
+{ TX2InetVersion }
+constructor TX2InetVersion.Create();
+begin
+ inherited Create(True);
+
+ FProxyParams := TIdProxyConnectionInfo.Create();
+ FVersions := TX2InetVersions.Create();
+end;
+
+destructor TX2InetVersion.Destroy();
+begin
+ FreeAndNil(FVersions);
+ FreeAndNil(FProxyParams);
+
+ inherited;
+end;
+
+
+procedure TX2InetVersion.Execute();
+var
+ idHTTP: TIdHTTP;
+ memData: TMemoryStream;
+ xmlDoc: IXMLDocument;
+ xmlRoot: IXMLNode;
+ xmlURL: IXMLNode;
+ xmlVersion: IXMLNode;
+
+begin
+ CoInitialize(nil);
+
+ idHTTP := TIdHTTP.Create(nil);
+ try
+ idHTTP.ProxyParams.Assign(FProxyParams);
+ memData := TMemoryStream.Create();
+ try
+ idHTTP.Get(Format('%s?appid=%s', [FURL, TIdURI.ParamsEncode(FAppID)]), memData);
+ memData.Seek(0, soFromBeginning);
+
+ xmlDoc := TXMLDocument.Create(nil);
+ try
+ xmlDoc.LoadFromStream(memData);
+ xmlRoot := xmlDoc.DocumentElement;
+
+ if xmlRoot.NodeName <> 'application' then
+ exit;
+
+ xmlURL := xmlRoot.ChildNodes.FindNode('url');
+ if Assigned(xmlURL) then
+ FApplicationURL := xmlURL.Text;
+
+ xmlVersion := xmlRoot.ChildNodes.First();
+ while Assigned(xmlVersion) do
+ begin
+ if xmlVersion.NodeName = 'version' then
+ FVersions.Add().LoadFromNode(xmlVersion);
+
+ xmlVersion := xmlVersion.NextSibling();
+ end;
+ finally
+ xmlDoc := nil;
+ end;
+ finally
+ FreeAndNil(memData);
+ end;
+ finally
+ FreeAndNil(idHTTP);
+ end;
+end;
+
+end.
+
\ No newline at end of file
diff --git a/X2UtSettingsForm.pas b/X2UtSettingsForm.pas
index e4a8ae0..63742d5 100644
--- a/X2UtSettingsForm.pas
+++ b/X2UtSettingsForm.pas
@@ -18,11 +18,18 @@ uses
const ASection: String; const AForm: TCustomForm);
implementation
+uses
+ MultiMon,
+ Windows;
+
type
THackCustomForm = class(TCustomForm);
procedure ReadFormPos(const AFactory: TX2SettingsFactory;
const ASection: String; const AForm: TCustomForm);
+var
+ rBounds: TRect;
+
begin
with AFactory[ASection] do
try
@@ -30,13 +37,20 @@ begin
begin
if ReadBool('Maximized', (AForm.WindowState = wsMaximized)) then
AForm.WindowState := wsMaximized
- else with THackCustomForm(AForm) do begin
- WindowState := wsNormal;
- Position := poDesigned;
- Left := ReadInteger('Left', Left);
- Top := ReadInteger('Top', Top);
- Width := ReadInteger('Width', Width);
- Height := ReadInteger('Height', Height);
+ else with THackCustomForm(AForm) do
+ begin
+ rBounds.Left := ReadInteger('Left', Left);
+ rBounds.Top := ReadInteger('Top', Top);
+ rBounds.Right := rBounds.Left + ReadInteger('Width', Width);
+ rBounds.Bottom := rBounds.Top + ReadInteger('Height', Height);
+
+ // Make sure the window is at least partially visible
+ if MonitorFromRect(@rBounds, MONITOR_DEFAULTTONULL) <> 0 then
+ begin
+ WindowState := wsNormal;
+ Position := poDesigned;
+ BoundsRect := rBounds;
+ end;
end;
end;
finally