1
0
mirror of synced 2024-11-22 10:03:51 +00:00

Added an auto update check

This commit is contained in:
Mark van Renswoude 2012-11-19 20:59:08 +00:00
parent 9e2fa518aa
commit 25aa106abc
5 changed files with 262 additions and 32 deletions

View File

@ -28,7 +28,7 @@ object MainForm: TMainForm
Margins.Top = 8
Margins.Right = 8
Margins.Bottom = 8
ActivePage = tsFSX
ActivePage = tsAbout
Align = alClient
TabOrder = 1
object tsFSX: TTabSheet
@ -438,6 +438,7 @@ object MainForm: TMainForm
object tsAbout: TTabSheet
Caption = 'About'
ImageIndex = 1
ExplicitLeft = 12
object lblVersionCaption: TLabel
Left = 16
Top = 67
@ -486,6 +487,19 @@ object MainForm: TMainForm
Height = 13
Caption = 'E-mail:'
end
object lblProxy: TLabel
Left = 36
Top = 368
Width = 246
Height = 13
Caption = 'This might not work if you'#39're behind a proxy, sorry!'
Font.Charset = DEFAULT_CHARSET
Font.Color = clGrayText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
end
object lblWebsiteLink: TLinkLabel
Left = 75
Top = 111
@ -508,6 +522,23 @@ object MainForm: TMainForm
TabOrder = 1
OnLinkClick = lblLinkLinkClick
end
object cbCheckUpdates: TCheckBox
Left = 16
Top = 344
Width = 305
Height = 17
Caption = ' Automatically check for &updates'
TabOrder = 2
end
object btnCheckUpdates: TButton
Left = 344
Top = 340
Width = 83
Height = 25
Caption = '&Check now'
TabOrder = 3
OnClick = btnCheckUpdatesClick
end
end
end
object pnlG940: TPanel
@ -900,7 +931,7 @@ object MainForm: TMainForm
Width = 75
Height = 25
Anchors = [akTop, akRight]
Caption = 'Retry'
Caption = '&Retry'
TabOrder = 0
Visible = False
OnClick = btnRetryClick

View File

@ -15,6 +15,7 @@ uses
OtlComm,
OtlEventMonitor,
OtlTaskControl,
OtlTask,
pngimage,
X2UtPersistIntf,
@ -23,10 +24,15 @@ uses
LEDStateProvider;
const
CM_ASKAUTOUPDATE = WM_APP + 1;
MSG_UPDATE = 1;
MSG_NOUPDATE = 2;
type
TComboBoxArray = array[0..7] of TComboBoxEx;
TMainForm = class(TForm)
imgStateNotFound: TImage;
lblG940Throttle: TLabel;
@ -79,6 +85,9 @@ type
lblEmailLink: TLinkLabel;
lblWebsite: TLabel;
lblEmail: TLabel;
cbCheckUpdates: TCheckBox;
btnCheckUpdates: TButton;
lblProxy: TLabel;
procedure FormCreate(Sender: TObject);
procedure btnRetryClick(Sender: TObject);
@ -88,6 +97,7 @@ type
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FunctionComboBoxChange(Sender: TObject);
procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType);
procedure btnCheckUpdatesClick(Sender: TObject);
private
FEventMonitor: TOmniEventMonitor;
FStateConsumerTask: IOmniTaskControl;
@ -100,8 +110,10 @@ type
procedure ReadFunctions(AReader: IX2PersistReader; AComboBoxes: TComboBoxArray);
procedure ReadFSXExtra(AReader: IX2PersistReader);
procedure ReadAutoUpdate(AReader: IX2PersistReader);
procedure WriteFunctions(AWriter: IX2PersistWriter; AComboBoxes: TComboBoxArray);
procedure WriteFSXExtra(AWriter: IX2PersistWriter);
procedure WriteAutoUpdate(AWriter: IX2PersistWriter);
procedure LoadDefaultProfile;
procedure SaveDefaultProfile;
@ -114,6 +126,9 @@ type
procedure UpdateMapping;
procedure CheckForUpdatesThread(const ATask: IOmniTask);
procedure CheckForUpdates(AReportNoUpdates: Boolean);
procedure EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
procedure EventMonitorTerminated(const task: IOmniTaskControl);
@ -122,6 +137,8 @@ type
procedure HandleProviderKilled(ATask: IOmniTaskControl; AMessage: TOmniMessage);
procedure HandleProviderKilledFSX(ATask: IOmniTaskControl; AMessage: TOmniMessage);
procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE;
property EventMonitor: TOmniEventMonitor read FEventMonitor;
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
end;
@ -134,8 +151,9 @@ uses
ShellAPI,
SysUtils,
IdException,
IdHTTP,
OtlCommon,
OtlTask,
X2UtApp,
X2UtPersistRegistry,
@ -154,8 +172,10 @@ const
TEXT_STATE_NOTFOUND = 'Not found';
TEXT_STATE_FOUND = 'Connected';
KEY_DEFAULTPROFILE = '\Software\X2Software\G940LEDControl\DefaultProfile\';
KEY_SETTINGS = '\Software\X2Software\G940LEDControl\';
SECTION_DEFAULTPROFILE = 'DefaultProfile';
SECTION_FSX = 'FSX';
SECTION_SETTINGS = 'Settings';
type
@ -221,6 +241,17 @@ begin
end;
procedure TMainForm.CMAskAutoUpdate(var Msg: TMessage);
begin
if MessageBox(Self.Handle, 'I''m sorry to delay your flight, but I will only ask this once.'#13#10 +
'Do you want to automatically check for updates?', 'Check for updates', MB_YESNO or MB_ICONQUESTION) = ID_YES then
begin
cbCheckUpdates.Checked := True;
CheckForUpdates(False);
end;
end;
procedure TMainForm.SetDeviceState(const AMessage: string; AFound: Boolean);
begin
lblG940ThrottleState.Caption := AMessage;
@ -326,6 +357,32 @@ begin
end;
procedure TMainForm.ReadAutoUpdate(AReader: IX2PersistReader);
var
checkUpdates: Boolean;
askAutoUpdate: Boolean;
begin
askAutoUpdate := True;
if AReader.BeginSection(SECTION_SETTINGS) then
try
if AReader.ReadBoolean('CheckUpdates', checkUpdates) then
begin
cbCheckUpdates.Checked := checkUpdates;
askAutoUpdate := False;
end;
finally
AReader.EndSection;
end;
if askAutoUpdate then
PostMessage(Self.Handle, CM_ASKAUTOUPDATE, 0, 0)
else if cbCheckUpdates.Checked then
CheckForUpdates(False);
end;
procedure TMainForm.WriteFunctions(AWriter: IX2PersistWriter; AComboBoxes: TComboBoxArray);
var
comboBox: TComboBoxEx;
@ -362,6 +419,17 @@ begin
end;
procedure TMainForm.WriteAutoUpdate(AWriter: IX2PersistWriter);
begin
if AWriter.BeginSection(SECTION_SETTINGS) then
try
AWriter.WriteBoolean('CheckUpdates', cbCheckUpdates.Checked);
finally
AWriter.EndSection;
end;
end;
procedure TMainForm.LoadDefaultProfile;
var
registryReader: TX2UtPersistRegistry;
@ -371,12 +439,19 @@ begin
registryReader := TX2UtPersistRegistry.Create;
try
registryReader.RootKey := HKEY_CURRENT_USER;
registryReader.Key := KEY_DEFAULTPROFILE;
registryReader.Key := KEY_SETTINGS;
reader := registryReader.CreateReader;
ReadFunctions(reader, FFSXComboBoxes);
ReadFSXExtra(reader);
if reader.BeginSection(SECTION_DEFAULTPROFILE) then
try
ReadFunctions(reader, FFSXComboBoxes);
ReadFSXExtra(reader);
finally
reader.EndSection;
end;
ReadAutoUpdate(reader);
finally
FreeAndNil(registryReader);
end;
@ -392,11 +467,18 @@ begin
registryWriter := TX2UtPersistRegistry.Create;
try
registryWriter.RootKey := HKEY_CURRENT_USER;
registryWriter.Key := KEY_DEFAULTPROFILE;
registryWriter.Key := KEY_SETTINGS;
writer := registryWriter.CreateWriter;
WriteFunctions(writer, FFSXComboBoxes);
WriteFSXExtra(writer);
if writer.BeginSection(SECTION_DEFAULTPROFILE) then
try
WriteFunctions(writer, FFSXComboBoxes);
WriteFSXExtra(writer);
finally
writer.EndSection;
end;
WriteAutoUpdate(writer);
finally
FreeAndNil(registryWriter);
end;
@ -426,12 +508,123 @@ begin
end;
function FetchNextNumber(var AValue: string; out ANumber: Integer): Boolean;
var
dotPos: Integer;
number: string;
begin
ANumber := 0;
dotPos := AnsiPos('.', AValue);
if dotPos > 0 then
begin
number := Copy(AValue, 1, Pred(dotPos));
Delete(AValue, 1, dotPos);
end
else
begin
number := AValue;
AValue := '';
end;
Result := TryStrToInt(number, ANumber);
end;
function VersionIsNewer(const AVersion1, AVersion2: string): Boolean;
var
version1: string;
version2: string;
number1: Integer;
number2: Integer;
begin
if Length(AVersion1) = 0 then
begin
Result := True;
Exit;
end;
Result := False;
version1 := AVersion1;
version2 := AVersion2;
while (not Result) and
FetchNextNumber(version1, number1) and
FetchNextNumber(version2, number2) do
begin
if number2 > number1 then
Result := True
else if number2 < number1 then
Break;
end;
end;
procedure TMainForm.CheckForUpdatesThread(const ATask: IOmniTask);
var
httpClient: TIdHTTP;
msgSent: Boolean;
latestVersion: string;
begin
msgSent := False;
try
httpClient := TIdHTTP.Create(nil);
try
latestVersion := httpClient.Get('http://g940.x2software.net/version');
if VersionIsNewer(Format('%d.%d.%d', [App.Version.Major, App.Version.Minor, App.Version.Release]), latestVersion) then
ATask.Comm.Send(MSG_UPDATE)
else
begin
if ATask.Param.ByName('ReportNoUpdates').AsBoolean then
ATask.Comm.Send(MSG_NOUPDATE, True);
end;
msgSent := True;
finally
FreeAndNil(httpClient);
end;
except
on E:EIdSilentException do;
on E:Exception do
begin
if not msgSent then
ATask.Comm.Send(MSG_NOUPDATE, False);
end;
end;
end;
procedure TMainForm.CheckForUpdates(AReportNoUpdates: Boolean);
begin
btnCheckUpdates.Enabled := False;
CreateTask(CheckForUpdatesThread, 'CheckForUpdatesThread')
.MonitorWith(EventMonitor)
.SetParameter('ReportNoUpdates', AReportNoUpdates)
.Run;
end;
procedure TMainForm.EventMonitorMessage(const task: IOmniTaskControl; const msg: TOmniMessage);
begin
case msg.MsgID of
MSG_NOTIFY_DEVICESTATE: HandleDeviceStateMessage(task, msg);
MSG_RUN_IN_MAINTHREAD: HandleRunInMainThreadMessage(task, msg);
MSG_PROVIDER_KILLED: HandleProviderKilled(task, msg);
MSG_UPDATE:
if MessageBox(Self.Handle, 'An update is available on the G940 LED Control website.'#13#10'Do you want to go there now?',
'Update available', MB_YESNO or MB_ICONINFORMATION) = ID_YES then
ShellExecute(Self.Handle, 'open', PChar('http://g940.x2software.net/#download'), nil, nil, SW_SHOWNORMAL);
MSG_NOUPDATE:
if msg.MsgData.AsBoolean then
MessageBox(Self.Handle, 'You are using the latest version.', 'No update available', MB_OK or MB_ICONINFORMATION)
else
MessageBox(Self.Handle, 'Failed to check for updates. Maybe try again later?', 'Uh-oh', MB_OK or MB_ICONWARNING);
end;
end;
@ -442,7 +635,8 @@ begin
begin
FStateConsumerTask := nil;
Close;
end;
end else if task.Name = 'CheckForUpdatesThread' then
btnCheckUpdates.Enabled := True;
end;
@ -495,6 +689,11 @@ begin
end;
procedure TMainForm.btnCheckUpdatesClick(Sender: TObject);
begin
CheckForUpdates(True);
end;
procedure TMainForm.btnFSXConnectClick(Sender: TObject);
begin
SaveDefaultProfile;

View File

@ -3,14 +3,14 @@ program G940LEDControl;
uses
Forms,
MainFrm in 'Forms\MainFrm.pas' {MainForm},
FSXLEDStateProvider in 'Units\FSXLEDStateProvider.pas',
LEDStateConsumer in 'Units\LEDStateConsumer.pas',
LEDStateProvider in 'Units\LEDStateProvider.pas',
LEDFunctionMap in 'Units\LEDFunctionMap.pas',
G940LEDStateConsumer in 'Units\G940LEDStateConsumer.pas',
LogiJoystickDLL in '..\Shared\LogiJoystickDLL.pas',
SimConnect in '..\Shared\SimConnect.pas',
ButtonSelectFrm in 'Forms\ButtonSelectFrm.pas' {ButtonSelectForm};
ButtonSelectFrm in 'Forms\ButtonSelectFrm.pas' {ButtonSelectForm},
FSXLEDStateProvider in 'Units\FSXLEDStateProvider.pas',
G940LEDStateConsumer in 'Units\G940LEDStateConsumer.pas',
LEDFunctionMap in 'Units\LEDFunctionMap.pas',
LEDStateConsumer in 'Units\LEDStateConsumer.pas',
LEDStateProvider in 'Units\LEDStateProvider.pas';
{$R *.res}

View File

@ -163,17 +163,17 @@
<DCCReference Include="Forms\MainFrm.pas">
<Form>MainForm</Form>
</DCCReference>
<DCCReference Include="Units\FSXLEDStateProvider.pas"/>
<DCCReference Include="Units\LEDStateConsumer.pas"/>
<DCCReference Include="Units\LEDStateProvider.pas"/>
<DCCReference Include="Units\LEDFunctionMap.pas"/>
<DCCReference Include="Units\G940LEDStateConsumer.pas"/>
<DCCReference Include="..\Shared\LogiJoystickDLL.pas"/>
<DCCReference Include="..\Shared\SimConnect.pas"/>
<DCCReference Include="Forms\ButtonSelectFrm.pas">
<Form>ButtonSelectForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="Units\FSXLEDStateProvider.pas"/>
<DCCReference Include="Units\G940LEDStateConsumer.pas"/>
<DCCReference Include="Units\LEDFunctionMap.pas"/>
<DCCReference Include="Units\LEDStateConsumer.pas"/>
<DCCReference Include="Units\LEDStateProvider.pas"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>

View File

@ -11,19 +11,19 @@ uses
const
MSG_CLEAR_FUNCTIONS = 1;
MSG_SET_FUNCTION = 2;
MSG_INITIALIZE_PROVIDER = 3;
MSG_FINALIZE_PROVIDER = 4;
MSG_PROCESS_MESSAGES = 5;
MSG_FINALIZE = 6;
MSG_CLEAR_FUNCTIONS = 1001;
MSG_SET_FUNCTION = 1002;
MSG_INITIALIZE_PROVIDER = 1003;
MSG_FINALIZE_PROVIDER = 1004;
MSG_PROCESS_MESSAGES = 1005;
MSG_FINALIZE = 1006;
MSG_PROVIDER_KILLED = 7;
MSG_RUN_IN_MAINTHREAD = 8;
MSG_PROVIDER_KILLED = 1007;
MSG_RUN_IN_MAINTHREAD = 1008;
MSG_CONSUMER_OFFSET = MSG_RUN_IN_MAINTHREAD;
TIMER_PROCESSMESSAGES = 1;
TIMER_PROCESSMESSAGES = 1001;
TIMER_CONSUMER_OFFSET = TIMER_PROCESSMESSAGES;