This commit is contained in:
parent
a9b472ea9a
commit
0a9d825261
@ -1,7 +1,7 @@
|
|||||||
object MainForm: TMainForm
|
object MainForm: TMainForm
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
ActiveControl = cmbProfiles
|
ActiveControl = cbProfileMenu
|
||||||
BorderIcons = [biSystemMenu, biMinimize]
|
BorderIcons = [biSystemMenu, biMinimize]
|
||||||
BorderStyle = bsSingle
|
BorderStyle = bsSingle
|
||||||
Caption = 'G940 LED Control'
|
Caption = 'G940 LED Control'
|
||||||
@ -29,11 +29,11 @@ object MainForm: TMainForm
|
|||||||
Margins.Top = 8
|
Margins.Top = 8
|
||||||
Margins.Right = 8
|
Margins.Right = 8
|
||||||
Margins.Bottom = 8
|
Margins.Bottom = 8
|
||||||
ActivePage = tsFSX
|
ActivePage = tsConfiguration
|
||||||
Align = alClient
|
Align = alClient
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
object tsFSX: TTabSheet
|
object tsButtons: TTabSheet
|
||||||
Caption = 'Configuration'
|
Caption = ' Button assignment '
|
||||||
DesignSize = (
|
DesignSize = (
|
||||||
442
|
442
|
||||||
452)
|
452)
|
||||||
@ -271,7 +271,7 @@ object MainForm: TMainForm
|
|||||||
object bvlProfiles: TBevel
|
object bvlProfiles: TBevel
|
||||||
Left = 11
|
Left = 11
|
||||||
Top = 52
|
Top = 52
|
||||||
Width = 474
|
Width = 418
|
||||||
Height = 13
|
Height = 13
|
||||||
Shape = bsTopLine
|
Shape = bsTopLine
|
||||||
end
|
end
|
||||||
@ -371,6 +371,50 @@ object MainForm: TMainForm
|
|||||||
OnClick = btnDeleteProfileClick
|
OnClick = btnDeleteProfileClick
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
object tsConfiguration: TTabSheet
|
||||||
|
Caption = ' Configuration '
|
||||||
|
ImageIndex = 2
|
||||||
|
object lblProfileSwitching: TLabel
|
||||||
|
Left = 11
|
||||||
|
Top = 19
|
||||||
|
Width = 92
|
||||||
|
Height = 13
|
||||||
|
Caption = 'Profile switching'
|
||||||
|
Font.Charset = DEFAULT_CHARSET
|
||||||
|
Font.Color = clWindowText
|
||||||
|
Font.Height = -11
|
||||||
|
Font.Name = 'Tahoma'
|
||||||
|
Font.Style = [fsBold]
|
||||||
|
ParentFont = False
|
||||||
|
end
|
||||||
|
object bvlProfileSwitching: TBevel
|
||||||
|
Left = 224
|
||||||
|
Top = 26
|
||||||
|
Width = 205
|
||||||
|
Height = 13
|
||||||
|
Shape = bsTopLine
|
||||||
|
end
|
||||||
|
object cbProfileMenu: TCheckBox
|
||||||
|
Left = 11
|
||||||
|
Top = 44
|
||||||
|
Width = 409
|
||||||
|
Height = 17
|
||||||
|
Caption = ' Add profile selection to FSX "Add-ons" menu'
|
||||||
|
Checked = True
|
||||||
|
State = cbChecked
|
||||||
|
TabOrder = 0
|
||||||
|
OnClick = cbProfileMenuClick
|
||||||
|
end
|
||||||
|
object cbProfileMenuCascaded: TCheckBox
|
||||||
|
Left = 31
|
||||||
|
Top = 67
|
||||||
|
Width = 389
|
||||||
|
Height = 17
|
||||||
|
Caption = ' Cascaded menu (profiles in "G940 Profile" submenu)'
|
||||||
|
TabOrder = 1
|
||||||
|
OnClick = cbProfileMenuCascadedClick
|
||||||
|
end
|
||||||
|
end
|
||||||
object tsAbout: TTabSheet
|
object tsAbout: TTabSheet
|
||||||
Caption = 'About'
|
Caption = 'About'
|
||||||
ImageIndex = 1
|
ImageIndex = 1
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
unit MainFrm;
|
unit MainFrm;
|
||||||
|
|
||||||
|
// #ToDo1 -oMvR: 3-3-2013: trigger profile update when Save As only changes the name
|
||||||
|
|
||||||
interface
|
interface
|
||||||
uses
|
uses
|
||||||
System.Classes,
|
System.Classes,
|
||||||
@ -22,11 +24,13 @@ uses
|
|||||||
FSXSimConnectIntf,
|
FSXSimConnectIntf,
|
||||||
LEDStateConsumer,
|
LEDStateConsumer,
|
||||||
Profile,
|
Profile,
|
||||||
|
ProfileManager,
|
||||||
Settings;
|
Settings;
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
CM_ASKAUTOUPDATE = WM_APP + 1;
|
CM_ASKAUTOUPDATE = WM_APP + 1;
|
||||||
|
CM_PROFILECHANGED = WM_APP + 2;
|
||||||
|
|
||||||
TM_UPDATE = 1;
|
TM_UPDATE = 1;
|
||||||
TM_NOUPDATE = 2;
|
TM_NOUPDATE = 2;
|
||||||
@ -48,7 +52,7 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
TMainForm = class(TForm)
|
TMainForm = class(TForm, IProfileObserver)
|
||||||
imgStateNotFound: TImage;
|
imgStateNotFound: TImage;
|
||||||
lblG940Throttle: TLabel;
|
lblG940Throttle: TLabel;
|
||||||
imgStateFound: TImage;
|
imgStateFound: TImage;
|
||||||
@ -67,7 +71,7 @@ type
|
|||||||
cbCheckUpdates: TCheckBox;
|
cbCheckUpdates: TCheckBox;
|
||||||
btnCheckUpdates: TButton;
|
btnCheckUpdates: TButton;
|
||||||
lblProxy: TLabel;
|
lblProxy: TLabel;
|
||||||
tsFSX: TTabSheet;
|
tsButtons: TTabSheet;
|
||||||
btnP1: TButton;
|
btnP1: TButton;
|
||||||
lblP1Function: TLabel;
|
lblP1Function: TLabel;
|
||||||
lblP1Category: TLabel;
|
lblP1Category: TLabel;
|
||||||
@ -103,6 +107,11 @@ type
|
|||||||
lblFSX: TLabel;
|
lblFSX: TLabel;
|
||||||
lblFSXState: TLabel;
|
lblFSXState: TLabel;
|
||||||
pnlState: TPanel;
|
pnlState: TPanel;
|
||||||
|
tsConfiguration: TTabSheet;
|
||||||
|
cbProfileMenu: TCheckBox;
|
||||||
|
cbProfileMenuCascaded: TCheckBox;
|
||||||
|
lblProfileSwitching: TLabel;
|
||||||
|
bvlProfileSwitching: TBevel;
|
||||||
|
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType);
|
procedure lblLinkLinkClick(Sender: TObject; const Link: string; LinkType: TSysLinkType);
|
||||||
@ -113,13 +122,13 @@ type
|
|||||||
procedure cbCheckUpdatesClick(Sender: TObject);
|
procedure cbCheckUpdatesClick(Sender: TObject);
|
||||||
procedure btnSaveProfileClick(Sender: TObject);
|
procedure btnSaveProfileClick(Sender: TObject);
|
||||||
procedure btnDeleteProfileClick(Sender: TObject);
|
procedure btnDeleteProfileClick(Sender: TObject);
|
||||||
|
procedure cbProfileMenuClick(Sender: TObject);
|
||||||
|
procedure cbProfileMenuCascadedClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
FLEDControls: array[0..LED_COUNT - 1] of TLEDControls;
|
FLEDControls: array[0..LED_COUNT - 1] of TLEDControls;
|
||||||
FEventMonitor: TOmniEventMonitor;
|
FEventMonitor: TOmniEventMonitor;
|
||||||
|
|
||||||
FProfilesFilename: string;
|
FProfilesFilename: string;
|
||||||
FProfiles: TProfileList;
|
|
||||||
FActiveProfile: TProfile;
|
|
||||||
FLockChangeProfile: Boolean;
|
FLockChangeProfile: Boolean;
|
||||||
FStateConsumerTask: IOmniTaskControl;
|
FStateConsumerTask: IOmniTaskControl;
|
||||||
|
|
||||||
@ -128,13 +137,17 @@ type
|
|||||||
|
|
||||||
FSettingsFileName: string;
|
FSettingsFileName: string;
|
||||||
FSettings: TSettings;
|
FSettings: TSettings;
|
||||||
|
|
||||||
procedure SetActiveProfile(const Value: TProfile);
|
|
||||||
protected
|
protected
|
||||||
procedure RegisterDeviceArrival;
|
procedure RegisterDeviceArrival;
|
||||||
procedure UnregisterDeviceArrival;
|
procedure UnregisterDeviceArrival;
|
||||||
|
|
||||||
|
{ IProfileObserver }
|
||||||
|
procedure ObserveAdd(AProfile: TProfile);
|
||||||
|
procedure ObserveRemove(AProfile: TProfile);
|
||||||
|
procedure ObserveActiveChanged(AProfile: TProfile);
|
||||||
|
|
||||||
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
|
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
|
||||||
|
procedure CMProfileChanged(var Msg: TMessage); message CM_PROFILECHANGED;
|
||||||
protected
|
protected
|
||||||
procedure FindLEDControls;
|
procedure FindLEDControls;
|
||||||
procedure LoadProfiles;
|
procedure LoadProfiles;
|
||||||
@ -151,6 +164,9 @@ type
|
|||||||
procedure UpdateProfile(AProfile: TProfile);
|
procedure UpdateProfile(AProfile: TProfile);
|
||||||
procedure DeleteProfile(AProfile: TProfile; ASetActiveProfile: Boolean);
|
procedure DeleteProfile(AProfile: TProfile; ASetActiveProfile: Boolean);
|
||||||
|
|
||||||
|
procedure ApplyProfileMenuSettings;
|
||||||
|
procedure FinalizeProfileMenu;
|
||||||
|
|
||||||
procedure SetDeviceState(const AMessage: string; AFound: Boolean);
|
procedure SetDeviceState(const AMessage: string; AFound: Boolean);
|
||||||
procedure SetFSXState(const AMessage: string; AConnected: Boolean);
|
procedure SetFSXState(const AMessage: string; AConnected: Boolean);
|
||||||
// procedure SetFSXToggleZoomButton(const ADeviceGUID: TGUID; AButtonIndex: Integer; const ADisplayText: string);
|
// procedure SetFSXToggleZoomButton(const ADeviceGUID: TGUID; AButtonIndex: Integer; const ADisplayText: string);
|
||||||
@ -166,9 +182,7 @@ type
|
|||||||
|
|
||||||
procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE;
|
procedure CMAskAutoUpdate(var Msg: TMessage); message CM_ASKAUTOUPDATE;
|
||||||
|
|
||||||
property ActiveProfile: TProfile read FActiveProfile write SetActiveProfile;
|
|
||||||
property EventMonitor: TOmniEventMonitor read FEventMonitor;
|
property EventMonitor: TOmniEventMonitor read FEventMonitor;
|
||||||
property Profiles: TProfileList read FProfiles;
|
|
||||||
property Settings: TSettings read FSettings;
|
property Settings: TSettings read FSettings;
|
||||||
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
|
property StateConsumerTask: IOmniTaskControl read FStateConsumerTask;
|
||||||
end;
|
end;
|
||||||
@ -190,6 +204,9 @@ uses
|
|||||||
|
|
||||||
ButtonFunctionFrm,
|
ButtonFunctionFrm,
|
||||||
ConfigConversion,
|
ConfigConversion,
|
||||||
|
DebugLog,
|
||||||
|
FSXLEDFunctionProviderIntf,
|
||||||
|
FSXResources,
|
||||||
FSXSimConnectStateMonitor,
|
FSXSimConnectStateMonitor,
|
||||||
G940LEDStateConsumer,
|
G940LEDStateConsumer,
|
||||||
LEDColorIntf,
|
LEDColorIntf,
|
||||||
@ -234,6 +251,17 @@ type
|
|||||||
|
|
||||||
{ TMainForm }
|
{ TMainForm }
|
||||||
procedure TMainForm.FormCreate(Sender: TObject);
|
procedure TMainForm.FormCreate(Sender: TObject);
|
||||||
|
|
||||||
|
procedure AlignBevel(ABevel: TBevel; ACaption: TLabel);
|
||||||
|
var
|
||||||
|
bounds: TRect;
|
||||||
|
|
||||||
|
begin
|
||||||
|
bounds := ABevel.BoundsRect;
|
||||||
|
bounds.Left := ACaption.BoundsRect.Right + 8;
|
||||||
|
ABevel.BoundsRect := bounds;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
worker: IOmniWorker;
|
worker: IOmniWorker;
|
||||||
|
|
||||||
@ -241,23 +269,29 @@ begin
|
|||||||
lblVersion.Caption := App.Version.FormatVersion(False);
|
lblVersion.Caption := App.Version.FormatVersion(False);
|
||||||
|
|
||||||
PageControl.ActivePageIndex := 0;
|
PageControl.ActivePageIndex := 0;
|
||||||
|
AlignBevel(bvlProfileSwitching, lblProfileSwitching);
|
||||||
|
|
||||||
FEventMonitor := TOmniEventMonitor.Create(Self);
|
FEventMonitor := TOmniEventMonitor.Create(Self);
|
||||||
|
|
||||||
|
Debug.Log('UI: Starting G940 LED state consumer thread');
|
||||||
worker := TG940LEDStateConsumer.Create;
|
worker := TG940LEDStateConsumer.Create;
|
||||||
FStateConsumerTask := EventMonitor.Monitor(CreateTask(worker)).MsgWait;
|
FStateConsumerTask := EventMonitor.Monitor(CreateTask(worker));
|
||||||
|
|
||||||
EventMonitor.OnTaskMessage := EventMonitorMessage;
|
EventMonitor.OnTaskMessage := EventMonitorMessage;
|
||||||
EventMonitor.OnTaskTerminated := EventMonitorTerminated;
|
EventMonitor.OnTaskTerminated := EventMonitorTerminated;
|
||||||
|
|
||||||
StateConsumerTask.Run;
|
StateConsumerTask.Run;
|
||||||
|
|
||||||
|
|
||||||
|
Debug.Log('UI: Starting FSX state monitor thread');
|
||||||
worker := TFSXStateMonitorWorker.Create;
|
worker := TFSXStateMonitorWorker.Create;
|
||||||
EventMonitor.Monitor(CreateTask(worker)).Run;
|
EventMonitor.Monitor(CreateTask(worker)).Run;
|
||||||
|
|
||||||
|
TProfileManager.Attach(Self);
|
||||||
|
|
||||||
FindLEDControls;
|
FindLEDControls;
|
||||||
|
|
||||||
FProfilesFilename := App.UserPath + FilenameProfiles;
|
FProfilesFilename := App.UserPath + FilenameProfiles;
|
||||||
FProfiles := TProfileList.Create(True);
|
|
||||||
LoadProfiles;
|
LoadProfiles;
|
||||||
|
|
||||||
FSettingsFileName := App.UserPath + FilenameSettings;
|
FSettingsFileName := App.UserPath + FilenameSettings;
|
||||||
@ -269,9 +303,10 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.FormDestroy(Sender: TObject);
|
procedure TMainForm.FormDestroy(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
UnregisterDeviceArrival;
|
FinalizeProfileMenu;
|
||||||
|
|
||||||
FreeAndNil(FProfiles);
|
UnregisterDeviceArrival;
|
||||||
|
TProfileManager.Detach(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -289,6 +324,8 @@ var
|
|||||||
request: TDevBroadcastDeviceInterface;
|
request: TDevBroadcastDeviceInterface;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('UI: Registering for device notifications');
|
||||||
|
|
||||||
ZeroMemory(@request, SizeOf(request));
|
ZeroMemory(@request, SizeOf(request));
|
||||||
request.dbcc_size := SizeOf(request);
|
request.dbcc_size := SizeOf(request);
|
||||||
request.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
|
request.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;
|
||||||
@ -303,6 +340,8 @@ procedure TMainForm.UnregisterDeviceArrival;
|
|||||||
begin
|
begin
|
||||||
if Assigned(FDeviceNotification) then
|
if Assigned(FDeviceNotification) then
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('UI: Unregistering for device notifications');
|
||||||
|
|
||||||
UnregisterDeviceNotification(FDeviceNotification);
|
UnregisterDeviceNotification(FDeviceNotification);
|
||||||
FDeviceNotification := nil;
|
FDeviceNotification := nil;
|
||||||
end;
|
end;
|
||||||
@ -316,16 +355,48 @@ begin
|
|||||||
|
|
||||||
case Msg.WParam of
|
case Msg.WParam of
|
||||||
DBT_DEVICEARRIVAL:
|
DBT_DEVICEARRIVAL:
|
||||||
if (not FG940Found) then
|
begin
|
||||||
StateConsumerTask.Comm.Send(TM_FINDTHROTTLEDEVICE);
|
Debug.Log('UI: Device arrived');
|
||||||
|
|
||||||
|
if (not FG940Found) then
|
||||||
|
StateConsumerTask.Comm.Send(TM_FINDTHROTTLEDEVICE);
|
||||||
|
end;
|
||||||
|
|
||||||
DBT_DEVICEREMOVECOMPLETE:
|
DBT_DEVICEREMOVECOMPLETE:
|
||||||
if FG940Found then
|
begin
|
||||||
StateConsumerTask.Comm.Send(TM_TESTTHROTTLEDEVICE);
|
Debug.Log('UI: Device removed');
|
||||||
|
|
||||||
|
if FG940Found then
|
||||||
|
StateConsumerTask.Comm.Send(TM_TESTTHROTTLEDEVICE);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.CMProfileChanged(var Msg: TMessage);
|
||||||
|
var
|
||||||
|
profile: TProfile;
|
||||||
|
|
||||||
|
begin
|
||||||
|
profile := TProfileManager.Instance.ActiveProfile;
|
||||||
|
|
||||||
|
if Settings.ActiveProfile <> profile.Name then
|
||||||
|
begin
|
||||||
|
Settings.ActiveProfile := profile.Name;
|
||||||
|
SaveSettings;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FLockChangeProfile := True;
|
||||||
|
try
|
||||||
|
cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(profile);
|
||||||
|
finally
|
||||||
|
FLockChangeProfile := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
LoadActiveProfile;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.FindLEDControls;
|
procedure TMainForm.FindLEDControls;
|
||||||
|
|
||||||
function ComponentByName(const AName: string; ATag: NativeInt): TComponent;
|
function ComponentByName(const AName: string; ATag: NativeInt): TComponent;
|
||||||
@ -365,49 +436,63 @@ var
|
|||||||
profile: TProfile;
|
profile: TProfile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not FileExists(FProfilesFilename) then
|
Debug.LogFmt('UI: Loading profiles (%s)', [FProfilesFilename]);
|
||||||
begin
|
Debug.Indent;
|
||||||
{ Check if version 0.x settings are in the registry }
|
|
||||||
defaultProfile := ConfigConversion.ConvertProfile0To1;
|
|
||||||
|
|
||||||
if not Assigned(defaultProfile) then
|
|
||||||
defaultProfile := CreateDefaultProfile
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
defaultProfile.Name := DefaultProfileName;
|
|
||||||
defaultProfile.IsTemporary := True;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if Assigned(defaultProfile) then
|
|
||||||
Profiles.Add(defaultProfile);
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
persistXML := TX2UtPersistXML.Create;
|
|
||||||
try
|
|
||||||
persistXML.FileName := FProfilesFilename;
|
|
||||||
Profiles.Load(persistXML.CreateReader);
|
|
||||||
finally
|
|
||||||
FreeAndNil(persistXML);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ Make sure we always have a profile }
|
|
||||||
if Profiles.Count = 0 then
|
|
||||||
Profiles.Add(CreateDefaultProfile);
|
|
||||||
|
|
||||||
FLockChangeProfile := True;
|
|
||||||
try
|
try
|
||||||
cmbProfiles.Items.BeginUpdate;
|
if not FileExists(FProfilesFilename) then
|
||||||
try
|
begin
|
||||||
cmbProfiles.Items.Clear;
|
Debug.Log('UI: Profiles not found, attempting conversion from 0.x profile');
|
||||||
|
|
||||||
for profile in Profiles do
|
{ Check if version 0.x settings are in the registry }
|
||||||
cmbProfiles.Items.AddObject(profile.Name, profile);
|
defaultProfile := ConfigConversion.ConvertProfile0To1;
|
||||||
|
|
||||||
|
if not Assigned(defaultProfile) then
|
||||||
|
begin
|
||||||
|
Debug.Log('UI: 0.x profile not found, creating default profile');
|
||||||
|
defaultProfile := CreateDefaultProfile
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
Debug.Log('UI: Succesfully converted 0.x profile');
|
||||||
|
defaultProfile.Name := DefaultProfileName;
|
||||||
|
defaultProfile.IsTemporary := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(defaultProfile) then
|
||||||
|
TProfileManager.Add(defaultProfile);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
persistXML := TX2UtPersistXML.Create;
|
||||||
|
try
|
||||||
|
persistXML.FileName := FProfilesFilename;
|
||||||
|
TProfileManager.Load(persistXML.CreateReader);
|
||||||
|
finally
|
||||||
|
FreeAndNil(persistXML);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Make sure we always have a profile }
|
||||||
|
if TProfileManager.Instance.Count = 0 then
|
||||||
|
begin
|
||||||
|
Debug.Log('UI: No profiles found, creating default profile');
|
||||||
|
TProfileManager.Add(CreateDefaultProfile);
|
||||||
|
end;
|
||||||
|
|
||||||
|
FLockChangeProfile := True;
|
||||||
|
try
|
||||||
|
cmbProfiles.Items.BeginUpdate;
|
||||||
|
try
|
||||||
|
cmbProfiles.Items.Clear;
|
||||||
|
|
||||||
|
for profile in TProfileManager.Instance do
|
||||||
|
cmbProfiles.Items.AddObject(profile.Name, profile);
|
||||||
|
finally
|
||||||
|
cmbProfiles.Items.EndUpdate;
|
||||||
|
end;
|
||||||
finally
|
finally
|
||||||
cmbProfiles.Items.EndUpdate;
|
FLockChangeProfile := False;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
FLockChangeProfile := False;
|
Debug.UnIndent;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -417,10 +502,12 @@ var
|
|||||||
persistXML: TX2UtPersistXML;
|
persistXML: TX2UtPersistXML;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Debug.LogFmt('UI: Saving profiles (%s)', [FProfilesFilename]);
|
||||||
|
|
||||||
persistXML := TX2UtPersistXML.Create;
|
persistXML := TX2UtPersistXML.Create;
|
||||||
try
|
try
|
||||||
persistXML.FileName := FProfilesFilename;
|
persistXML.FileName := FProfilesFilename;
|
||||||
Profiles.Save(persistXML.CreateWriter);
|
TProfileManager.Instance.Save(persistXML.CreateWriter);
|
||||||
finally
|
finally
|
||||||
FreeAndNil(persistXML);
|
FreeAndNil(persistXML);
|
||||||
end;
|
end;
|
||||||
@ -433,44 +520,62 @@ var
|
|||||||
profile: TProfile;
|
profile: TProfile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not FileExists(FSettingsFileName) then
|
Debug.LogFmt('UI: Loading profiles (%s)', [FSettingsFilename]);
|
||||||
begin
|
Debug.Indent;
|
||||||
{ Check if version 0.x settings are in the registry }
|
try
|
||||||
FSettings := ConfigConversion.ConvertSettings0To1;
|
if not FileExists(FSettingsFileName) then
|
||||||
|
begin
|
||||||
|
Debug.Log('UI: Settings not found, attempting conversion from 0.x settings');
|
||||||
|
|
||||||
if not Assigned(FSettings) then
|
{ Check if version 0.x settings are in the registry }
|
||||||
|
FSettings := ConfigConversion.ConvertSettings0To1;
|
||||||
|
|
||||||
|
if not Assigned(FSettings) then
|
||||||
|
begin
|
||||||
|
Debug.Log('UI: 0.x profile not found, creating default settings');
|
||||||
|
FSettings := TSettings.Create;
|
||||||
|
end else
|
||||||
|
Debug.Log('UI: Succesfully converted 0.x settings');
|
||||||
|
end else
|
||||||
|
begin
|
||||||
FSettings := TSettings.Create;
|
FSettings := TSettings.Create;
|
||||||
end else
|
|
||||||
begin
|
|
||||||
FSettings := TSettings.Create;
|
|
||||||
|
|
||||||
persistXML := TX2UtPersistXML.Create;
|
persistXML := TX2UtPersistXML.Create;
|
||||||
try
|
try
|
||||||
persistXML.FileName := FSettingsFileName;
|
persistXML.FileName := FSettingsFileName;
|
||||||
Settings.Load(persistXML.CreateReader);
|
Settings.Load(persistXML.CreateReader);
|
||||||
finally
|
finally
|
||||||
FreeAndNil(persistXML);
|
FreeAndNil(persistXML);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Default profile }
|
||||||
|
profile := nil;
|
||||||
|
if Length(Settings.ActiveProfile) > 0 then
|
||||||
|
profile := TProfileManager.Instance.Find(Settings.ActiveProfile);
|
||||||
|
|
||||||
|
{ LoadProfiles ensures there's always at least 1 profile }
|
||||||
|
if (not Assigned(profile)) and (TProfileManager.Instance.Count > 0) then
|
||||||
|
profile := TProfileManager.Instance[0];
|
||||||
|
|
||||||
|
TProfileManager.Instance.ActiveProfile := profile;
|
||||||
|
|
||||||
|
{ Auto-update }
|
||||||
|
cbCheckUpdates.Checked := Settings.CheckUpdates;
|
||||||
|
|
||||||
|
if not Settings.HasCheckUpdates then
|
||||||
|
PostMessage(Self.Handle, CM_ASKAUTOUPDATE, 0, 0)
|
||||||
|
else if Settings.CheckUpdates then
|
||||||
|
CheckForUpdates(False);
|
||||||
|
|
||||||
|
|
||||||
|
cbProfileMenu.Checked := Settings.ProfileMenu;
|
||||||
|
cbProfileMenuCascaded.Checked := Settings.ProfileMenuCascaded;
|
||||||
|
|
||||||
|
ApplyProfileMenuSettings;
|
||||||
|
finally
|
||||||
|
Debug.UnIndent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Default profile }
|
|
||||||
profile := nil;
|
|
||||||
if Length(Settings.ActiveProfile) > 0 then
|
|
||||||
profile := Profiles.Find(Settings.ActiveProfile);
|
|
||||||
|
|
||||||
{ LoadProfiles ensures there's always at least 1 profile }
|
|
||||||
if (not Assigned(profile)) and (Profiles.Count > 0) then
|
|
||||||
profile := Profiles[0];
|
|
||||||
|
|
||||||
SetActiveProfile(profile);
|
|
||||||
|
|
||||||
{ Auto-update }
|
|
||||||
cbCheckUpdates.Checked := Settings.CheckUpdates;
|
|
||||||
|
|
||||||
if not Settings.HasCheckUpdates then
|
|
||||||
PostMessage(Self.Handle, CM_ASKAUTOUPDATE, 0, 0)
|
|
||||||
else if Settings.CheckUpdates then
|
|
||||||
CheckForUpdates(False);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -479,6 +584,8 @@ var
|
|||||||
persistXML: TX2UtPersistXML;
|
persistXML: TX2UtPersistXML;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Debug.LogFmt('UI: Saving settings (%s)', [FSettingsFilename]);
|
||||||
|
|
||||||
persistXML := TX2UtPersistXML.Create;
|
persistXML := TX2UtPersistXML.Create;
|
||||||
try
|
try
|
||||||
persistXML.FileName := FSettingsFileName;
|
persistXML.FileName := FSettingsFileName;
|
||||||
@ -500,17 +607,21 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.LoadActiveProfile;
|
procedure TMainForm.LoadActiveProfile;
|
||||||
var
|
var
|
||||||
|
activeProfile: TProfile;
|
||||||
buttonIndex: Integer;
|
buttonIndex: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not Assigned(ActiveProfile) then
|
activeProfile := TProfileManager.Instance.ActiveProfile;
|
||||||
|
if not Assigned(activeProfile) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
Debug.LogFmt('UI: Loading active profile (%s)', [activeProfile.Name]);
|
||||||
|
|
||||||
for buttonIndex := 0 to Pred(LED_COUNT) do
|
for buttonIndex := 0 to Pred(LED_COUNT) do
|
||||||
UpdateButton(ActiveProfile, buttonIndex);
|
UpdateButton(activeProfile, buttonIndex);
|
||||||
|
|
||||||
if Assigned(StateConsumerTask) then
|
if Assigned(StateConsumerTask) then
|
||||||
StateConsumerTask.Comm.Send(TM_LOADPROFILE, ActiveProfile);
|
StateConsumerTask.Comm.Send(TM_LOADPROFILE, activeProfile);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -549,9 +660,8 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.AddProfile(AProfile: TProfile);
|
procedure TMainForm.AddProfile(AProfile: TProfile);
|
||||||
begin
|
begin
|
||||||
Profiles.Add(AProfile);
|
|
||||||
cmbProfiles.Items.AddObject(AProfile.Name, AProfile);
|
cmbProfiles.Items.AddObject(AProfile.Name, AProfile);
|
||||||
SetActiveProfile(AProfile);
|
TProfileManager.Instance.Add(AProfile, True);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -581,27 +691,24 @@ var
|
|||||||
itemIndex: Integer;
|
itemIndex: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if AProfile = ActiveProfile then
|
|
||||||
FActiveProfile := nil;
|
|
||||||
|
|
||||||
itemIndex := cmbProfiles.Items.IndexOfObject(AProfile);
|
itemIndex := cmbProfiles.Items.IndexOfObject(AProfile);
|
||||||
if itemIndex > -1 then
|
if itemIndex > -1 then
|
||||||
begin
|
begin
|
||||||
Profiles.Remove(AProfile);
|
TProfileManager.Remove(AProfile);
|
||||||
cmbProfiles.Items.Delete(itemIndex);
|
cmbProfiles.Items.Delete(itemIndex);
|
||||||
|
|
||||||
if Profiles.Count = 0 then
|
if TProfileManager.Instance.Count = 0 then
|
||||||
AddProfile(CreateDefaultProfile);
|
AddProfile(CreateDefaultProfile);
|
||||||
|
|
||||||
if ASetActiveProfile then
|
if ASetActiveProfile then
|
||||||
begin
|
begin
|
||||||
if itemIndex >= Profiles.Count then
|
if itemIndex >= TProfileManager.Instance.Count then
|
||||||
itemIndex := Pred(Profiles.Count);
|
itemIndex := Pred(TProfileManager.Instance.Count);
|
||||||
|
|
||||||
FLockChangeProfile := True;
|
FLockChangeProfile := True;
|
||||||
try
|
try
|
||||||
cmbProfiles.ItemIndex := itemIndex;
|
cmbProfiles.ItemIndex := itemIndex;
|
||||||
SetActiveProfile(TProfile(cmbProfiles.Items.Objects[itemIndex]));
|
TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[itemIndex]);
|
||||||
finally
|
finally
|
||||||
FLockChangeProfile := False;
|
FLockChangeProfile := False;
|
||||||
end;
|
end;
|
||||||
@ -615,7 +722,7 @@ begin
|
|||||||
if not FLockChangeProfile then
|
if not FLockChangeProfile then
|
||||||
begin
|
begin
|
||||||
if cmbProfiles.ItemIndex > -1 then
|
if cmbProfiles.ItemIndex > -1 then
|
||||||
SetActiveProfile(TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]));
|
TProfileManager.Instance.ActiveProfile := TProfile(cmbProfiles.Items.Objects[cmbProfiles.ItemIndex]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -635,35 +742,28 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.SetActiveProfile(const Value: TProfile);
|
procedure TMainForm.ObserveActiveChanged(AProfile: TProfile);
|
||||||
begin
|
begin
|
||||||
if Value <> FActiveProfile then
|
{ This callback is not thread-safe }
|
||||||
begin
|
PostMessage(Self.Handle, CM_PROFILECHANGED, 0, 0);
|
||||||
FActiveProfile := Value;
|
end;
|
||||||
|
|
||||||
if Assigned(ActiveProfile) then
|
|
||||||
begin
|
|
||||||
if Settings.ActiveProfile <> ActiveProfile.Name then
|
|
||||||
begin
|
|
||||||
Settings.ActiveProfile := ActiveProfile.Name;
|
|
||||||
SaveSettings;
|
|
||||||
end;
|
|
||||||
|
|
||||||
FLockChangeProfile := True;
|
procedure TMainForm.ObserveAdd(AProfile: TProfile);
|
||||||
try
|
begin
|
||||||
cmbProfiles.ItemIndex := cmbProfiles.Items.IndexOfObject(ActiveProfile);
|
{ For now we'll assume we're the only one changing the profiles }
|
||||||
finally
|
end;
|
||||||
FLockChangeProfile := False;
|
|
||||||
end;
|
|
||||||
|
|
||||||
LoadActiveProfile;
|
|
||||||
end;
|
procedure TMainForm.ObserveRemove(AProfile: TProfile);
|
||||||
end;
|
begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.SetDeviceState(const AMessage: string; AFound: Boolean);
|
procedure TMainForm.SetDeviceState(const AMessage: string; AFound: Boolean);
|
||||||
begin
|
begin
|
||||||
|
Debug.LogFmt('UI: G940 Throttle state changed (found = %s, status = %s)', [BoolToStr(AFound, True), AMessage]);
|
||||||
|
|
||||||
lblG940ThrottleState.Caption := AMessage;
|
lblG940ThrottleState.Caption := AMessage;
|
||||||
lblG940ThrottleState.Update;
|
lblG940ThrottleState.Update;
|
||||||
|
|
||||||
@ -676,6 +776,8 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.SetFSXState(const AMessage: string; AConnected: Boolean);
|
procedure TMainForm.SetFSXState(const AMessage: string; AConnected: Boolean);
|
||||||
begin
|
begin
|
||||||
|
Debug.LogFmt('UI: FSX SimConnect state changed (connected = %s, status = %s)', [BoolToStr(AConnected, True), AMessage]);
|
||||||
|
|
||||||
lblFSXState.Caption := AMessage;
|
lblFSXState.Caption := AMessage;
|
||||||
lblFSXState.Update;
|
lblFSXState.Update;
|
||||||
|
|
||||||
@ -694,7 +796,7 @@ procedure TMainForm.LEDButtonClick(Sender: TObject);
|
|||||||
Result := AName;
|
Result := AName;
|
||||||
counter := 0;
|
counter := 0;
|
||||||
|
|
||||||
while Assigned(Profiles.Find(Result)) do
|
while Assigned(TProfileManager.Find(Result)) do
|
||||||
begin
|
begin
|
||||||
Inc(counter);
|
Inc(counter);
|
||||||
Result := Format('%s (%d)', [AName, counter]);
|
Result := Format('%s (%d)', [AName, counter]);
|
||||||
@ -703,27 +805,29 @@ procedure TMainForm.LEDButtonClick(Sender: TObject);
|
|||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
|
activeProfile: TProfile;
|
||||||
buttonIndex: NativeInt;
|
buttonIndex: NativeInt;
|
||||||
profile: TProfile;
|
profile: TProfile;
|
||||||
newProfile: Boolean;
|
newProfile: Boolean;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not Assigned(ActiveProfile) then
|
activeProfile := TProfileManager.Instance.ActiveProfile;
|
||||||
|
if not Assigned(activeProfile) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
{ Behaviour similar to the Windows System Sounds control panel;
|
{ Behaviour similar to the Windows System Sounds control panel;
|
||||||
when a change occurs, create a temporary profile "(modified)"
|
when a change occurs, create a temporary profile "(modified)"
|
||||||
so the original profile can still be selected }
|
so the original profile can still be selected }
|
||||||
if not ActiveProfile.IsTemporary then
|
if not activeProfile.IsTemporary then
|
||||||
begin
|
begin
|
||||||
profile := TProfile.Create;
|
profile := TProfile.Create;
|
||||||
profile.Assign(ActiveProfile);
|
profile.Assign(activeProfile);
|
||||||
profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified);
|
profile.Name := GetUniqueProfileName(profile.Name + ProfilePostfixModified);
|
||||||
profile.IsTemporary := True;
|
profile.IsTemporary := True;
|
||||||
newProfile := True;
|
newProfile := True;
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
profile := ActiveProfile;
|
profile := activeProfile;
|
||||||
newProfile := False;
|
newProfile := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -801,6 +905,9 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TMainForm.CheckForUpdatesThread(const ATask: IOmniTask);
|
procedure TMainForm.CheckForUpdatesThread(const ATask: IOmniTask);
|
||||||
|
const
|
||||||
|
UPDATE_URL = 'http://g940.x2software.net/version';
|
||||||
|
|
||||||
var
|
var
|
||||||
httpClient: TIdHTTP;
|
httpClient: TIdHTTP;
|
||||||
msgSent: Boolean;
|
msgSent: Boolean;
|
||||||
@ -809,9 +916,13 @@ var
|
|||||||
begin
|
begin
|
||||||
msgSent := False;
|
msgSent := False;
|
||||||
try
|
try
|
||||||
|
Debug.LogFmt('AutoUpdate: Checking for updates (%s)', [UPDATE_URL]);
|
||||||
|
|
||||||
httpClient := TIdHTTP.Create(nil);
|
httpClient := TIdHTTP.Create(nil);
|
||||||
try
|
try
|
||||||
latestVersion := httpClient.Get('http://g940.x2software.net/version');
|
latestVersion := httpClient.Get(UPDATE_URL);
|
||||||
|
Debug.LogFmt('AutoUpdate: Received version "%s"', [latestVersion]);
|
||||||
|
|
||||||
if VersionIsNewer(Format('%d.%d.%d', [App.Version.Major, App.Version.Minor, App.Version.Release]), latestVersion) then
|
if VersionIsNewer(Format('%d.%d.%d', [App.Version.Major, App.Version.Minor, App.Version.Release]), latestVersion) then
|
||||||
ATask.Comm.Send(TM_UPDATE, latestVersion)
|
ATask.Comm.Send(TM_UPDATE, latestVersion)
|
||||||
else
|
else
|
||||||
@ -844,13 +955,13 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
name := '';
|
name := '';
|
||||||
profile := ActiveProfile;
|
profile := TProfileManager.Instance.ActiveProfile;
|
||||||
existingProfile := nil;
|
existingProfile := nil;
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
if InputQuery('Save profile as', 'Save this profile as:', name) then
|
if InputQuery('Save profile as', 'Save this profile as:', name) then
|
||||||
begin
|
begin
|
||||||
existingProfile := Profiles.Find(name);
|
existingProfile := TProfileManager.Find(name);
|
||||||
if existingProfile = profile then
|
if existingProfile = profile then
|
||||||
existingProfile := nil;
|
existingProfile := nil;
|
||||||
|
|
||||||
@ -875,7 +986,7 @@ begin
|
|||||||
existingProfile.Assign(profile);
|
existingProfile.Assign(profile);
|
||||||
existingProfile.Name := name;
|
existingProfile.Name := name;
|
||||||
UpdateProfile(existingProfile);
|
UpdateProfile(existingProfile);
|
||||||
SetActiveProfile(existingProfile);
|
TProfileManager.Instance.ActiveProfile := existingProfile;
|
||||||
|
|
||||||
if profile.IsTemporary then
|
if profile.IsTemporary then
|
||||||
DeleteProfile(profile, False);
|
DeleteProfile(profile, False);
|
||||||
@ -900,13 +1011,17 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TMainForm.btnDeleteProfileClick(Sender: TObject);
|
procedure TMainForm.btnDeleteProfileClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
activeProfile: TProfile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if Assigned(ActiveProfile) then
|
activeProfile := TProfileManager.Instance.ActiveProfile;
|
||||||
|
if Assigned(activeProfile) then
|
||||||
begin
|
begin
|
||||||
if MessageBox(Self.Handle, PChar(Format('Do you want to remove the profile named "%s"?', [ActiveProfile.Name])),
|
if MessageBox(Self.Handle, PChar(Format('Do you want to remove the profile named "%s"?', [activeProfile.Name])),
|
||||||
'Remove profile', MB_ICONQUESTION or MB_YESNO) = ID_YES then
|
'Remove profile', MB_ICONQUESTION or MB_YESNO) = ID_YES then
|
||||||
begin
|
begin
|
||||||
DeleteProfile(ActiveProfile, True);
|
DeleteProfile(activeProfile, True);
|
||||||
SaveProfiles;
|
SaveProfiles;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -920,6 +1035,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.cbProfileMenuClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Settings.ProfileMenu := cbProfileMenu.Checked;
|
||||||
|
SaveSettings;
|
||||||
|
ApplyProfileMenuSettings;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.cbProfileMenuCascadedClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Settings.ProfileMenuCascaded := cbProfileMenuCascaded.Checked;
|
||||||
|
SaveSettings;
|
||||||
|
ApplyProfileMenuSettings;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.CheckForUpdates(AReportNoUpdates: Boolean);
|
procedure TMainForm.CheckForUpdates(AReportNoUpdates: Boolean);
|
||||||
begin
|
begin
|
||||||
btnCheckUpdates.Enabled := False;
|
btnCheckUpdates.Enabled := False;
|
||||||
@ -1001,6 +1132,26 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.ApplyProfileMenuSettings;
|
||||||
|
var
|
||||||
|
fsxProvider: IFSXLEDFunctionProvider;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Supports(TLEDFunctionRegistry.Find(FSXProviderUID), IFSXLEDFunctionProvider, fsxProvider) then
|
||||||
|
fsxProvider.SetProfileMenu(Settings.ProfileMenu, Settings.ProfileMenuCascaded);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.FinalizeProfileMenu;
|
||||||
|
var
|
||||||
|
fsxProvider: IFSXLEDFunctionProvider;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Supports(TLEDFunctionRegistry.Find(FSXProviderUID), IFSXLEDFunctionProvider, fsxProvider) then
|
||||||
|
fsxProvider.SetProfileMenu(False, False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TMainForm.btnCheckUpdatesClick(Sender: TObject);
|
procedure TMainForm.btnCheckUpdatesClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
CheckForUpdates(True);
|
CheckForUpdates(True);
|
||||||
|
@ -2,6 +2,7 @@ program G940LEDControl;
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Forms,
|
Forms,
|
||||||
|
SysUtils,
|
||||||
MainFrm in 'Forms\MainFrm.pas' {MainForm},
|
MainFrm in 'Forms\MainFrm.pas' {MainForm},
|
||||||
LogiJoystickDLL in '..\Shared\LogiJoystickDLL.pas',
|
LogiJoystickDLL in '..\Shared\LogiJoystickDLL.pas',
|
||||||
SimConnect in '..\Shared\SimConnect.pas',
|
SimConnect in '..\Shared\SimConnect.pas',
|
||||||
@ -30,7 +31,12 @@ uses
|
|||||||
LEDResources in 'Units\LEDResources.pas',
|
LEDResources in 'Units\LEDResources.pas',
|
||||||
Settings in 'Units\Settings.pas',
|
Settings in 'Units\Settings.pas',
|
||||||
FSXLEDFunctionWorker in 'Units\FSXLEDFunctionWorker.pas',
|
FSXLEDFunctionWorker in 'Units\FSXLEDFunctionWorker.pas',
|
||||||
FSXSimConnectStateMonitor in 'Units\FSXSimConnectStateMonitor.pas';
|
FSXSimConnectStateMonitor in 'Units\FSXSimConnectStateMonitor.pas',
|
||||||
|
ProfileManager in 'Units\ProfileManager.pas',
|
||||||
|
FSXLEDFunctionProviderIntf in 'Units\FSXLEDFunctionProviderIntf.pas',
|
||||||
|
GxDbugIntf in 'Units\GxDbugIntf.pas',
|
||||||
|
DebugLog in 'Units\DebugLog.pas',
|
||||||
|
DebugLogGExperts in 'Units\DebugLogGExperts.pas';
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
@ -39,6 +45,9 @@ var
|
|||||||
MainForm: TMainForm;
|
MainForm: TMainForm;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
if FindCmdLineSwitch('log') then
|
||||||
|
SetDebugLogConsumer(TGExpertsDebugLogConsumer.Create);
|
||||||
|
|
||||||
Application.Initialize;
|
Application.Initialize;
|
||||||
Application.MainFormOnTaskbar := True;
|
Application.MainFormOnTaskbar := True;
|
||||||
Application.Title := 'G940 LED Control';
|
Application.Title := 'G940 LED Control';
|
||||||
|
@ -82,10 +82,10 @@
|
|||||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||||
<VerInfo_Release>1</VerInfo_Release>
|
<VerInfo_Release>5</VerInfo_Release>
|
||||||
<VerInfo_MajorVer>1</VerInfo_MajorVer>
|
<VerInfo_MajorVer>1</VerInfo_MajorVer>
|
||||||
<VerInfo_MinorVer>0</VerInfo_MinorVer>
|
<VerInfo_MinorVer>0</VerInfo_MinorVer>
|
||||||
<VerInfo_Keys>CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=1.0.1.0;InternalName=;LegalCopyright=© 2011 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=1.0;Comments=</VerInfo_Keys>
|
<VerInfo_Keys>CompanyName=X²Software;FileDescription=G940 LED Control;FileVersion=1.0.5.0;InternalName=;LegalCopyright=© 2011 X²Software;LegalTrademarks=;OriginalFilename=G940LEDControl.exe;ProductName=G940 LED Control;ProductVersion=1.0;Comments=</VerInfo_Keys>
|
||||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -106,11 +106,68 @@
|
|||||||
<Manifest_File>F:\Components\X2Utils\Resources\VistaManAsInvoker.manifest</Manifest_File>
|
<Manifest_File>F:\Components\X2Utils\Resources\VistaManAsInvoker.manifest</Manifest_File>
|
||||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<DelphiCompile Include="$(MainSource)">
|
||||||
|
<MainSource>MainSource</MainSource>
|
||||||
|
</DelphiCompile>
|
||||||
|
<DCCReference Include="Forms\MainFrm.pas">
|
||||||
|
<Form>MainForm</Form>
|
||||||
|
</DCCReference>
|
||||||
|
<DCCReference Include="..\Shared\LogiJoystickDLL.pas"/>
|
||||||
|
<DCCReference Include="..\Shared\SimConnect.pas"/>
|
||||||
|
<DCCReference Include="Units\G940LEDStateConsumer.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDStateConsumer.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDColorIntf.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDColor.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDFunctionIntf.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDFunction.pas"/>
|
||||||
|
<DCCReference Include="Units\StaticLEDFunction.pas"/>
|
||||||
|
<DCCReference Include="Units\ConfigConversion.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDFunctionRegistry.pas"/>
|
||||||
|
<DCCReference Include="Units\StaticLEDColor.pas"/>
|
||||||
|
<DCCReference Include="Units\DynamicLEDColor.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDStateIntf.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDState.pas"/>
|
||||||
|
<DCCReference Include="Units\Profile.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDColorPool.pas"/>
|
||||||
|
<DCCReference Include="Forms\ButtonFunctionFrm.pas">
|
||||||
|
<Form>ButtonFunctionForm</Form>
|
||||||
|
</DCCReference>
|
||||||
|
<DCCReference Include="Units\FSXLEDFunctionProvider.pas"/>
|
||||||
|
<DCCReference Include="Units\StaticResources.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXResources.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXSimConnectClient.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXSimConnectIntf.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXLEDFunction.pas"/>
|
||||||
|
<DCCReference Include="Units\LEDResources.pas"/>
|
||||||
|
<DCCReference Include="Units\Settings.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXLEDFunctionWorker.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXSimConnectStateMonitor.pas"/>
|
||||||
|
<DCCReference Include="Units\ProfileManager.pas"/>
|
||||||
|
<DCCReference Include="Units\FSXLEDFunctionProviderIntf.pas"/>
|
||||||
|
<DCCReference Include="Units\GxDbugIntf.pas"/>
|
||||||
|
<DCCReference Include="Units\DebugLog.pas"/>
|
||||||
|
<DCCReference Include="Units\DebugLogGExperts.pas"/>
|
||||||
|
<BuildConfiguration Include="Debug">
|
||||||
|
<Key>Cfg_2</Key>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Base">
|
||||||
|
<Key>Base</Key>
|
||||||
|
</BuildConfiguration>
|
||||||
|
<BuildConfiguration Include="Release">
|
||||||
|
<Key>Cfg_1</Key>
|
||||||
|
<CfgParent>Base</CfgParent>
|
||||||
|
</BuildConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||||
<Borland.ProjectType/>
|
<Borland.ProjectType/>
|
||||||
<BorlandProject>
|
<BorlandProject>
|
||||||
<Delphi.Personality>
|
<Delphi.Personality>
|
||||||
|
<Source>
|
||||||
|
<Source Name="MainSource">G940LEDControl.dpr</Source>
|
||||||
|
</Source>
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<Parameters Name="UseLauncher">False</Parameters>
|
<Parameters Name="UseLauncher">False</Parameters>
|
||||||
<Parameters Name="LoadAllSymbols">True</Parameters>
|
<Parameters Name="LoadAllSymbols">True</Parameters>
|
||||||
@ -143,95 +200,7 @@
|
|||||||
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
|
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
|
||||||
<VersionInfoKeys Name="Comments"/>
|
<VersionInfoKeys Name="Comments"/>
|
||||||
</VersionInfoKeys>
|
</VersionInfoKeys>
|
||||||
<Source>
|
|
||||||
<Source Name="MainSource">G940LEDControl.dpr</Source>
|
|
||||||
</Source>
|
|
||||||
<Excluded_Packages>
|
<Excluded_Packages>
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxEditorFieldLinkD16.bpl">ExpressEditors FieldLink by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarDBNavD16.bpl">ExpressBars DBNavigator by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarExtDBItemsD16.bpl">ExpressBars extended DB items by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxBarExtItemsD16.bpl">ExpressBars extended items by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxTabbedMDID16.bpl">ExpressBars Tabbed MDI by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxLayoutControlD16.bpl">ExpressLayout Control by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxTreeListD16.bpl">ExpressQuantumTreeList 5 by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxGridD16.bpl">ExpressQuantumGrid by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxVerticalGridD16.bpl">ExpressVerticalGrid by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxmdsD16.bpl">ExpressMemData by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSpellCheckerD16.bpl">ExpressSpellChecker 2 by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxSpreadSheetD16.bpl">ExpressSpreadSheet by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxDockingD16.bpl">ExpressDocking Library by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxNavBarD16.bpl">ExpressNavBar by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinBlackD16.bpl">ExpressSkins - Black Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinBlueD16.bpl">ExpressSkins - Blue Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinBlueprintD16.bpl">ExpressSkins - Blueprint Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinCaramelD16.bpl">ExpressSkins - Caramel Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinCoffeeD16.bpl">ExpressSkins - Coffee Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDarkRoomD16.bpl">ExpressSkins - Darkroom Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDarkSideD16.bpl">ExpressSkins - DarkSide Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDevExpressDarkStyleD16.bpl">ExpressSkins - DevExpressDarkStyle Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinDevExpressStyleD16.bpl">ExpressSkins - DevExpressStyle Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinFoggyD16.bpl">ExpressSkins - Foggy Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinGlassOceansD16.bpl">ExpressSkins - GlassOceans Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinHighContrastD16.bpl">ExpressSkins - HighContrast Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkiniMaginaryD16.bpl">ExpressSkins - iMaginary Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinLilianD16.bpl">ExpressSkins - Lilian Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinLiquidSkyD16.bpl">ExpressSkins - LiquidSky Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinLondonLiquidSkyD16.bpl">ExpressSkins - LondonLiquidSky Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinMcSkinD16.bpl">ExpressSkins - McSkin Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinMoneyTwinsD16.bpl">ExpressSkins - MoneyTwins Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007BlackD16.bpl">ExpressSkins - Office2007Black Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007BlueD16.bpl">ExpressSkins - Office2007Blue Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007GreenD16.bpl">ExpressSkins - Office2007Green Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007PinkD16.bpl">ExpressSkins - Office2007Pink Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2007SilverD16.bpl">ExpressSkins - Office2007Silver Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2010BlackD16.bpl">ExpressSkins - Office2010Black Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2010BlueD16.bpl">ExpressSkins - Office2010Blue Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinOffice2010SilverD16.bpl">ExpressSkins - Office2010Silver Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinPumpkinD16.bpl">ExpressSkins - Pumpkin Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSevenClassicD16.bpl">ExpressSkins - SevenClassic Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSevenD16.bpl">ExpressSkins - Seven Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSharpD16.bpl">ExpressSkins - Sharp Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSharpPlusD16.bpl">ExpressSkins - SharpPlus Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSilverD16.bpl">ExpressSkins - Silver Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSpringTimeD16.bpl">ExpressSkins - Springtime Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinStardustD16.bpl">ExpressSkins - Stardust Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinSummer2008D16.bpl">ExpressSkins - Summer2008 Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinTheAsphaltWorldD16.bpl">ExpressSkins - TheAsphaltWorld Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinValentineD16.bpl">ExpressSkins - Valentine Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinVS2010D16.bpl">ExpressSkins - VS2010 Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinWhiteprintD16.bpl">ExpressSkins - Whiteprint Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxSkinXmas2008BlueD16.bpl">ExpressSkins - Xmas2008Blue Skin by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSLnksD16.bpl">ExpressPrinting System ReportLinks (Standard) by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dxPScxPCProdD16.bpl">ExpressPrinting System ContainerProducer for ExpressPageControl by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxdbtrD16.bpl">ExpressDBTree by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxtrmdD16.bpl">ExpressTreePrintedDataSet by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxDBOrD16.bpl">ExpressDBOrgChart by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxFlowChartD16.bpl">ExpressFlowChart by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPageControldxBarPopupMenuD16.bpl">ExpressPageControl dxBar Popup Menu by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxBarEditItemD16.bpl">ExpressBars cxEditor item by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxSchedulerGridD16.bpl">ExpressScheduler connection to ExpressQuantumGrid by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxTreeListdxBarPopupMenuD16.bpl">ExpressQuantumTreeList 5 dxBar Built-In Menu by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinscxEditorsHelperD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for ExpressEditors by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinscxPCPainterD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for PageControl Painter by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinscxSchedulerPainterD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for Scheduler Painter by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsdxBarsPaintersD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for Bars Painters by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsdxNavBarPainterD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for NavBar Painter by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxSkinsdxRibbonPaintersD16.bpl">ExpressSkins Library Uses Clause Auto Fill Helper for Ribbon Painters by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxCommonD16.bpl">ExpressPrinting System Cross Platform Library by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxExtCommonD16.bpl">ExpressPrinting System Extended Cross Platform Library by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxPivotGridLnkD16.bpl">ExpressPrinting System ReportLink for ExpressPivotGrid by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxSchedulerLnkD16.bpl">ExpressPrinting System ReportLink for ExpressScheduler by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxSSLnkD16.bpl">ExpressPrinting System ReportLink for ExpressSpreadSheet by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxTLLnkD16.bpl">ExpressPrinting System ReportLink for ExpressQuantumTreeList by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxVGridLnkD16.bpl">ExpressPrinting System ReportLink for ExpressVerticalGrid by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxDBOCLnkD16.bpl">ExpressPrinting System ReportLinks for ExpressDBOrgChart by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxDBTVLnkD16.bpl">ExpressPrinting System ReportLink for ExpressDBTree by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxFCLnkD16.bpl">ExpressPrinting System ReportLinks for ExpressFlowChart by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPScxGridLnkD16.bpl">ExpressPrinting System ReportLink for ExpressQuantumGrid by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSdxOCLnkD16.bpl">ExpressPrinting System ReportLinks for ExpressOrgChart by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSPrVwAdvD16.bpl">ExpressPrinting System Advanced Preview Window by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dcldxPSPrVwRibbonD16.bpl">ExpressPrinting System Ribbon Preview Window by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridChartD16.bpl">ExpressPivotGrid 2 connection to ExpressQuantumGrid Chart View by Developer Express Inc.</Excluded_Packages>
|
|
||||||
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridOLAPD16.bpl">ExpressPivotGrid 2 OLAP by Developer Express Inc.</Excluded_Packages>
|
<Excluded_Packages Name="D:\Program Files\Developer Express.VCL\Library\Delphi16\dclcxPivotGridOLAPD16.bpl">ExpressPivotGrid 2 OLAP by Developer Express Inc.</Excluded_Packages>
|
||||||
</Excluded_Packages>
|
</Excluded_Packages>
|
||||||
</Delphi.Personality>
|
</Delphi.Personality>
|
||||||
@ -243,55 +212,5 @@
|
|||||||
<ProjectFileVersion>12</ProjectFileVersion>
|
<ProjectFileVersion>12</ProjectFileVersion>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
|
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
|
||||||
<ItemGroup>
|
|
||||||
<DelphiCompile Include="$(MainSource)">
|
|
||||||
<MainSource>MainSource</MainSource>
|
|
||||||
</DelphiCompile>
|
|
||||||
<DCCReference Include="Forms\MainFrm.pas">
|
|
||||||
<Form>MainForm</Form>
|
|
||||||
</DCCReference>
|
|
||||||
<DCCReference Include="..\Shared\LogiJoystickDLL.pas"/>
|
|
||||||
<DCCReference Include="..\Shared\SimConnect.pas"/>
|
|
||||||
<DCCReference Include="Units\G940LEDStateConsumer.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDStateConsumer.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDColorIntf.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDColor.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDFunctionIntf.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDFunction.pas"/>
|
|
||||||
<DCCReference Include="Units\StaticLEDFunction.pas"/>
|
|
||||||
<DCCReference Include="Units\ConfigConversion.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDFunctionRegistry.pas"/>
|
|
||||||
<DCCReference Include="Units\StaticLEDColor.pas"/>
|
|
||||||
<DCCReference Include="Units\DynamicLEDColor.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDStateIntf.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDState.pas"/>
|
|
||||||
<DCCReference Include="Units\Profile.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDColorPool.pas"/>
|
|
||||||
<DCCReference Include="Forms\ButtonFunctionFrm.pas">
|
|
||||||
<Form>ButtonFunctionForm</Form>
|
|
||||||
<FormType>dfm</FormType>
|
|
||||||
</DCCReference>
|
|
||||||
<DCCReference Include="Units\FSXLEDFunctionProvider.pas"/>
|
|
||||||
<DCCReference Include="Units\StaticResources.pas"/>
|
|
||||||
<DCCReference Include="Units\FSXResources.pas"/>
|
|
||||||
<DCCReference Include="Units\FSXSimConnectClient.pas"/>
|
|
||||||
<DCCReference Include="Units\FSXSimConnectIntf.pas"/>
|
|
||||||
<DCCReference Include="Units\FSXLEDFunction.pas"/>
|
|
||||||
<DCCReference Include="Units\LEDResources.pas"/>
|
|
||||||
<DCCReference Include="Units\Settings.pas"/>
|
|
||||||
<DCCReference Include="Units\FSXLEDFunctionWorker.pas"/>
|
|
||||||
<DCCReference Include="Units\FSXSimConnectStateMonitor.pas"/>
|
|
||||||
<BuildConfiguration Include="Debug">
|
|
||||||
<Key>Cfg_2</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
<BuildConfiguration Include="Base">
|
|
||||||
<Key>Base</Key>
|
|
||||||
</BuildConfiguration>
|
|
||||||
<BuildConfiguration Include="Release">
|
|
||||||
<Key>Cfg_1</Key>
|
|
||||||
<CfgParent>Base</CfgParent>
|
|
||||||
</BuildConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
|
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
|
||||||
</Project>
|
</Project>
|
||||||
|
Binary file not shown.
173
G940LEDControl/Units/DebugLog.pas
Normal file
173
G940LEDControl/Units/DebugLog.pas
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
unit DebugLog;
|
||||||
|
|
||||||
|
interface
|
||||||
|
type
|
||||||
|
TCustomDebugLogConsumer = class(TObject)
|
||||||
|
public
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: Boolean); overload; virtual; abstract;
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: TDateTime); overload; virtual; abstract;
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: Integer); overload; virtual; abstract;
|
||||||
|
|
||||||
|
procedure Log(const AMsg: string); virtual; abstract;
|
||||||
|
procedure LogFmt(const AMsg: string; const AArgs: array of const); virtual; abstract;
|
||||||
|
|
||||||
|
procedure LogWarning(const AMsg: string); virtual; abstract;
|
||||||
|
procedure LogWarningFmt(const AMsg: string; const AArgs: array of const); virtual; abstract;
|
||||||
|
|
||||||
|
procedure LogError(const AMsg: string); virtual; abstract;
|
||||||
|
procedure LogErrorFmt(const AMsg: string; const AArgs: array of const); virtual; abstract;
|
||||||
|
|
||||||
|
procedure LogMethodEnter(const AMethodName: string); virtual; abstract;
|
||||||
|
procedure LogMethodExit(const AMethodName: string); virtual; abstract;
|
||||||
|
|
||||||
|
procedure Indent; virtual; abstract;
|
||||||
|
procedure UnIndent; virtual; abstract;
|
||||||
|
procedure Separator; virtual; abstract;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure SetDebugLogConsumer(AConsumer: TCustomDebugLogConsumer);
|
||||||
|
procedure ClearDebugLogConsumer;
|
||||||
|
|
||||||
|
function Debug: TCustomDebugLogConsumer;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
uses
|
||||||
|
SysUtils;
|
||||||
|
|
||||||
|
|
||||||
|
var
|
||||||
|
DebugLogConsumer: TCustomDebugLogConsumer;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TNullDebugLogConsumer = class(TCustomDebugLogConsumer)
|
||||||
|
public
|
||||||
|
procedure Log(const AMsg: string); override;
|
||||||
|
procedure LogFmt(const AMsg: string; const AArgs: array of const); override;
|
||||||
|
|
||||||
|
procedure LogWarning(const AMsg: string); override;
|
||||||
|
procedure LogWarningFmt(const AMsg: string; const AArgs: array of const); override;
|
||||||
|
|
||||||
|
procedure LogError(const AMsg: string); override;
|
||||||
|
procedure LogErrorFmt(const AMsg: string; const AArgs: array of const); override;
|
||||||
|
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: Boolean); overload; override;
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: TDateTime); overload; override;
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: Integer); overload; override;
|
||||||
|
|
||||||
|
procedure LogMethodEnter(const AMethodName: string); override;
|
||||||
|
procedure LogMethodExit(const AMethodName: string); override;
|
||||||
|
|
||||||
|
procedure Indent; override;
|
||||||
|
procedure UnIndent; override;
|
||||||
|
procedure Separator; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure SetDebugLogConsumer(AConsumer: TCustomDebugLogConsumer);
|
||||||
|
begin
|
||||||
|
if (not Assigned(DebugLogConsumer)) or (AConsumer <> DebugLogConsumer) then
|
||||||
|
begin
|
||||||
|
FreeAndNil(DebugLogConsumer);
|
||||||
|
|
||||||
|
if Assigned(AConsumer) then
|
||||||
|
DebugLogConsumer := AConsumer
|
||||||
|
else
|
||||||
|
DebugLogConsumer := TNullDebugLogConsumer.Create;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ClearDebugLogConsumer;
|
||||||
|
begin
|
||||||
|
SetDebugLogConsumer(nil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Debug: TCustomDebugLogConsumer;
|
||||||
|
begin
|
||||||
|
Result := DebugLogConsumer;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TNullDebugLogConsumer }
|
||||||
|
procedure TNullDebugLogConsumer.Log(const AMsg: string);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogFmt(const AMsg: string; const AArgs: array of const);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogWarning(const AMsg: string);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogWarningFmt(const AMsg: string; const AArgs: array of const);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogError(const AMsg: string);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogErrorFmt(const AMsg: string; const AArgs: array of const);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogValue(const AIdentifier: string; const AValue: Boolean);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogValue(const AIdentifier: string; const AValue: TDateTime);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogValue(const AIdentifier: string; const AValue: Integer);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogMethodEnter(const AMethodName: string);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.LogMethodExit(const AMethodName: string);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.Indent;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.UnIndent;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TNullDebugLogConsumer.Separator;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
initialization
|
||||||
|
ClearDebugLogConsumer;
|
||||||
|
|
||||||
|
finalization
|
||||||
|
FreeAndNil(DebugLogConsumer);
|
||||||
|
|
||||||
|
end.
|
137
G940LEDControl/Units/DebugLogGExperts.pas
Normal file
137
G940LEDControl/Units/DebugLogGExperts.pas
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
unit DebugLogGExperts;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
DebugLog;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
TGExpertsDebugLogConsumer = class(TCustomDebugLogConsumer)
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
|
||||||
|
procedure Log(const AMsg: string); override;
|
||||||
|
procedure LogFmt(const AMsg: string; const AArgs: array of const); override;
|
||||||
|
|
||||||
|
procedure LogWarning(const AMsg: string); override;
|
||||||
|
procedure LogWarningFmt(const AMsg: string; const AArgs: array of const); override;
|
||||||
|
|
||||||
|
procedure LogError(const AMsg: string); override;
|
||||||
|
procedure LogErrorFmt(const AMsg: string; const AArgs: array of const); override;
|
||||||
|
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: Boolean); overload; override;
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: TDateTime); overload; override;
|
||||||
|
procedure LogValue(const AIdentifier: string; const AValue: Integer); overload; override;
|
||||||
|
|
||||||
|
procedure LogMethodEnter(const AMethodName: string); override;
|
||||||
|
procedure LogMethodExit(const AMethodName: string); override;
|
||||||
|
|
||||||
|
procedure Indent; override;
|
||||||
|
procedure UnIndent; override;
|
||||||
|
procedure Separator; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
uses
|
||||||
|
Dialogs,
|
||||||
|
SysUtils,
|
||||||
|
|
||||||
|
GxDbugIntf;
|
||||||
|
|
||||||
|
|
||||||
|
{ TGExpertsDebugLogConsumer }
|
||||||
|
constructor TGExpertsDebugLogConsumer.Create;
|
||||||
|
begin
|
||||||
|
if StartDebugWin = 0 then
|
||||||
|
raise Exception.Create('Debug log not available; is GExpertsDebugWindow.exe present?');
|
||||||
|
|
||||||
|
Log('G940 LED Control log initialized');
|
||||||
|
Separator;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.Log(const AMsg: string);
|
||||||
|
begin
|
||||||
|
SendDebug(AMsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogFmt(const AMsg: string; const AArgs: array of const);
|
||||||
|
begin
|
||||||
|
SendDebugFmt(AMsg, AArgs);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogWarning(const AMsg: string);
|
||||||
|
begin
|
||||||
|
SendDebugWarning(AMsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogWarningFmt(const AMsg: string; const AArgs: array of const);
|
||||||
|
begin
|
||||||
|
SendDebugFmtEx(AMsg, AArgs, mtWarning);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogError(const AMsg: string);
|
||||||
|
begin
|
||||||
|
SendDebug(AMsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogErrorFmt(const AMsg: string; const AArgs: array of const);
|
||||||
|
begin
|
||||||
|
SendDebugFmtEx(AMsg, AArgs, mtError);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogValue(const AIdentifier: string; const AValue: Boolean);
|
||||||
|
begin
|
||||||
|
SendBoolean(AIdentifier, AValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogValue(const AIdentifier: string; const AValue: TDateTime);
|
||||||
|
begin
|
||||||
|
SendDateTime(AIdentifier, AValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogValue(const AIdentifier: string; const AValue: Integer);
|
||||||
|
begin
|
||||||
|
SendInteger(AIdentifier, AValue);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogMethodEnter(const AMethodName: string);
|
||||||
|
begin
|
||||||
|
SendMethodEnter(AMethodName);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.LogMethodExit(const AMethodName: string);
|
||||||
|
begin
|
||||||
|
SendMethodExit(AMethodName);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.Indent;
|
||||||
|
begin
|
||||||
|
SendIndent;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.UnIndent;
|
||||||
|
begin
|
||||||
|
SendUnIndent;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TGExpertsDebugLogConsumer.Separator;
|
||||||
|
begin
|
||||||
|
SendSeparator;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
@ -145,6 +145,13 @@ type
|
|||||||
function GetLightMask: Integer; override;
|
function GetLightMask: Integer; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TFSXAllLightsFunction = class(TCustomFSXFunction)
|
||||||
|
protected
|
||||||
|
procedure RegisterStates; override;
|
||||||
|
function GetCategoryName: string; override;
|
||||||
|
function GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Autopilot }
|
{ Autopilot }
|
||||||
TCustomFSXAutoPilotFunction = class(TCustomFSXFunction)
|
TCustomFSXAutoPilotFunction = class(TCustomFSXFunction)
|
||||||
@ -483,6 +490,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TFSXAllLightsFunction }
|
||||||
|
procedure TFSXAllLightsFunction.RegisterStates;
|
||||||
|
begin
|
||||||
|
RegisterState(TLEDState.Create(FSXStateUIDOn, FSXStateDisplayNameOn, lcGreen));
|
||||||
|
RegisterState(TLEDState.Create(FSXStateUIDPartial, FSXStateDisplayNamePartial, lcAmber));
|
||||||
|
RegisterState(TLEDState.Create(FSXStateUIDOff, FSXStateDisplayNameOff, lcRed));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TFSXAllLightsFunction.GetCategoryName: string;
|
||||||
|
begin
|
||||||
|
Result := FSXCategoryLights;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TFSXAllLightsFunction.GetWorkerClass: TCustomLEDMultiStateFunctionWorkerClass;
|
||||||
|
begin
|
||||||
|
Result := TFSXAllLightsFunctionWorker;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TCustomFSXAutoPilotFunction }
|
{ TCustomFSXAutoPilotFunction }
|
||||||
function TCustomFSXAutoPilotFunction.GetCategoryName: string;
|
function TCustomFSXAutoPilotFunction.GetCategoryName: string;
|
||||||
begin
|
begin
|
||||||
|
@ -5,6 +5,7 @@ uses
|
|||||||
Generics.Collections,
|
Generics.Collections,
|
||||||
System.SyncObjs,
|
System.SyncObjs,
|
||||||
|
|
||||||
|
FSXLEDFunctionProviderIntf,
|
||||||
FSXSimConnectIntf,
|
FSXSimConnectIntf,
|
||||||
LEDFunction,
|
LEDFunction,
|
||||||
LEDFunctionIntf,
|
LEDFunctionIntf,
|
||||||
@ -16,10 +17,11 @@ type
|
|||||||
TCustomFSXFunctionList = TObjectList<TCustomFSXFunction>;
|
TCustomFSXFunctionList = TObjectList<TCustomFSXFunction>;
|
||||||
|
|
||||||
|
|
||||||
TFSXLEDFunctionProvider = class(TCustomLEDFunctionProvider, IFSXSimConnectObserver)
|
TFSXLEDFunctionProvider = class(TCustomLEDFunctionProvider, IFSXLEDFunctionProvider, IFSXSimConnectObserver)
|
||||||
private
|
private
|
||||||
FSimConnect: TInterfacedObject;
|
FSimConnect: TInterfacedObject;
|
||||||
FSimConnectLock: TCriticalSection;
|
FSimConnectLock: TCriticalSection;
|
||||||
|
FProfileMenuSimConnect: IFSXSimConnectProfileMenu;
|
||||||
protected
|
protected
|
||||||
procedure RegisterFunctions; override;
|
procedure RegisterFunctions; override;
|
||||||
|
|
||||||
@ -27,6 +29,9 @@ type
|
|||||||
protected
|
protected
|
||||||
{ IFSXSimConnectObserver }
|
{ IFSXSimConnectObserver }
|
||||||
procedure ObserveDestroy(Sender: IFSXSimConnect);
|
procedure ObserveDestroy(Sender: IFSXSimConnect);
|
||||||
|
|
||||||
|
{ IFSXLEDFunctionProvider }
|
||||||
|
procedure SetProfileMenu(AEnabled: Boolean; ACascaded: Boolean);
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -147,6 +152,7 @@ begin
|
|||||||
RegisterFunction(TFSXRecognitionLightsFunction.Create( Self, FSXFunctionDisplayNameRecognitionLights, FSXFunctionUIDRecognitionLights));
|
RegisterFunction(TFSXRecognitionLightsFunction.Create( Self, FSXFunctionDisplayNameRecognitionLights, FSXFunctionUIDRecognitionLights));
|
||||||
RegisterFunction(TFSXStrobeLightsFunction.Create( Self, FSXFunctionDisplayNameStrobeLights, FSXFunctionUIDStrobeLights));
|
RegisterFunction(TFSXStrobeLightsFunction.Create( Self, FSXFunctionDisplayNameStrobeLights, FSXFunctionUIDStrobeLights));
|
||||||
RegisterFunction(TFSXTaxiLightsFunction.Create( Self, FSXFunctionDisplayNameTaxiLights, FSXFunctionUIDTaxiLights));
|
RegisterFunction(TFSXTaxiLightsFunction.Create( Self, FSXFunctionDisplayNameTaxiLights, FSXFunctionUIDTaxiLights));
|
||||||
|
RegisterFunction(TFSXAllLightsFunction.Create( Self, FSXFunctionDisplayNameAllLights, FSXFunctionUIDAllLights));
|
||||||
|
|
||||||
{ Autopilot }
|
{ Autopilot }
|
||||||
RegisterFunction(TFSXAutoPilotFunction.Create( Self, FSXFunctionDisplayNameAutoPilot, FSXFunctionUIDAutoPilot));
|
RegisterFunction(TFSXAutoPilotFunction.Create( Self, FSXFunctionDisplayNameAutoPilot, FSXFunctionUIDAutoPilot));
|
||||||
@ -197,6 +203,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXLEDFunctionProvider.SetProfileMenu(AEnabled: Boolean; ACascaded: Boolean);
|
||||||
|
begin
|
||||||
|
if AEnabled and (not Assigned(FProfileMenuSimConnect)) then
|
||||||
|
FProfileMenuSimConnect := (GetSimConnect as IFSXSimConnectProfileMenu);
|
||||||
|
|
||||||
|
if Assigned(FProfileMenuSimConnect) then
|
||||||
|
FProfileMenuSimConnect.SetProfileMenu(AEnabled, ACascaded);
|
||||||
|
|
||||||
|
if not AEnabled then
|
||||||
|
FProfileMenuSimConnect := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ TCustomFSXFunction }
|
{ TCustomFSXFunction }
|
||||||
constructor TCustomFSXFunction.Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string);
|
constructor TCustomFSXFunction.Create(AProvider: TFSXLEDFunctionProvider; const ADisplayName, AUID: string);
|
||||||
begin
|
begin
|
||||||
|
13
G940LEDControl/Units/FSXLEDFunctionProviderIntf.pas
Normal file
13
G940LEDControl/Units/FSXLEDFunctionProviderIntf.pas
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
unit FSXLEDFunctionProviderIntf;
|
||||||
|
|
||||||
|
interface
|
||||||
|
type
|
||||||
|
IFSXLEDFunctionProvider = interface
|
||||||
|
['{F13C936C-32C3-4204-A5E9-3AE6604AA31C}']
|
||||||
|
procedure SetProfileMenu(AEnabled, ACascaded: Boolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
end.
|
@ -91,6 +91,13 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TFSXAllLightsFunctionWorker = class(TCustomFSXFunctionWorker)
|
||||||
|
protected
|
||||||
|
procedure RegisterVariables(ADefinition: IFSXSimConnectDefinition); override;
|
||||||
|
procedure HandleData(AData: Pointer); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ Autopilot }
|
{ Autopilot }
|
||||||
PAutoPilotData = ^TAutoPilotData;
|
PAutoPilotData = ^TAutoPilotData;
|
||||||
TAutoPilotData = packed record
|
TAutoPilotData = packed record
|
||||||
@ -533,6 +540,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TFSXAllLightsFunctionWorker }
|
||||||
|
procedure TFSXAllLightsFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
|
||||||
|
begin
|
||||||
|
ADefinition.AddVariable('LIGHT ON STATES', FSX_UNIT_MASK, SIMCONNECT_DATATYPE_INT32);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXAllLightsFunctionWorker.HandleData(AData: Pointer);
|
||||||
|
begin
|
||||||
|
if PCardinal(AData)^ = FSX_LIGHTON_ALL then
|
||||||
|
SetCurrentState(FSXStateUIDOn)
|
||||||
|
else if PCardinal(AData)^ > 0 then
|
||||||
|
SetCurrentState(FSXStateUIDPartial)
|
||||||
|
else
|
||||||
|
SetCurrentState(FSXStateUIDOff);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TCustomFSXAutoPilotFunctionWorker }
|
{ TCustomFSXAutoPilotFunctionWorker }
|
||||||
procedure TCustomFSXAutoPilotFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
|
procedure TCustomFSXAutoPilotFunctionWorker.RegisterVariables(ADefinition: IFSXSimConnectDefinition);
|
||||||
begin
|
begin
|
||||||
|
@ -15,9 +15,11 @@ const
|
|||||||
|
|
||||||
FSXStateUIDOn = 'on';
|
FSXStateUIDOn = 'on';
|
||||||
FSXStateUIDOff = 'off';
|
FSXStateUIDOff = 'off';
|
||||||
|
FSXStateUIDPartial = 'partial';
|
||||||
|
|
||||||
FSXStateDisplayNameOn = 'On';
|
FSXStateDisplayNameOn = 'On';
|
||||||
FSXStateDisplayNameOff = 'Off';
|
FSXStateDisplayNameOff = 'Off';
|
||||||
|
FSXStateDisplayNamePartial = 'Partial';
|
||||||
|
|
||||||
|
|
||||||
FSXFunctionUIDEngine = 'engine';
|
FSXFunctionUIDEngine = 'engine';
|
||||||
@ -77,6 +79,9 @@ const
|
|||||||
FSXFunctionUIDRecognitionLights = 'recognitionLights';
|
FSXFunctionUIDRecognitionLights = 'recognitionLights';
|
||||||
FSXFunctionDisplayNameRecognitionLights = 'Recognition lights';
|
FSXFunctionDisplayNameRecognitionLights = 'Recognition lights';
|
||||||
|
|
||||||
|
FSXFunctionUIDAllLights = 'allLights';
|
||||||
|
FSXFunctionDisplayNameAllLights = 'All lights';
|
||||||
|
|
||||||
|
|
||||||
FSXFunctionUIDParkingBrake = 'parkingBrake';
|
FSXFunctionUIDParkingBrake = 'parkingBrake';
|
||||||
FSXFunctionDisplayNameParkingBrake = 'Parking brake';
|
FSXFunctionDisplayNameParkingBrake = 'Parking brake';
|
||||||
@ -190,6 +195,10 @@ const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FSXMenuProfiles = 'G940 Profile';
|
||||||
|
FSXMenuProfileFormat = 'G940: %s';
|
||||||
|
FSXMenuProfileFormatCascaded = '%s';
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
unit FSXSimConnectClient;
|
unit FSXSimConnectClient;
|
||||||
|
|
||||||
|
// Determines if a Win32 event will be used to wait for new
|
||||||
|
// messages instead of the old 0.x method of polling via a timer.
|
||||||
|
{$DEFINE SCUSEEVENT}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
uses
|
uses
|
||||||
Classes,
|
Classes,
|
||||||
|
|
||||||
OtlTaskControl,
|
OtlTaskControl,
|
||||||
|
|
||||||
FSXSimConnectIntf;
|
FSXSimConnectIntf,
|
||||||
|
Profile,
|
||||||
|
ProfileManager;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TFSXSimConnectInterface = class(TInterfacedObject, IFSXSimConnect)
|
TFSXSimConnectInterface = class(TInterfacedObject, IFSXSimConnect, IFSXSimConnectProfileMenu, IProfileObserver)
|
||||||
private
|
private
|
||||||
FClient: IOmniTaskControl;
|
FClient: IOmniTaskControl;
|
||||||
FObservers: TInterfaceList;
|
FObservers: TInterfaceList;
|
||||||
|
|
||||||
|
FObservingProfileManager: Boolean;
|
||||||
protected
|
protected
|
||||||
property Client: IOmniTaskControl read FClient;
|
property Client: IOmniTaskControl read FClient;
|
||||||
property Observers: TInterfaceList read FObservers;
|
property Observers: TInterfaceList read FObservers;
|
||||||
@ -25,6 +33,14 @@ type
|
|||||||
function CreateDefinition: IFSXSimConnectDefinition;
|
function CreateDefinition: IFSXSimConnectDefinition;
|
||||||
function AddDefinition(ADefinition: IFSXSimConnectDefinition; ADataHandler: IFSXSimConnectDataHandler): Integer;
|
function AddDefinition(ADefinition: IFSXSimConnectDefinition; ADataHandler: IFSXSimConnectDataHandler): Integer;
|
||||||
procedure RemoveDefinition(ADefinitionID: Cardinal; ADataHandler: IFSXSimConnectDataHandler);
|
procedure RemoveDefinition(ADefinitionID: Cardinal; ADataHandler: IFSXSimConnectDataHandler);
|
||||||
|
|
||||||
|
{ IFSXSimConnectProfileMenu }
|
||||||
|
procedure SetProfileMenu(AEnabled, ACascaded: Boolean);
|
||||||
|
|
||||||
|
{ IProfileObserver }
|
||||||
|
procedure ObserveAdd(AProfile: TProfile);
|
||||||
|
procedure ObserveRemove(AProfile: TProfile);
|
||||||
|
procedure ObserveActiveChanged(AProfile: TProfile);
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -43,6 +59,7 @@ uses
|
|||||||
OtlCommon,
|
OtlCommon,
|
||||||
SimConnect,
|
SimConnect,
|
||||||
|
|
||||||
|
DebugLog,
|
||||||
FSXResources,
|
FSXResources,
|
||||||
FSXSimConnectStateMonitor;
|
FSXSimConnectStateMonitor;
|
||||||
|
|
||||||
@ -52,12 +69,16 @@ const
|
|||||||
TM_REMOVEDEFINITION = 3002;
|
TM_REMOVEDEFINITION = 3002;
|
||||||
TM_TRYSIMCONNECT = 3003;
|
TM_TRYSIMCONNECT = 3003;
|
||||||
TM_PROCESSMESSAGES = 3004;
|
TM_PROCESSMESSAGES = 3004;
|
||||||
|
TM_SETPROFILEMENU = 3005;
|
||||||
|
TM_UPDATEPROFILEMENU = 3006;
|
||||||
|
|
||||||
TIMER_TRYSIMCONNECT = 201;
|
TIMER_TRYSIMCONNECT = 201;
|
||||||
TIMER_PROCESSMESSAGES = 202;
|
|
||||||
|
|
||||||
INTERVAL_TRYSIMCONNECT = 5000;
|
INTERVAL_TRYSIMCONNECT = 5000;
|
||||||
|
|
||||||
|
{$IFNDEF SCUSEEVENT}
|
||||||
|
TIMER_PROCESSMESSAGES = 202;
|
||||||
INTERVAL_PROCESSMESSAGES = 50;
|
INTERVAL_PROCESSMESSAGES = 50;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -71,7 +92,7 @@ type
|
|||||||
constructor Create(ADefinition: IFSXSimConnectDefinitionAccess);
|
constructor Create(ADefinition: IFSXSimConnectDefinitionAccess);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
procedure Attach(ADataHandler: IFSXSimConnectDataHandler);
|
function Attach(ADataHandler: IFSXSimConnectDataHandler): Integer;
|
||||||
function Detach(ADataHandler: IFSXSimConnectDataHandler): Integer;
|
function Detach(ADataHandler: IFSXSimConnectDataHandler): Integer;
|
||||||
|
|
||||||
procedure HandleData(AData: Pointer);
|
procedure HandleData(AData: Pointer);
|
||||||
@ -90,14 +111,27 @@ type
|
|||||||
FDefinitions: TFSXSimConnectDefinitionMap;
|
FDefinitions: TFSXSimConnectDefinitionMap;
|
||||||
FLastDefinitionID: Cardinal;
|
FLastDefinitionID: Cardinal;
|
||||||
FSimConnectHandle: THandle;
|
FSimConnectHandle: THandle;
|
||||||
// FSimConnectDataEvent: TEvent;
|
{$IFDEF SCUSEEVENT}
|
||||||
|
FSimConnectDataEvent: TEvent;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
FProfileMenu: Boolean;
|
||||||
|
FProfileMenuCascaded: Boolean;
|
||||||
|
|
||||||
|
FMenuProfiles: TStringList;
|
||||||
|
FMenuWasCascaded: Boolean;
|
||||||
protected
|
protected
|
||||||
procedure TMAddDefinition(var Msg: TOmniMessage); message TM_ADDDEFINITION;
|
procedure TMAddDefinition(var Msg: TOmniMessage); message TM_ADDDEFINITION;
|
||||||
procedure TMRemoveDefinition(var Msg: TOmniMessage); message TM_REMOVEDEFINITION;
|
procedure TMRemoveDefinition(var Msg: TOmniMessage); message TM_REMOVEDEFINITION;
|
||||||
procedure TMTrySimConnect(var Msg: TOmniMessage); message TM_TRYSIMCONNECT;
|
procedure TMTrySimConnect(var Msg: TOmniMessage); message TM_TRYSIMCONNECT;
|
||||||
|
{$IFNDEF SCUSEEVENT}
|
||||||
procedure TMProcessMessages(var Msg: TOmniMessage); message TM_PROCESSMESSAGES;
|
procedure TMProcessMessages(var Msg: TOmniMessage); message TM_PROCESSMESSAGES;
|
||||||
|
{$ENDIF}
|
||||||
|
procedure TMSetProfileMenu(var Msg: TOmniMessage); message TM_SETPROFILEMENU;
|
||||||
|
procedure TMUpdateProfileMenu(var Msg: TOmniMessage); message TM_UPDATEPROFILEMENU;
|
||||||
|
|
||||||
procedure HandleSimConnectDataEvent;
|
procedure HandleSimConnectDataEvent;
|
||||||
|
procedure HandleEvent(AEventID: Integer);
|
||||||
protected
|
protected
|
||||||
function Initialize: Boolean; override;
|
function Initialize: Boolean; override;
|
||||||
procedure Cleanup; override;
|
procedure Cleanup; override;
|
||||||
@ -111,10 +145,17 @@ type
|
|||||||
|
|
||||||
function SameDefinition(ADefinition1, ADefinition2: IFSXSimConnectDefinitionAccess): Boolean;
|
function SameDefinition(ADefinition1, ADefinition2: IFSXSimConnectDefinitionAccess): Boolean;
|
||||||
|
|
||||||
|
procedure UpdateProfileMenu;
|
||||||
|
|
||||||
property Definitions: TFSXSimConnectDefinitionMap read FDefinitions;
|
property Definitions: TFSXSimConnectDefinitionMap read FDefinitions;
|
||||||
property LastDefinitionID: Cardinal read FLastDefinitionID;
|
property LastDefinitionID: Cardinal read FLastDefinitionID;
|
||||||
property SimConnectHandle: THandle read FSimConnectHandle;
|
property SimConnectHandle: THandle read FSimConnectHandle;
|
||||||
// property SimConnectDataEvent: TEvent read FSimConnectDataEvent;
|
{$IFDEF SCUSEEVENT}
|
||||||
|
property SimConnectDataEvent: TEvent read FSimConnectDataEvent;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
property ProfileMenu: Boolean read FProfileMenu;
|
||||||
|
property ProfileMenuCascaded: Boolean read FProfileMenuCascaded;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -263,6 +304,40 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectInterface.SetProfileMenu(AEnabled, ACascaded: Boolean);
|
||||||
|
begin
|
||||||
|
Client.Comm.Send(TM_SETPROFILEMENU, [AEnabled, ACascaded]);
|
||||||
|
|
||||||
|
if AEnabled <> FObservingProfileManager then
|
||||||
|
begin
|
||||||
|
if AEnabled then
|
||||||
|
TProfileManager.Attach(Self)
|
||||||
|
else
|
||||||
|
TProfileManager.Detach(Self);
|
||||||
|
|
||||||
|
FObservingProfileManager := AEnabled;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectInterface.ObserveAdd(AProfile: TProfile);
|
||||||
|
begin
|
||||||
|
Client.Comm.Send(TM_UPDATEPROFILEMENU);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectInterface.ObserveRemove(AProfile: TProfile);
|
||||||
|
begin
|
||||||
|
Client.Comm.Send(TM_UPDATEPROFILEMENU);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectInterface.ObserveActiveChanged(AProfile: TProfile);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ TFSXSimConnectDefinition }
|
{ TFSXSimConnectDefinition }
|
||||||
constructor TFSXSimConnectDefinition.Create;
|
constructor TFSXSimConnectDefinition.Create;
|
||||||
begin
|
begin
|
||||||
@ -301,14 +376,19 @@ end;
|
|||||||
{ TFSXSimConnectClient }
|
{ TFSXSimConnectClient }
|
||||||
function TFSXSimConnectClient.Initialize: Boolean;
|
function TFSXSimConnectClient.Initialize: Boolean;
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('FSX SimConnect: Initializing');
|
||||||
|
|
||||||
Result := inherited Initialize;
|
Result := inherited Initialize;
|
||||||
if not Result then
|
if not Result then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
FDefinitions := TFSXSimConnectDefinitionMap.Create;
|
FDefinitions := TFSXSimConnectDefinitionMap.Create;
|
||||||
|
FMenuProfiles := TStringList.Create;
|
||||||
|
|
||||||
// FSimConnectDataEvent := TEvent.Create(nil, False, False, '');
|
{$IFDEF SCUSEEVENT}
|
||||||
// Task.RegisterWaitObject(SimConnectDataEvent.Handle, HandleSimConnectDataEvent);
|
FSimConnectDataEvent := TEvent.Create(nil, False, False, '');
|
||||||
|
Task.RegisterWaitObject(SimConnectDataEvent.Handle, HandleSimConnectDataEvent);
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
TrySimConnect;
|
TrySimConnect;
|
||||||
end;
|
end;
|
||||||
@ -316,7 +396,13 @@ end;
|
|||||||
|
|
||||||
procedure TFSXSimConnectClient.Cleanup;
|
procedure TFSXSimConnectClient.Cleanup;
|
||||||
begin
|
begin
|
||||||
// FreeAndNil(FSimConnectDataEvent);
|
Debug.Log('FSX SimConnect: Cleaning up');
|
||||||
|
|
||||||
|
{$IFDEF SCUSEEVENT}
|
||||||
|
FreeAndNil(FSimConnectDataEvent);
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
FreeAndNil(FMenuProfiles);
|
||||||
FreeAndNil(FDefinitions);
|
FreeAndNil(FDefinitions);
|
||||||
|
|
||||||
if SimConnectHandle <> 0 then
|
if SimConnectHandle <> 0 then
|
||||||
@ -329,41 +415,85 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TFSXSimConnectClient.TrySimConnect;
|
procedure TFSXSimConnectClient.TrySimConnect;
|
||||||
|
var
|
||||||
|
eventHandle: THandle;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if SimConnectHandle <> 0 then
|
if SimConnectHandle <> 0 then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
Debug.Log('FSX SimConnect: Attempting to connect to SimConnect');
|
||||||
|
|
||||||
if InitSimConnect then
|
if InitSimConnect then
|
||||||
begin
|
begin
|
||||||
if SimConnect_Open(FSimConnectHandle, FSXSimConnectAppName, 0, 0, 0 (*SimConnectDataEvent.Handle*), 0) = S_OK then
|
{$IFDEF SCUSEEVENT}
|
||||||
|
eventHandle := SimConnectDataEvent.Handle;
|
||||||
|
{$ELSE}
|
||||||
|
eventHandle := 0;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
if SimConnect_Open(FSimConnectHandle, FSXSimConnectAppName, 0, 0, eventHandle, 0) = S_OK then
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('FSX SimConnect: Succesfully connected');
|
||||||
TFSXSimConnectStateMonitor.SetCurrentState(scsConnected);
|
TFSXSimConnectStateMonitor.SetCurrentState(scsConnected);
|
||||||
|
|
||||||
Task.ClearTimer(TIMER_TRYSIMCONNECT);
|
Task.ClearTimer(TIMER_TRYSIMCONNECT);
|
||||||
RegisterDefinitions;
|
RegisterDefinitions;
|
||||||
|
UpdateProfileMenu;
|
||||||
|
|
||||||
|
{$IFNDEF SCUSEEVENT}
|
||||||
Task.SetTimer(TIMER_PROCESSMESSAGES, INTERVAL_PROCESSMESSAGES, TM_PROCESSMESSAGES);
|
Task.SetTimer(TIMER_PROCESSMESSAGES, INTERVAL_PROCESSMESSAGES, TM_PROCESSMESSAGES);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if SimConnectHandle = 0 then
|
if SimConnectHandle = 0 then
|
||||||
begin
|
begin
|
||||||
|
Debug.LogFmt('FSX SimConnect: Connection failed, trying again in %d seconds', [INTERVAL_TRYSIMCONNECT div 1000]);
|
||||||
TFSXSimConnectStateMonitor.SetCurrentState(scsFailed);
|
TFSXSimConnectStateMonitor.SetCurrentState(scsFailed);
|
||||||
|
|
||||||
Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT);
|
Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT);
|
||||||
|
{$IFNDEF SCUSEEVENT}
|
||||||
Task.ClearTimer(TIMER_PROCESSMESSAGES);
|
Task.ClearTimer(TIMER_PROCESSMESSAGES);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TFSXSimConnectClient.HandleSimConnectDataEvent;
|
procedure TFSXSimConnectClient.HandleSimConnectDataEvent;
|
||||||
|
const
|
||||||
|
RecvMessageName: array[SIMCONNECT_RECV_ID] of string =
|
||||||
|
(
|
||||||
|
'Null',
|
||||||
|
'Exception',
|
||||||
|
'Open',
|
||||||
|
'Quit',
|
||||||
|
'Event',
|
||||||
|
'Event Object Addremove',
|
||||||
|
'Event Filename',
|
||||||
|
'Event Frame',
|
||||||
|
'Simobject Data',
|
||||||
|
'Simobject Data Bytype',
|
||||||
|
'Weather Observation',
|
||||||
|
'Cloud State',
|
||||||
|
'Assigned Object Id',
|
||||||
|
'Reserved Key',
|
||||||
|
'Custom Action',
|
||||||
|
'System State',
|
||||||
|
'Client Data'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
data: PSimConnectRecv;
|
data: PSimConnectRecv;
|
||||||
dataSize: Cardinal;
|
dataSize: Cardinal;
|
||||||
simObjectData: PSimConnectRecvSimObjectData;
|
simObjectData: PSimConnectRecvSimObjectData;
|
||||||
|
eventData: PSimConnectRecvEvent;
|
||||||
definitionRef: TFSXSimConnectDefinitionRef;
|
definitionRef: TFSXSimConnectDefinitionRef;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('FSX SimConnect: Handling messages');
|
||||||
|
|
||||||
while (SimConnectHandle <> 0) and
|
while (SimConnectHandle <> 0) and
|
||||||
(SimConnect_GetNextDispatch(SimConnectHandle, data, dataSize) = S_OK) do
|
(SimConnect_GetNextDispatch(SimConnectHandle, data, dataSize) = S_OK) do
|
||||||
begin
|
begin
|
||||||
@ -371,6 +501,7 @@ begin
|
|||||||
SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
SIMCONNECT_RECV_ID_SIMOBJECT_DATA:
|
||||||
begin
|
begin
|
||||||
simObjectData := PSimConnectRecvSimObjectData(data);
|
simObjectData := PSimConnectRecvSimObjectData(data);
|
||||||
|
Debug.LogFmt('FSX SimConnect: Received Sim Object Data message (definition = %d)', [simObjectData^.dwDefineID]);
|
||||||
|
|
||||||
if Definitions.ContainsKey(simObjectData^.dwDefineID) then
|
if Definitions.ContainsKey(simObjectData^.dwDefineID) then
|
||||||
begin
|
begin
|
||||||
@ -379,19 +510,54 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
SIMCONNECT_RECV_ID_EVENT:
|
||||||
|
begin
|
||||||
|
eventData := PSimConnectRecvEvent(data);
|
||||||
|
Debug.LogFmt('FSX SimConnect: Received Event message (eventId = %d)', [eventData^.uEventID]);
|
||||||
|
|
||||||
|
HandleEvent(eventData^.uEventID);
|
||||||
|
end;
|
||||||
|
|
||||||
SIMCONNECT_RECV_ID_QUIT:
|
SIMCONNECT_RECV_ID_QUIT:
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('FSX SimConnect: Received Quit message');
|
||||||
|
|
||||||
FSimConnectHandle := 0;
|
FSimConnectHandle := 0;
|
||||||
|
{$IFNDEF SCUSEEVENT}
|
||||||
Task.ClearTimer(TIMER_PROCESSMESSAGES);
|
Task.ClearTimer(TIMER_PROCESSMESSAGES);
|
||||||
|
{$ENDIF}
|
||||||
Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT);
|
Task.SetTimer(TIMER_TRYSIMCONNECT, INTERVAL_TRYSIMCONNECT, TM_TRYSIMCONNECT);
|
||||||
|
|
||||||
|
FMenuProfiles.Clear;
|
||||||
|
|
||||||
TFSXSimConnectStateMonitor.SetCurrentState(scsDisconnected);
|
TFSXSimConnectStateMonitor.SetCurrentState(scsDisconnected);
|
||||||
end;
|
end;
|
||||||
|
else
|
||||||
|
if SIMCONNECT_RECV_ID(data^.dwID) in [Low(SIMCONNECT_RECV_ID)..High(SIMCONNECT_RECV_ID)] then
|
||||||
|
Debug.LogFmt('FSX SimConnect: Received unhandled message (%s)', [RecvMessageName[SIMCONNECT_RECV_ID(data^.dwID)]])
|
||||||
|
else
|
||||||
|
Debug.LogFmt('FSX SimConnect: Received unknown message (%d)', [data^.dwID]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectClient.HandleEvent(AEventID: Integer);
|
||||||
|
var
|
||||||
|
profileName: string;
|
||||||
|
profile: TProfile;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (AEventID <= 0) or (AEventID > FMenuProfiles.Count) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
profileName := FMenuProfiles[Pred(AEventID)];
|
||||||
|
profile := TProfileManager.Find(profileName);
|
||||||
|
if Assigned(profile) then
|
||||||
|
TProfileManager.Instance.ActiveProfile := profile;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TFSXSimConnectClient.RegisterDefinitions;
|
procedure TFSXSimConnectClient.RegisterDefinitions;
|
||||||
var
|
var
|
||||||
definitionID: Cardinal;
|
definitionID: Cardinal;
|
||||||
@ -400,6 +566,8 @@ begin
|
|||||||
if SimConnectHandle = 0 then
|
if SimConnectHandle = 0 then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
UpdateProfileMenu;
|
||||||
|
|
||||||
for definitionID in Definitions.Keys do
|
for definitionID in Definitions.Keys do
|
||||||
RegisterDefinition(definitionID, Definitions[definitionID].Definition);
|
RegisterDefinition(definitionID, Definitions[definitionID].Definition);
|
||||||
end;
|
end;
|
||||||
@ -414,6 +582,8 @@ begin
|
|||||||
if SimConnectHandle = 0 then
|
if SimConnectHandle = 0 then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
Debug.LogFmt('FSX SimConnect: Registering definition %d', [ADefinitionID]);
|
||||||
|
|
||||||
for variableIndex := 0 to Pred(ADefinition.GetVariableCount) do
|
for variableIndex := 0 to Pred(ADefinition.GetVariableCount) do
|
||||||
begin
|
begin
|
||||||
variable := ADefinition.GetVariable(variableIndex);
|
variable := ADefinition.GetVariable(variableIndex);
|
||||||
@ -446,7 +616,10 @@ end;
|
|||||||
procedure TFSXSimConnectClient.UnregisterDefinition(ADefinitionID: Cardinal);
|
procedure TFSXSimConnectClient.UnregisterDefinition(ADefinitionID: Cardinal);
|
||||||
begin
|
begin
|
||||||
if SimConnectHandle <> 0 then
|
if SimConnectHandle <> 0 then
|
||||||
|
begin
|
||||||
|
Debug.LogFmt('FSX SimConnect: Unregistering definition: %d', [ADefinitionID]);
|
||||||
SimConnect_ClearDataDefinition(SimConnectHandle, ADefinitionID);
|
SimConnect_ClearDataDefinition(SimConnectHandle, ADefinitionID);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -482,6 +655,69 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectClient.UpdateProfileMenu;
|
||||||
|
var
|
||||||
|
profile: TProfile;
|
||||||
|
profileIndex: Integer;
|
||||||
|
menuIndex: Integer;
|
||||||
|
profileName: string;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if SimConnectHandle = 0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
Debug.Log('FSX SimConnect: Updating profile menu');
|
||||||
|
|
||||||
|
if FMenuWasCascaded then
|
||||||
|
begin
|
||||||
|
for menuIndex := Pred(FMenuProfiles.Count) downto 0 do
|
||||||
|
SimConnect_MenuDeleteSubItem(SimConnectHandle, 1, Cardinal(FMenuProfiles.Objects[menuIndex]));
|
||||||
|
|
||||||
|
SimConnect_MenuDeleteItem(SimConnectHandle, 1);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
for menuIndex := Pred(FMenuProfiles.Count) downto 0 do
|
||||||
|
SimConnect_MenuDeleteItem(SimConnectHandle, Cardinal(FMenuProfiles.Objects[menuIndex]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
FMenuProfiles.Clear;
|
||||||
|
|
||||||
|
|
||||||
|
if ProfileMenu then
|
||||||
|
begin
|
||||||
|
for profile in TProfileManager.Instance do
|
||||||
|
FMenuProfiles.Add(profile.Name);
|
||||||
|
|
||||||
|
FMenuProfiles.Sort;
|
||||||
|
|
||||||
|
|
||||||
|
if ProfileMenuCascaded then
|
||||||
|
begin
|
||||||
|
SimConnect_MenuAddItem(SimConnectHandle, FSXMenuProfiles, 1, 0);
|
||||||
|
|
||||||
|
for profileIndex := 0 to Pred(FMenuProfiles.Count) do
|
||||||
|
begin
|
||||||
|
profileName := Format(FSXMenuProfileFormatCascaded, [FMenuProfiles[profileIndex]]);
|
||||||
|
|
||||||
|
SimConnect_MenuAddSubItem(SimConnectHandle, 1, PAnsiChar(AnsiString(profileName)), Succ(profileIndex), Succ(profileIndex));
|
||||||
|
FMenuProfiles.Objects[profileIndex] := TObject(Succ(profileIndex));
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
for profileIndex := 0 to Pred(FMenuProfiles.Count) do
|
||||||
|
begin
|
||||||
|
profileName := Format(FSXMenuProfileFormat, [FMenuProfiles[profileIndex]]);
|
||||||
|
|
||||||
|
SimConnect_MenuAddItem(SimConnectHandle, PAnsiChar(AnsiString(profileName)), Succ(profileIndex), Succ(profileIndex));
|
||||||
|
FMenuProfiles.Objects[profileIndex] := TObject(Succ(profileIndex));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FMenuWasCascaded := ProfileMenuCascaded;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TFSXSimConnectClient.TMAddDefinition(var Msg: TOmniMessage);
|
procedure TFSXSimConnectClient.TMAddDefinition(var Msg: TOmniMessage);
|
||||||
var
|
var
|
||||||
addDefinition: TAddDefinitionValue;
|
addDefinition: TAddDefinitionValue;
|
||||||
@ -489,12 +725,15 @@ var
|
|||||||
definitionRef: TFSXSimConnectDefinitionRef;
|
definitionRef: TFSXSimConnectDefinitionRef;
|
||||||
definitionAccess: IFSXSimConnectDefinitionAccess;
|
definitionAccess: IFSXSimConnectDefinitionAccess;
|
||||||
hasDefinition: Boolean;
|
hasDefinition: Boolean;
|
||||||
|
refCount: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
addDefinition := Msg.MsgData;
|
addDefinition := Msg.MsgData;
|
||||||
definitionAccess := (addDefinition.Definition as IFSXSimConnectDefinitionAccess);
|
definitionAccess := (addDefinition.Definition as IFSXSimConnectDefinitionAccess);
|
||||||
hasDefinition := False;
|
hasDefinition := False;
|
||||||
|
|
||||||
|
Debug.Log('FSX SimConnect: Received request to add a definition');
|
||||||
|
|
||||||
{ Attempt to re-use existing definition to save on SimConnect traffic }
|
{ Attempt to re-use existing definition to save on SimConnect traffic }
|
||||||
for definitionID in Definitions.Keys do
|
for definitionID in Definitions.Keys do
|
||||||
begin
|
begin
|
||||||
@ -502,9 +741,12 @@ begin
|
|||||||
|
|
||||||
if SameDefinition(definitionRef.Definition, definitionAccess) then
|
if SameDefinition(definitionRef.Definition, definitionAccess) then
|
||||||
begin
|
begin
|
||||||
definitionRef.Attach(addDefinition.DataHandler);
|
refCount := definitionRef.Attach(addDefinition.DataHandler);
|
||||||
addDefinition.DefinitionID := definitionID;
|
addDefinition.DefinitionID := definitionID;
|
||||||
|
|
||||||
|
Debug.LogFmt('FSX SimConnect: Definition exists, incremented reference count (definitionID = %d, refCount = %d)', [definitionID, refCount]);
|
||||||
|
|
||||||
|
|
||||||
{ Request an update on the definition to update the new worker }
|
{ Request an update on the definition to update the new worker }
|
||||||
UpdateDefinition(definitionID);
|
UpdateDefinition(definitionID);
|
||||||
|
|
||||||
@ -517,6 +759,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
{ Add as new definition }
|
{ Add as new definition }
|
||||||
Inc(FLastDefinitionID);
|
Inc(FLastDefinitionID);
|
||||||
|
Debug.LogFmt('FSX SimConnect: Adding as new definition (%d)', [FLastDefinitionID]);
|
||||||
|
|
||||||
definitionRef := TFSXSimConnectDefinitionRef.Create(definitionAccess);
|
definitionRef := TFSXSimConnectDefinitionRef.Create(definitionAccess);
|
||||||
definitionRef.Attach(addDefinition.DataHandler);
|
definitionRef.Attach(addDefinition.DataHandler);
|
||||||
@ -534,15 +777,23 @@ procedure TFSXSimConnectClient.TMRemoveDefinition(var Msg: TOmniMessage);
|
|||||||
var
|
var
|
||||||
removeDefinition: TRemoveDefinitionValue;
|
removeDefinition: TRemoveDefinitionValue;
|
||||||
definitionRef: TFSXSimConnectDefinitionRef;
|
definitionRef: TFSXSimConnectDefinitionRef;
|
||||||
|
refCount: Integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
removeDefinition := Msg.MsgData;
|
removeDefinition := Msg.MsgData;
|
||||||
|
Debug.LogFmt('FSX SimConnect: Received request to remove a definition (%d)', [removeDefinition.DefinitionID]);
|
||||||
|
|
||||||
if Definitions.ContainsKey(removeDefinition.DefinitionID) then
|
if Definitions.ContainsKey(removeDefinition.DefinitionID) then
|
||||||
begin
|
begin
|
||||||
definitionRef := Definitions[removeDefinition.DefinitionID];
|
definitionRef := Definitions[removeDefinition.DefinitionID];
|
||||||
if definitionRef.Detach(removeDefinition.DataHandler) = 0 then
|
refCount := definitionRef.Detach(removeDefinition.DataHandler);
|
||||||
|
|
||||||
|
Debug.LogFmt('FSX SimConnect: Definition exists, decreased reference count (refCount = %d)', [refCount]);
|
||||||
|
|
||||||
|
if refCount = 0 then
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('FSX SimConnect: Removing definition');
|
||||||
|
|
||||||
{ Unregister with SimConnect }
|
{ Unregister with SimConnect }
|
||||||
UnregisterDefinition(removeDefinition.DefinitionID);
|
UnregisterDefinition(removeDefinition.DefinitionID);
|
||||||
|
|
||||||
@ -560,10 +811,37 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{$IFNDEF SCUSEEVENT}
|
||||||
procedure TFSXSimConnectClient.TMProcessMessages(var Msg: TOmniMessage);
|
procedure TFSXSimConnectClient.TMProcessMessages(var Msg: TOmniMessage);
|
||||||
begin
|
begin
|
||||||
HandleSimConnectDataEvent;
|
HandleSimConnectDataEvent;
|
||||||
end;
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectClient.TMSetProfileMenu(var Msg: TOmniMessage);
|
||||||
|
var
|
||||||
|
newProfileMenu: Boolean;
|
||||||
|
newProfileMenuCascaded: Boolean;
|
||||||
|
|
||||||
|
begin
|
||||||
|
newProfileMenu := Msg.MsgData[0];
|
||||||
|
newProfileMenuCascaded := Msg.MsgData[1];
|
||||||
|
|
||||||
|
if (newProfileMenu <> FProfileMenu) or (newProfileMenuCascaded <> FProfileMenuCascaded) then
|
||||||
|
begin
|
||||||
|
FProfileMenu := newProfileMenu;
|
||||||
|
FProfileMenuCascaded := newProfileMenuCascaded;
|
||||||
|
|
||||||
|
UpdateProfileMenu;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TFSXSimConnectClient.TMUpdateProfileMenu(var Msg: TOmniMessage);
|
||||||
|
begin
|
||||||
|
UpdateProfileMenu;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TFSXSimConnectDefinitionRef }
|
{ TFSXSimConnectDefinitionRef }
|
||||||
@ -594,9 +872,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TFSXSimConnectDefinitionRef.Attach(ADataHandler: IFSXSimConnectDataHandler);
|
function TFSXSimConnectDefinitionRef.Attach(ADataHandler: IFSXSimConnectDataHandler): Integer;
|
||||||
begin
|
begin
|
||||||
DataHandlers.Add(ADataHandler as IFSXSimConnectDataHandler);
|
DataHandlers.Add(ADataHandler as IFSXSimConnectDataHandler);
|
||||||
|
Result := DataHandlers.Count;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
IFSXSimConnectProfileMenu = interface
|
||||||
|
['{362B6F7D-3E68-48A8-83BC-6078AE100334}']
|
||||||
|
procedure SetProfileMenu(AEnabled, ACascaded: Boolean);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
IFSXSimConnectDefinition = interface
|
IFSXSimConnectDefinition = interface
|
||||||
['{F1EAB3B1-0A3D-4B06-A75F-823E15C313B8}']
|
['{F1EAB3B1-0A3D-4B06-A75F-823E15C313B8}']
|
||||||
procedure AddVariable(AVariableName, AUnitsName: string; ADataType: SIMCONNECT_DATAType; AEpsilon: Single = 0);
|
procedure AddVariable(AVariableName, AUnitsName: string; ADataType: SIMCONNECT_DATAType; AEpsilon: Single = 0);
|
||||||
@ -76,8 +82,16 @@ const
|
|||||||
FSX_LIGHTON_STROBE = $0010;
|
FSX_LIGHTON_STROBE = $0010;
|
||||||
FSX_LIGHTON_PANEL = $0020;
|
FSX_LIGHTON_PANEL = $0020;
|
||||||
FSX_LIGHTON_RECOGNITION = $0040;
|
FSX_LIGHTON_RECOGNITION = $0040;
|
||||||
|
FSX_LIGHTON_WING = $0080;
|
||||||
|
FSX_LIGHTON_LOGO = $0100;
|
||||||
FSX_LIGHTON_CABIN = $0200;
|
FSX_LIGHTON_CABIN = $0200;
|
||||||
|
|
||||||
|
FSX_LIGHTON_ALL = FSX_LIGHTON_NAV or FSX_LIGHTON_BEACON or FSX_LIGHTON_LANDING or
|
||||||
|
FSX_LIGHTON_TAXI or FSX_LIGHTON_STROBE or FSX_LIGHTON_PANEL or
|
||||||
|
FSX_LIGHTON_RECOGNITION or FSX_LIGHTON_WING or FSX_LIGHTON_LOGO or
|
||||||
|
FSX_LIGHTON_CABIN;
|
||||||
|
|
||||||
|
|
||||||
FSX_MAX_ENGINES = 4;
|
FSX_MAX_ENGINES = 4;
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ uses
|
|||||||
OtlCommon,
|
OtlCommon,
|
||||||
OtlTask,
|
OtlTask,
|
||||||
|
|
||||||
|
DebugLog,
|
||||||
LEDColorIntf,
|
LEDColorIntf,
|
||||||
LogiJoystickDLL;
|
LogiJoystickDLL;
|
||||||
|
|
||||||
@ -99,12 +100,14 @@ begin
|
|||||||
|
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|
||||||
|
Debug.Log('G940 LED State consumer: Initializing LogiJoystickDLL');
|
||||||
if not LogiJoystickDLLInitialized then
|
if not LogiJoystickDLLInitialized then
|
||||||
begin
|
begin
|
||||||
Task.SetExitStatus(EXIT_ERROR_LOGIJOYSTICKDLL, 'Could not load LogiJoystickDLL.dll');
|
Task.SetExitStatus(EXIT_ERROR_LOGIJOYSTICKDLL, 'Could not load LogiJoystickDLL.dll');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Debug.Log('G940 LED State consumer: Initializing DirectInput');
|
||||||
if DirectInput8Create(SysInit.HInstance, DIRECTINPUT_VERSION, IDirectInput8, FDirectInput, nil) <> S_OK then
|
if DirectInput8Create(SysInit.HInstance, DIRECTINPUT_VERSION, IDirectInput8, FDirectInput, nil) <> S_OK then
|
||||||
begin
|
begin
|
||||||
Task.SetExitStatus(EXIT_ERROR_DIRECTINPUT, 'Failed to initialize DirectInput');
|
Task.SetExitStatus(EXIT_ERROR_DIRECTINPUT, 'Failed to initialize DirectInput');
|
||||||
@ -121,12 +124,17 @@ begin
|
|||||||
inherited Cleanup;
|
inherited Cleanup;
|
||||||
|
|
||||||
if Assigned(ThrottleDevice) then
|
if Assigned(ThrottleDevice) then
|
||||||
|
begin
|
||||||
|
Debug.Log('G940 LED State consumer: Cleanup (all LEDs to Green)');
|
||||||
SetLEDs(ThrottleDevice, 0, $FF);
|
SetLEDs(ThrottleDevice, 0, $FF);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TG940LEDStateConsumer.FindThrottleDevice;
|
procedure TG940LEDStateConsumer.FindThrottleDevice;
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('G940 LED State consumer: Searching for throttle device');
|
||||||
|
|
||||||
SetDeviceState(DEVICESTATE_SEARCHING);
|
SetDeviceState(DEVICESTATE_SEARCHING);
|
||||||
DirectInput.EnumDevices(DI8DEVCLASS_GAMECTRL,
|
DirectInput.EnumDevices(DI8DEVCLASS_GAMECTRL,
|
||||||
EnumDevicesProc,
|
EnumDevicesProc,
|
||||||
@ -164,6 +172,21 @@ procedure TG940LEDStateConsumer.Update;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ByteToBin(AByte: Byte): string;
|
||||||
|
var
|
||||||
|
bit: Integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result := StringOfChar('0', 8);
|
||||||
|
|
||||||
|
for bit := 0 to 7 do
|
||||||
|
begin
|
||||||
|
if (AByte and (1 shl bit)) <> 0 then
|
||||||
|
Result[8 - bit] := '1';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
red: Byte;
|
red: Byte;
|
||||||
green: Byte;
|
green: Byte;
|
||||||
@ -199,6 +222,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Debug.LogFmt('G940 LED State consumer: Set LED colors (red = %s, green = %s)', [ByteToBin(red), ByteToBin(green)]);
|
||||||
SetLEDs(ThrottleDevice, red, green);
|
SetLEDs(ThrottleDevice, red, green);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -213,8 +237,12 @@ procedure TG940LEDStateConsumer.TMTestThrottleDevice(var Msg: TOmniMessage);
|
|||||||
begin
|
begin
|
||||||
if Assigned(ThrottleDevice) then
|
if Assigned(ThrottleDevice) then
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('G940 LED State consumer: Checking if throttle is still attached');
|
||||||
|
|
||||||
if DirectInput.GetDeviceStatus(ThrottleDeviceGUID) = DI_NOTATTACHED then
|
if DirectInput.GetDeviceStatus(ThrottleDeviceGUID) = DI_NOTATTACHED then
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('G940 LED State consumer: Throttle disconnect');
|
||||||
|
|
||||||
FThrottleDevice := nil;
|
FThrottleDevice := nil;
|
||||||
SetDeviceState(DEVICESTATE_NOTFOUND);
|
SetDeviceState(DEVICESTATE_NOTFOUND);
|
||||||
end;
|
end;
|
||||||
|
274
G940LEDControl/Units/GxDbugIntf.pas
Normal file
274
G940LEDControl/Units/GxDbugIntf.pas
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
(*
|
||||||
|
* GExperts Debug Window Interface
|
||||||
|
* http://www.gexperts.org
|
||||||
|
*
|
||||||
|
* You are free to use this code in any application to send commands to the
|
||||||
|
* GExperts debug window. This includes usage in commercial, shareware,
|
||||||
|
* freeware, public domain, and other applications.
|
||||||
|
*)
|
||||||
|
|
||||||
|
unit GxDbugIntf;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Windows, Dialogs; // We need "Dialogs" for TMsgDlgType
|
||||||
|
|
||||||
|
procedure SendBoolean(const Identifier: string; const Value: Boolean);
|
||||||
|
procedure SendDateTime(const Identifier: string; const Value: TDateTime);
|
||||||
|
procedure SendDebugEx(const Msg: string; MType: TMsgDlgType);
|
||||||
|
procedure SendDebug(const Msg: string);
|
||||||
|
procedure SendDebugError(const Msg: string);
|
||||||
|
procedure SendDebugWarning(const Msg: string);
|
||||||
|
procedure SendDebugClear;
|
||||||
|
procedure SendInteger(const Identifier: string; const Value: Integer);
|
||||||
|
procedure SendMethodEnter(const MethodName: string);
|
||||||
|
procedure SendMethodExit(const MethodName: string);
|
||||||
|
procedure SendIndent;
|
||||||
|
procedure SendUnIndent;
|
||||||
|
procedure SendSeparator;
|
||||||
|
procedure SendDebugFmt(const Msg: string; const Args: array of const);
|
||||||
|
procedure SendDebugFmtEx(const Msg: string; const Args: array of const; MType: TMsgDlgType);
|
||||||
|
function StartDebugWin: hWnd;
|
||||||
|
procedure SendDebugPause;
|
||||||
|
procedure SendDebugResume;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
Messages,
|
||||||
|
SysUtils,
|
||||||
|
Registry,
|
||||||
|
{$IFDEF GX_DEBUGLOG}
|
||||||
|
GX_Debug,
|
||||||
|
{$ENDIF GX_DEBUGLOG}
|
||||||
|
Forms; // We need "Forms" for the Application object
|
||||||
|
|
||||||
|
threadvar
|
||||||
|
MsgPrefix: string;
|
||||||
|
|
||||||
|
const
|
||||||
|
chrStringCommand: AnsiChar = {$IFDEF UNICODE} #4 {$ELSE} #1 {$ENDIF};
|
||||||
|
chrSQLCommand: AnsiChar = #2; // Old, unused type
|
||||||
|
chrClearCommand: AnsiChar = #3;
|
||||||
|
chrNull: AnsiChar = #0;
|
||||||
|
|
||||||
|
var
|
||||||
|
PastFailedAttemptToStartDebugWin: Boolean = False;
|
||||||
|
SendPaused: Boolean = False;
|
||||||
|
|
||||||
|
function StartDebugWin: hWnd;
|
||||||
|
var
|
||||||
|
DebugFileName: string;
|
||||||
|
Buf: array[0..MAX_PATH + 1] of Char;
|
||||||
|
si: TStartupInfo;
|
||||||
|
pi: TProcessInformation;
|
||||||
|
begin
|
||||||
|
MsgPrefix := '';
|
||||||
|
|
||||||
|
Result := 0;
|
||||||
|
if PastFailedAttemptToStartDebugWin then
|
||||||
|
Exit;
|
||||||
|
|
||||||
|
with TRegIniFile.Create('\Software\GExperts') do // Do not localize.
|
||||||
|
try
|
||||||
|
DebugFileName := ReadString('Debug', 'FilePath', ''); // Do not localize.
|
||||||
|
finally
|
||||||
|
Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Trim(DebugFileName) = '' then
|
||||||
|
begin
|
||||||
|
GetModuleFileName(HINSTANCE, Buf, SizeOf(Buf)-1);
|
||||||
|
DebugFileName := ExtractFilePath(StrPas(Buf)) + 'GExpertsDebugWindow.exe'; // Do not localize.
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (Trim(DebugFileName) = '') or not FileExists(DebugFileName) then
|
||||||
|
begin
|
||||||
|
PastFailedAttemptToStartDebugWin := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FillChar(si, SizeOf(si), #0);
|
||||||
|
si.cb := SizeOf(si);
|
||||||
|
si.dwFlags := STARTF_USESHOWWINDOW;
|
||||||
|
si.wShowWindow := SW_SHOW;
|
||||||
|
if not CreateProcess(PChar(DebugFileName), nil, nil, nil,
|
||||||
|
False, 0, nil, nil, si, pi) then
|
||||||
|
begin
|
||||||
|
PastFailedAttemptToStartDebugWin := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
try
|
||||||
|
WaitForInputIdle(pi.hProcess, 3 * 1000); // wait for 3 seconds to get idle
|
||||||
|
finally
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := FindWindow('TfmDebug', nil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugEx(const Msg: string; MType: TMsgDlgType);
|
||||||
|
var
|
||||||
|
CDS: TCopyDataStruct;
|
||||||
|
DebugWin: hWnd;
|
||||||
|
MessageString: string;
|
||||||
|
MsgBytes: array of Byte;
|
||||||
|
MsgType: AnsiChar;
|
||||||
|
ByteIndex: Integer;
|
||||||
|
{$IFDEF GX_DEBUGLOG}
|
||||||
|
{$DEFINE NEEDMTYPESTR}
|
||||||
|
{$ENDIF GX_DEBUGLOG}
|
||||||
|
|
||||||
|
procedure AddByte(B: Byte);
|
||||||
|
begin
|
||||||
|
MsgBytes[ByteIndex] := B;
|
||||||
|
Inc(ByteIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure AddStringBytes(Str: string);
|
||||||
|
var
|
||||||
|
BPointer: {$IFDEF UNICODE} PByte {$ELSE} PAnsiChar {$ENDIF};
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
BPointer := Pointer(Str);
|
||||||
|
for i := 0 to ((Length(Str)) * SizeOf(Char)) - 1 do
|
||||||
|
AddByte(Byte(BPointer[i]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$IFDEF NEEDMTYPESTR}
|
||||||
|
const
|
||||||
|
MTypeStr: array[TMsgDlgType] of string =
|
||||||
|
('Warning: ', 'Error: ', 'Information: ', 'Confirmation: ', 'Custom: ');
|
||||||
|
{$ENDIF NEEDMTYPESTR}
|
||||||
|
begin
|
||||||
|
if SendPaused then
|
||||||
|
Exit;
|
||||||
|
|
||||||
|
{$IFDEF GX_DEBUGLOG}
|
||||||
|
GxAddToDebugLog(MTypeStr[MType] + Msg);
|
||||||
|
{$ENDIF GX_DEBUGLOG}
|
||||||
|
{$IFDEF MSWINDOWS}
|
||||||
|
DebugWin := FindWindow('TfmDebug', nil);
|
||||||
|
|
||||||
|
if DebugWin = 0 then
|
||||||
|
DebugWin := StartDebugWin;
|
||||||
|
|
||||||
|
if DebugWin <> 0 then
|
||||||
|
begin
|
||||||
|
ByteIndex := 0;
|
||||||
|
MessageString := MsgPrefix + Msg;
|
||||||
|
SetLength(MsgBytes, 1 + 1 + (Length(MessageString)* SizeOf(Char)) + 1); // Payload, type, message, null
|
||||||
|
CDS.cbData := Length(MsgBytes);
|
||||||
|
CDS.dwData := 0;
|
||||||
|
MsgType := AnsiChar(Ord(MType) + 1);
|
||||||
|
if Msg = string(chrClearCommand) then
|
||||||
|
AddByte(Byte(chrClearCommand))
|
||||||
|
else
|
||||||
|
AddByte(Byte(chrStringCommand));
|
||||||
|
AddByte(Byte(MsgType));
|
||||||
|
AddStringBytes(MessageString);
|
||||||
|
AddByte(Byte(chrNull));
|
||||||
|
CDS.lpData := Pointer(MsgBytes);
|
||||||
|
SendMessage(DebugWin, WM_COPYDATA, WPARAM(Application.Handle), LPARAM(@CDS));
|
||||||
|
end;
|
||||||
|
{$ENDIF MSWINDOWS}
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebug(const Msg: string);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Msg, mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugError(const Msg: string);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Msg, mtError);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugWarning(const Msg: string);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Msg, mtWarning);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugFmt(const Msg: string; const Args: array of const);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Format(Msg, Args), mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugFmtEx(const Msg: string; const Args: array of const; MType: TMsgDlgType);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Format(Msg, Args), MType);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugClear;
|
||||||
|
begin
|
||||||
|
SendDebug(string(chrClearCommand));
|
||||||
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
Indentation = ' ';
|
||||||
|
|
||||||
|
procedure SendMethodEnter(const MethodName: string);
|
||||||
|
begin
|
||||||
|
SendDebugEx('Entering ' + MethodName, mtInformation);
|
||||||
|
SendIndent;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendIndent;
|
||||||
|
begin
|
||||||
|
MsgPrefix := MsgPrefix + Indentation;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendUnIndent;
|
||||||
|
begin
|
||||||
|
Delete(MsgPrefix, 1, Length(Indentation));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendMethodExit(const MethodName: string);
|
||||||
|
begin
|
||||||
|
SendUnindent;
|
||||||
|
SendDebugEx('Exiting ' + MethodName, mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendSeparator;
|
||||||
|
const
|
||||||
|
SeparatorString = '------------------------------';
|
||||||
|
begin
|
||||||
|
SendDebugEx(SeparatorString, mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendBoolean(const Identifier: string; const Value: Boolean);
|
||||||
|
begin
|
||||||
|
// Note: We deliberately leave "True" and "False" as
|
||||||
|
// hard-coded string constants, since these are
|
||||||
|
// technical terminology which should not be localised.
|
||||||
|
if Value then
|
||||||
|
SendDebugEx(Identifier + ' = True', mtInformation)
|
||||||
|
else
|
||||||
|
SendDebugEx(Identifier + ' = False', mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendInteger(const Identifier: string; const Value: Integer);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Format('%s = %d', [Identifier, Value]), mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDateTime(const Identifier: string; const Value: TDateTime);
|
||||||
|
begin
|
||||||
|
SendDebugEx(Identifier + ' = ' + DateTimeToStr(Value), mtInformation);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugPause;
|
||||||
|
begin
|
||||||
|
SendPaused := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SendDebugResume;
|
||||||
|
begin
|
||||||
|
SendPaused := False;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -53,6 +53,7 @@ uses
|
|||||||
System.SysUtils,
|
System.SysUtils,
|
||||||
Winapi.Windows,
|
Winapi.Windows,
|
||||||
|
|
||||||
|
DebugLog,
|
||||||
LEDFunctionRegistry,
|
LEDFunctionRegistry,
|
||||||
LEDStateIntf;
|
LEDStateIntf;
|
||||||
|
|
||||||
@ -123,46 +124,57 @@ var
|
|||||||
dynamicColor: ILEDStateDynamicColor;
|
dynamicColor: ILEDStateDynamicColor;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
hasDynamicColors := False;
|
Debug.Log('LED State consumer: Updating LED states');
|
||||||
ButtonColors.Clear;
|
Debug.Indent;
|
||||||
|
try
|
||||||
|
hasDynamicColors := False;
|
||||||
|
ButtonColors.Clear;
|
||||||
|
|
||||||
for buttonIndex := 0 to Pred(ButtonWorkers.Count) do
|
for buttonIndex := 0 to Pred(ButtonWorkers.Count) do
|
||||||
begin
|
|
||||||
color := nil;
|
|
||||||
|
|
||||||
if Assigned(ButtonWorkers[buttonIndex]) then
|
|
||||||
begin
|
begin
|
||||||
state := (ButtonWorkers[buttonIndex] as ILEDFunctionWorker).GetCurrentState;
|
color := nil;
|
||||||
if Assigned(state) then
|
|
||||||
|
if Assigned(ButtonWorkers[buttonIndex]) then
|
||||||
begin
|
begin
|
||||||
color := state.GetColor;
|
state := (ButtonWorkers[buttonIndex] as ILEDFunctionWorker).GetCurrentState;
|
||||||
if Assigned(color) then
|
if Assigned(state) then
|
||||||
begin
|
begin
|
||||||
if (hasDynamicColors = False) and Supports(color, ILEDStateDynamicColor, dynamicColor) then
|
color := state.GetColor;
|
||||||
|
if Assigned(color) then
|
||||||
begin
|
begin
|
||||||
{ If the tick timer isn't currently running, there were no
|
if (hasDynamicColors = False) and Supports(color, ILEDStateDynamicColor, dynamicColor) then
|
||||||
dynamic colors before. Reset each dynamic colors now. }
|
begin
|
||||||
if not HasTickTimer then
|
{ If the tick timer isn't currently running, there were no
|
||||||
dynamicColor.Reset;
|
dynamic colors before. Reset each dynamic colors now. }
|
||||||
|
if not HasTickTimer then
|
||||||
|
dynamicColor.Reset;
|
||||||
|
|
||||||
hasDynamicColors := True;
|
hasDynamicColors := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ButtonColors.Add(color as ILEDStateColor);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ButtonColors.Add(color as ILEDStateColor);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if not Assigned(color) then
|
||||||
|
ButtonColors.Add(nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not Assigned(color) then
|
if hasDynamicColors <> HasTickTimer then
|
||||||
ButtonColors.Add(nil);
|
begin
|
||||||
end;
|
if hasDynamicColors then
|
||||||
|
begin
|
||||||
if hasDynamicColors <> HasTickTimer then
|
Debug.Log('LED State consumer: Starting tick timer');
|
||||||
begin
|
Task.SetTimer(TIMER_TICK, INTERVAL_TICK, TM_TICK)
|
||||||
if hasDynamicColors then
|
end else
|
||||||
Task.SetTimer(TIMER_TICK, INTERVAL_TICK, TM_TICK)
|
begin
|
||||||
else
|
Debug.Log('LED State consumer: Stopping tick timer');
|
||||||
Task.ClearTimer(TIMER_TICK);
|
Task.ClearTimer(TIMER_TICK);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
Debug.UnIndent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Update;
|
Update;
|
||||||
@ -197,6 +209,10 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
profile := Msg.MsgData;
|
profile := Msg.MsgData;
|
||||||
|
if not Assigned(profile) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
Debug.Log('LED State consumer: Loading profile');
|
||||||
|
|
||||||
oldStates := nil;
|
oldStates := nil;
|
||||||
oldWorkers := nil;
|
oldWorkers := nil;
|
||||||
@ -267,6 +283,8 @@ var
|
|||||||
dynamicColor: ILEDStateDynamicColor;
|
dynamicColor: ILEDStateDynamicColor;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Debug.Log('LED State consumer: Tick');
|
||||||
|
|
||||||
// (MvR) 19-2-2013: I could pass a tick count to Tick() so that they can all use modulus to blink synchronously... think about it.
|
// (MvR) 19-2-2013: I could pass a tick count to Tick() so that they can all use modulus to blink synchronously... think about it.
|
||||||
|
|
||||||
for buttonIndex := 0 to Pred(ButtonColors.Count) do
|
for buttonIndex := 0 to Pred(ButtonColors.Count) do
|
||||||
@ -301,6 +319,7 @@ begin
|
|||||||
FProfileButton := AProfileButton;
|
FProfileButton := AProfileButton;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TProfileButtonWorkerSettings.GetStateColor(const AUID: string; out AColor: TLEDColor): Boolean;
|
function TProfileButtonWorkerSettings.GetStateColor(const AUID: string; out AColor: TLEDColor): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := ProfileButton.GetStateColor(AUID, AColor);
|
Result := ProfileButton.GetStateColor(AUID, AColor);
|
||||||
|
270
G940LEDControl/Units/ProfileManager.pas
Normal file
270
G940LEDControl/Units/ProfileManager.pas
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
unit ProfileManager;
|
||||||
|
|
||||||
|
interface
|
||||||
|
uses
|
||||||
|
System.Classes,
|
||||||
|
System.SyncObjs,
|
||||||
|
|
||||||
|
Profile,
|
||||||
|
X2UtPersistIntf;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
IProfileObserver = interface
|
||||||
|
['{DF41398E-015B-4BF4-A6EE-D3E8679E16A9}']
|
||||||
|
procedure ObserveAdd(AProfile: TProfile);
|
||||||
|
procedure ObserveRemove(AProfile: TProfile);
|
||||||
|
procedure ObserveActiveChanged(AProfile: TProfile);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TProfileManager = class;
|
||||||
|
|
||||||
|
|
||||||
|
TProfileManagerEnumerator = class(TProfileList.TEnumerator)
|
||||||
|
private
|
||||||
|
FManager: TProfileManager;
|
||||||
|
public
|
||||||
|
constructor Create(AManager: TProfileManager);
|
||||||
|
destructor Destroy; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TProfileManager = class(TObject)
|
||||||
|
private
|
||||||
|
FLock: TCriticalSection;
|
||||||
|
FProfiles: TProfileList;
|
||||||
|
FObservers: TInterfaceList;
|
||||||
|
FActiveProfile: TProfile;
|
||||||
|
|
||||||
|
function GetActiveProfile: TProfile;
|
||||||
|
function GetCount: Integer;
|
||||||
|
function GetItem(Index: Integer): TProfile;
|
||||||
|
procedure SetActiveProfile(const Value: TProfile);
|
||||||
|
procedure SetItem(Index: Integer; const Value: TProfile);
|
||||||
|
protected
|
||||||
|
property Observers: TInterfaceList read FObservers;
|
||||||
|
property Profiles: TProfileList read FProfiles;
|
||||||
|
public
|
||||||
|
class function Instance(): TProfileManager;
|
||||||
|
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure Lock;
|
||||||
|
procedure Unlock;
|
||||||
|
|
||||||
|
class procedure Add(AProfile: TProfile; ASetActive: Boolean = False);
|
||||||
|
class function Find(const AName: string): TProfile;
|
||||||
|
class function Remove(const AProfile: TProfile): Integer;
|
||||||
|
|
||||||
|
class procedure Load(AReader: IX2PersistReader);
|
||||||
|
class procedure Save(AWriter: IX2PersistWriter);
|
||||||
|
|
||||||
|
class procedure Attach(AObserver: IProfileObserver);
|
||||||
|
class procedure Detach(AObserver: IProfileObserver);
|
||||||
|
|
||||||
|
function GetEnumerator: TProfileManagerEnumerator;
|
||||||
|
|
||||||
|
property ActiveProfile: TProfile read GetActiveProfile write SetActiveProfile;
|
||||||
|
property Count: Integer read GetCount;
|
||||||
|
property Items[Index: Integer]: TProfile read GetItem write SetItem; default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
uses
|
||||||
|
System.SysUtils;
|
||||||
|
|
||||||
|
|
||||||
|
var
|
||||||
|
ProfileManagerInstance: TProfileManager;
|
||||||
|
|
||||||
|
|
||||||
|
{ TProfileManager }
|
||||||
|
class function TProfileManager.Instance: TProfileManager;
|
||||||
|
begin
|
||||||
|
if not Assigned(ProfileManagerInstance) then
|
||||||
|
ProfileManagerInstance := TProfileManager.Create;
|
||||||
|
|
||||||
|
Result := ProfileManagerInstance;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor TProfileManager.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
|
||||||
|
FObservers := TInterfaceList.Create;
|
||||||
|
FProfiles := TProfileList.Create(True);
|
||||||
|
FLock := TCriticalSection.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
destructor TProfileManager.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FLock);
|
||||||
|
FreeAndNil(FProfiles);
|
||||||
|
FreeAndNil(FObservers);
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TProfileManager.Lock;
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TProfileManager.Unlock;
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TProfileManager.Add(AProfile: TProfile; ASetActive: Boolean);
|
||||||
|
var
|
||||||
|
observer: IInterface;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Instance.Lock;
|
||||||
|
try
|
||||||
|
Instance.Profiles.Add(AProfile);
|
||||||
|
finally
|
||||||
|
Instance.Unlock;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for observer in Instance.Observers do
|
||||||
|
(observer as IProfileObserver).ObserveAdd(AProfile);
|
||||||
|
|
||||||
|
if ASetActive then
|
||||||
|
Instance.SetActiveProfile(AProfile);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class function TProfileManager.Find(const AName: string): TProfile;
|
||||||
|
begin
|
||||||
|
Result := Instance.Profiles.Find(AName);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class function TProfileManager.Remove(const AProfile: TProfile): Integer;
|
||||||
|
var
|
||||||
|
observer: IInterface;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Instance.Lock;
|
||||||
|
try
|
||||||
|
Result := Instance.Profiles.Remove(AProfile);
|
||||||
|
finally
|
||||||
|
Instance.Unlock;
|
||||||
|
end;
|
||||||
|
|
||||||
|
for observer in Instance.Observers do
|
||||||
|
(observer as IProfileObserver).ObserveRemove(AProfile);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TProfileManager.Load(AReader: IX2PersistReader);
|
||||||
|
begin
|
||||||
|
Instance.Lock;
|
||||||
|
try
|
||||||
|
Instance.Profiles.Load(AReader);
|
||||||
|
finally
|
||||||
|
Instance.Unlock;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TProfileManager.Save(AWriter: IX2PersistWriter);
|
||||||
|
begin
|
||||||
|
Instance.Lock;
|
||||||
|
try
|
||||||
|
Instance.Profiles.Save(AWriter);
|
||||||
|
finally
|
||||||
|
Instance.Unlock;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TProfileManager.Attach(AObserver: IProfileObserver);
|
||||||
|
begin
|
||||||
|
Instance.Observers.Add(AObserver as IProfileObserver);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure TProfileManager.Detach(AObserver: IProfileObserver);
|
||||||
|
begin
|
||||||
|
Instance.Observers.Remove(AObserver as IProfileObserver);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TProfileManager.GetActiveProfile: TProfile;
|
||||||
|
begin
|
||||||
|
Result := Instance.FActiveProfile;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TProfileManager.GetCount: Integer;
|
||||||
|
begin
|
||||||
|
Result := Instance.Profiles.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TProfileManager.GetEnumerator: TProfileManagerEnumerator;
|
||||||
|
begin
|
||||||
|
Result := TProfileManagerEnumerator.Create(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TProfileManager.GetItem(Index: Integer): TProfile;
|
||||||
|
begin
|
||||||
|
Result := Profiles[Index];
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TProfileManager.SetActiveProfile(const Value: TProfile);
|
||||||
|
var
|
||||||
|
observer: IInterface;
|
||||||
|
begin
|
||||||
|
if Value <> FActiveProfile then
|
||||||
|
begin
|
||||||
|
FActiveProfile := Value;
|
||||||
|
|
||||||
|
for observer in Observers do
|
||||||
|
(observer as IProfileObserver).ObserveActiveChanged(Value);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TProfileManager.SetItem(Index: Integer; const Value: TProfile);
|
||||||
|
begin
|
||||||
|
Profiles[Index] := Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TProfileManagerEnumerator }
|
||||||
|
constructor TProfileManagerEnumerator.Create(AManager: TProfileManager);
|
||||||
|
begin
|
||||||
|
inherited Create(AManager.Profiles);
|
||||||
|
|
||||||
|
FManager := AManager;
|
||||||
|
FManager.Lock;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
destructor TProfileManagerEnumerator.Destroy;
|
||||||
|
begin
|
||||||
|
FManager.Unlock;
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
finalization
|
||||||
|
FreeAndNil(ProfileManagerInstance);
|
||||||
|
|
||||||
|
end.
|
@ -10,6 +10,8 @@ type
|
|||||||
FCheckUpdates: Boolean;
|
FCheckUpdates: Boolean;
|
||||||
FHasCheckUpdates: Boolean;
|
FHasCheckUpdates: Boolean;
|
||||||
FActiveProfile: string;
|
FActiveProfile: string;
|
||||||
|
FProfileMenu: Boolean;
|
||||||
|
FProfileMenuCascaded: Boolean;
|
||||||
|
|
||||||
procedure SetCheckUpdates(const Value: Boolean);
|
procedure SetCheckUpdates(const Value: Boolean);
|
||||||
public
|
public
|
||||||
@ -20,6 +22,9 @@ type
|
|||||||
property HasCheckUpdates: Boolean read FHasCheckUpdates;
|
property HasCheckUpdates: Boolean read FHasCheckUpdates;
|
||||||
|
|
||||||
property ActiveProfile: string read FActiveProfile write FActiveProfile;
|
property ActiveProfile: string read FActiveProfile write FActiveProfile;
|
||||||
|
|
||||||
|
property ProfileMenu: Boolean read FProfileMenu write FProfileMenu;
|
||||||
|
property ProfileMenuCascaded: Boolean read FProfileMenuCascaded write FProfileMenuCascaded;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +35,9 @@ const
|
|||||||
KeyCheckUpdates = 'CheckUpdates';
|
KeyCheckUpdates = 'CheckUpdates';
|
||||||
KeyActiveProfile = 'ActiveProfile';
|
KeyActiveProfile = 'ActiveProfile';
|
||||||
|
|
||||||
|
KeyProfileMenu = 'ProfileMenu';
|
||||||
|
KeyProfileMenuCascaded = 'ProfileMenuCascaded';
|
||||||
|
|
||||||
|
|
||||||
{ TSettings }
|
{ TSettings }
|
||||||
procedure TSettings.Load(AReader: IX2PersistReader);
|
procedure TSettings.Load(AReader: IX2PersistReader);
|
||||||
@ -44,6 +52,12 @@ begin
|
|||||||
|
|
||||||
if not AReader.ReadString(KeyActiveProfile, FActiveProfile) then
|
if not AReader.ReadString(KeyActiveProfile, FActiveProfile) then
|
||||||
FActiveProfile := '';
|
FActiveProfile := '';
|
||||||
|
|
||||||
|
if not AReader.ReadBoolean(KeyProfileMenu, FProfileMenu) then
|
||||||
|
FProfileMenu := False;
|
||||||
|
|
||||||
|
if not AReader.ReadBoolean(KeyProfileMenuCascaded, FProfileMenuCascaded) then
|
||||||
|
FProfileMenuCascaded := False;
|
||||||
finally
|
finally
|
||||||
AReader.EndSection;
|
AReader.EndSection;
|
||||||
end;
|
end;
|
||||||
@ -56,6 +70,8 @@ begin
|
|||||||
try
|
try
|
||||||
AWriter.WriteBoolean(KeyCheckUpdates, CheckUpdates);
|
AWriter.WriteBoolean(KeyCheckUpdates, CheckUpdates);
|
||||||
AWriter.WriteString(KeyActiveProfile, ActiveProfile);
|
AWriter.WriteString(KeyActiveProfile, ActiveProfile);
|
||||||
|
AWriter.WriteBoolean(KeyProfileMenu, ProfileMenu);
|
||||||
|
AWriter.WriteBoolean(KeyProfileMenuCascaded, ProfileMenuCascaded);
|
||||||
finally
|
finally
|
||||||
AWriter.EndSection;
|
AWriter.EndSection;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user