mirror of
https://github.com/salvadordf/CEF4Delphi.git
synced 2025-05-13 21:46:53 +02:00
Update to CEF 81.2.24
- Added code comments to the MediaRouter demo - Added a Lazarus version of the MediaRouter demo
This commit is contained in:
parent
22b59eae73
commit
a34ae44cb0
@ -3,10 +3,10 @@ CEF4Delphi is an open source project created by Salvador D
|
|||||||
|
|
||||||
CEF4Delphi is based on DCEF3, made by Henri Gourvest. The original license of DCEF3 still applies to CEF4Delphi. Read the license terms in the first lines of any *.pas file.
|
CEF4Delphi is based on DCEF3, made by Henri Gourvest. The original license of DCEF3 still applies to CEF4Delphi. Read the license terms in the first lines of any *.pas file.
|
||||||
|
|
||||||
CEF4Delphi uses CEF 81.2.22 which includes Chromium 81.0.4044.113.
|
CEF4Delphi uses CEF 81.2.24 which includes Chromium 81.0.4044.113.
|
||||||
The CEF binaries used by CEF4Delphi are available for download at spotify :
|
The CEF binaries used by CEF4Delphi are available for download at spotify :
|
||||||
* [32 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.22%2Bg23f4473%2Bchromium-81.0.4044.113_windows32.tar.bz2)
|
* [32 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.24%2Bgc0b313d%2Bchromium-81.0.4044.113_windows32.tar.bz2)
|
||||||
* [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.22%2Bg23f4473%2Bchromium-81.0.4044.113_windows64.tar.bz2)
|
* [64 bits](http://opensource.spotify.com/cefbuilds/cef_binary_81.2.24%2Bgc0b313d%2Bchromium-81.0.4044.113_windows64.tar.bz2)
|
||||||
|
|
||||||
|
|
||||||
CEF4Delphi was developed and tested on Delphi 10.3.3 and it has been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2 and Lazarus 2.0.8/FPC 3.0.4. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components.
|
CEF4Delphi was developed and tested on Delphi 10.3.3 and it has been tested in Delphi 7, Delphi XE, Delphi 10, Delphi 10.2 and Lazarus 2.0.8/FPC 3.0.4. CEF4Delphi includes VCL, FireMonkey (FMX) and Lazarus components.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<MainSource>MediaRouter.dpr</MainSource>
|
<MainSource>MediaRouter.dpr</MainSource>
|
||||||
<Base>True</Base>
|
<Base>True</Base>
|
||||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||||
<TargetedPlatforms>3</TargetedPlatforms>
|
<TargetedPlatforms>3</TargetedPlatforms>
|
||||||
<AppType>Application</AppType>
|
<AppType>Application</AppType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -45,7 +45,7 @@ object MediaRouterFrm: TMediaRouterFrm
|
|||||||
Width = 250
|
Width = 250
|
||||||
Height = 727
|
Height = 727
|
||||||
Align = alLeft
|
Align = alLeft
|
||||||
Caption = ' Sinks available on this network '
|
Caption = ' Sinks on this network '
|
||||||
Padding.Left = 10
|
Padding.Left = 10
|
||||||
Padding.Top = 10
|
Padding.Top = 10
|
||||||
Padding.Right = 10
|
Padding.Right = 10
|
||||||
@ -114,16 +114,6 @@ object MediaRouterFrm: TMediaRouterFrm
|
|||||||
Padding.Right = 2
|
Padding.Right = 2
|
||||||
Padding.Bottom = 10
|
Padding.Bottom = 10
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
object SourceURNEdt: TEdit
|
|
||||||
Left = 65
|
|
||||||
Top = 10
|
|
||||||
Width = 392
|
|
||||||
Height = 21
|
|
||||||
Align = alClient
|
|
||||||
TabOrder = 0
|
|
||||||
Text = 'cast:<appId>?clientId=<clientId>'
|
|
||||||
OnChange = SourceURNEdtChange
|
|
||||||
end
|
|
||||||
object SourceLblPnl: TPanel
|
object SourceLblPnl: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 10
|
Top = 10
|
||||||
@ -131,7 +121,7 @@ object MediaRouterFrm: TMediaRouterFrm
|
|||||||
Height = 21
|
Height = 21
|
||||||
Align = alLeft
|
Align = alLeft
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
TabOrder = 1
|
TabOrder = 0
|
||||||
object SourceURNLbl: TLabel
|
object SourceURNLbl: TLabel
|
||||||
Left = 0
|
Left = 0
|
||||||
Top = 0
|
Top = 0
|
||||||
@ -144,6 +134,20 @@ object MediaRouterFrm: TMediaRouterFrm
|
|||||||
ExplicitHeight = 13
|
ExplicitHeight = 13
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
object SourceURNCbx: TComboBox
|
||||||
|
Left = 65
|
||||||
|
Top = 10
|
||||||
|
Width = 392
|
||||||
|
Height = 21
|
||||||
|
Align = alClient
|
||||||
|
ItemIndex = 1
|
||||||
|
TabOrder = 1
|
||||||
|
Text = 'cast:CC1AD845?clientId=123456789'
|
||||||
|
Items.Strings = (
|
||||||
|
'cast:<appId>?clientId=<clientId>'
|
||||||
|
'cast:CC1AD845?clientId=123456789'
|
||||||
|
'cast:4F8B3483?clientId=123456789')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
object MessageGbx: TGroupBox
|
object MessageGbx: TGroupBox
|
||||||
Left = 20
|
Left = 20
|
||||||
@ -247,7 +251,7 @@ object MediaRouterFrm: TMediaRouterFrm
|
|||||||
Width = 250
|
Width = 250
|
||||||
Height = 727
|
Height = 727
|
||||||
Align = alRight
|
Align = alRight
|
||||||
Caption = ' Routes available '
|
Caption = ' Established routes '
|
||||||
Padding.Left = 10
|
Padding.Left = 10
|
||||||
Padding.Top = 10
|
Padding.Top = 10
|
||||||
Padding.Right = 10
|
Padding.Right = 10
|
||||||
@ -261,6 +265,7 @@ object MediaRouterFrm: TMediaRouterFrm
|
|||||||
Align = alClient
|
Align = alClient
|
||||||
ItemHeight = 13
|
ItemHeight = 13
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
|
OnClick = RoutesLbxClick
|
||||||
end
|
end
|
||||||
object RoutesButtonPnl: TPanel
|
object RoutesButtonPnl: TPanel
|
||||||
Left = 12
|
Left = 12
|
||||||
|
@ -72,7 +72,6 @@ type
|
|||||||
CreateRouteBtn: TButton;
|
CreateRouteBtn: TButton;
|
||||||
CentralPnl: TPanel;
|
CentralPnl: TPanel;
|
||||||
SourcePnl: TPanel;
|
SourcePnl: TPanel;
|
||||||
SourceURNEdt: TEdit;
|
|
||||||
SourceLblPnl: TPanel;
|
SourceLblPnl: TPanel;
|
||||||
SourceURNLbl: TLabel;
|
SourceURNLbl: TLabel;
|
||||||
RoutesGbx: TGroupBox;
|
RoutesGbx: TGroupBox;
|
||||||
@ -90,6 +89,7 @@ type
|
|||||||
NotifyRoutesBtn: TButton;
|
NotifyRoutesBtn: TButton;
|
||||||
ClearLogPnl: TPanel;
|
ClearLogPnl: TPanel;
|
||||||
ClearLogBtn: TButton;
|
ClearLogBtn: TButton;
|
||||||
|
SourceURNCbx: TComboBox;
|
||||||
|
|
||||||
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
@ -115,6 +115,7 @@ type
|
|||||||
procedure NotifyRoutesBtnClick(Sender: TObject);
|
procedure NotifyRoutesBtnClick(Sender: TObject);
|
||||||
procedure ClearLogBtnClick(Sender: TObject);
|
procedure ClearLogBtnClick(Sender: TObject);
|
||||||
procedure MessageMemChange(Sender: TObject);
|
procedure MessageMemChange(Sender: TObject);
|
||||||
|
procedure RoutesLbxClick(Sender: TObject);
|
||||||
|
|
||||||
protected
|
protected
|
||||||
// Variables to control when can we destroy the form safely
|
// Variables to control when can we destroy the form safely
|
||||||
@ -162,16 +163,63 @@ uses
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
uCEFMiscFunctions;
|
uCEFMiscFunctions;
|
||||||
|
|
||||||
|
// This demo can use a MediaRouter to communicate with devices on the local
|
||||||
|
// network via the CAST and DIAL protocols.
|
||||||
|
|
||||||
|
// TChromium exposes all the ICefMediaObserver events and the ICefMediaRouter
|
||||||
|
// methods to show the available devices, to established communication routes
|
||||||
|
// and to send messages to those devices.
|
||||||
|
|
||||||
|
// Follow these steps to test this demo :
|
||||||
|
|
||||||
|
// STEP 1
|
||||||
|
// ------
|
||||||
|
// Turn on your ChromeCast receiver. It can be an Android TV or similar device
|
||||||
|
// like a Xiaomi MiBox. It must be on the same local network as the computer
|
||||||
|
// running this demo.
|
||||||
|
|
||||||
|
// STEP 2
|
||||||
|
// ------
|
||||||
|
// Run this demo and wait a few seconds. It will show all the available devices
|
||||||
|
// in the local network and the protocol used to communicate with them.
|
||||||
|
// In the case of the MiBox device it shows a DIAL and a CAST "sink" but after
|
||||||
|
// a couple of secods the list is updated and it only shows the CAST sink.
|
||||||
|
|
||||||
|
// STEP 3
|
||||||
|
// ------
|
||||||
|
// Select the CAST sink and click on the "Create route" button. This button will
|
||||||
|
// use the "Source URN" value to create the route and that value has a CAST URN
|
||||||
|
// with the "Application ID" of the "Default Media Receiver", which is CC1AD845.
|
||||||
|
// This ID can be used for tests.
|
||||||
|
|
||||||
|
// STEP 4
|
||||||
|
// ------
|
||||||
|
// The "Established routes" box will show the routes that you created.
|
||||||
|
|
||||||
|
// STEP 5
|
||||||
|
// ------
|
||||||
|
// Select the route, type the message and click on the "Send message" button.
|
||||||
|
|
||||||
|
// STEP 6
|
||||||
|
// ------
|
||||||
|
// Click on the "Terminate route" button.
|
||||||
|
|
||||||
|
// WARNING
|
||||||
|
// =======
|
||||||
|
// This demo has a known bug when you close the form and it will crash.
|
||||||
|
|
||||||
|
// References :
|
||||||
|
// ============
|
||||||
|
// https://bitbucket.org/chromiumembedded/cef/issues/2900/add-mediarouter-support-for-cast-receiver
|
||||||
|
// https://blog.oakbits.com/google-cast-protocol-overview.html
|
||||||
|
// https://developers.google.com/cast/docs/developers
|
||||||
|
// https://gist.github.com/jloutsenhizer/8855258
|
||||||
|
|
||||||
procedure CreateGlobalCEFApp;
|
procedure CreateGlobalCEFApp;
|
||||||
begin
|
begin
|
||||||
GlobalCEFApp := TCefApplication.Create;
|
GlobalCEFApp := TCefApplication.Create;
|
||||||
GlobalCEFApp.LogFile := 'debug.log';
|
GlobalCEFApp.LogFile := 'debug.log';
|
||||||
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; //LOGSEVERITY_VERBOSE;
|
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
|
||||||
{
|
|
||||||
GlobalCEFApp.FrameworkDirPath := 'c:\cef';
|
|
||||||
GlobalCEFApp.ResourcesDirPath := 'c:\cef';
|
|
||||||
GlobalCEFApp.LocalesDirPath := 'c:\cef\locales';
|
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMediaRouterFrm.Chromium1AfterCreated(Sender: TObject;
|
procedure TMediaRouterFrm.Chromium1AfterCreated(Sender: TObject;
|
||||||
@ -411,6 +459,8 @@ begin
|
|||||||
if (FLog <> nil) and (FLog.Count > 0) then
|
if (FLog <> nil) and (FLog.Count > 0) then
|
||||||
begin
|
begin
|
||||||
LogMem.Lines.AddStrings(FLog);
|
LogMem.Lines.AddStrings(FLog);
|
||||||
|
LogMem.SelLength := 0;
|
||||||
|
LogMem.SelStart := Length(LogMem.Text);
|
||||||
FLog.Clear;
|
FLog.Clear;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
@ -427,6 +477,11 @@ begin
|
|||||||
UpdateButtons;
|
UpdateButtons;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.RoutesLbxClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMediaRouterFrm.RefreshRoutesMsg(var aMessage : TMessage);
|
procedure TMediaRouterFrm.RefreshRoutesMsg(var aMessage : TMessage);
|
||||||
begin
|
begin
|
||||||
if FClosing then exit;
|
if FClosing then exit;
|
||||||
@ -572,7 +627,7 @@ var
|
|||||||
TempURN, TempErrorMsg : string;
|
TempURN, TempErrorMsg : string;
|
||||||
TempSource : ICefMediaSource;
|
TempSource : ICefMediaSource;
|
||||||
begin
|
begin
|
||||||
TempURN := trim(SourceURNEdt.Text);
|
TempURN := trim(SourceURNCbx.Text);
|
||||||
|
|
||||||
if (length(TempURN) = 0) then
|
if (length(TempURN) = 0) then
|
||||||
begin
|
begin
|
||||||
@ -619,6 +674,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
|
TempSource := nil;
|
||||||
FMediaCS.Release;
|
FMediaCS.Release;
|
||||||
if (length(TempErrorMsg) > 0) then AddLogEntry(TempErrorMsg);
|
if (length(TempErrorMsg) > 0) then AddLogEntry(TempErrorMsg);
|
||||||
end;
|
end;
|
||||||
@ -682,7 +738,7 @@ begin
|
|||||||
(length(trim(MessageMem.Lines.Text)) > 0);
|
(length(trim(MessageMem.Lines.Text)) > 0);
|
||||||
|
|
||||||
CreateRouteBtn.Enabled := not(TerminateRouteBtn.Enabled) and
|
CreateRouteBtn.Enabled := not(TerminateRouteBtn.Enabled) and
|
||||||
(length(trim(SourceURNEdt.Text)) > 0) and
|
(length(trim(SourceURNCbx.Text)) > 0) and
|
||||||
(SinksLbx.ItemIndex >= 0) and
|
(SinksLbx.ItemIndex >= 0) and
|
||||||
(SinksLbx.Items.Count > 0);
|
(SinksLbx.Items.Count > 0);
|
||||||
end;
|
end;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<MainSource>PopupBrowser.dpr</MainSource>
|
<MainSource>PopupBrowser.dpr</MainSource>
|
||||||
<Base>True</Base>
|
<Base>True</Base>
|
||||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||||
<TargetedPlatforms>3</TargetedPlatforms>
|
<TargetedPlatforms>3</TargetedPlatforms>
|
||||||
<AppType>Application</AppType>
|
<AppType>Application</AppType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -232,6 +232,8 @@ begin
|
|||||||
GlobalCEFApp.EnableHighDPISupport := True;
|
GlobalCEFApp.EnableHighDPISupport := True;
|
||||||
GlobalCEFApp.TouchEvents := STATE_ENABLED;
|
GlobalCEFApp.TouchEvents := STATE_ENABLED;
|
||||||
//GlobalCEFApp.EnableGPU := True;
|
//GlobalCEFApp.EnableGPU := True;
|
||||||
|
GlobalCEFApp.LogFile := 'debug.log';
|
||||||
|
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
|
||||||
|
|
||||||
// If you need transparency leave the GlobalCEFApp.BackgroundColor property
|
// If you need transparency leave the GlobalCEFApp.BackgroundColor property
|
||||||
// with the default value or set the alpha channel to 0
|
// with the default value or set the alpha channel to 0
|
||||||
|
2
demos/Lazarus/MediaRouter/00-Delete.bat
Normal file
2
demos/Lazarus/MediaRouter/00-Delete.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
rmdir /S /Q lib
|
||||||
|
rmdir /S /Q backup
|
91
demos/Lazarus/MediaRouter/MediaRouter.lpi
Normal file
91
demos/Lazarus/MediaRouter/MediaRouter.lpi
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasUsesSectionForAllUnits Value="False"/>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
<MainUnitHasScaledStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<Title Value="MediaRouter"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<BuildModes Count="1">
|
||||||
|
<Item1 Name="Default" Default="True"/>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<UseFileFilters Value="True"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<FormatVersion Value="2"/>
|
||||||
|
<Modes Count="0"/>
|
||||||
|
</RunParams>
|
||||||
|
<RequiredPackages Count="2">
|
||||||
|
<Item1>
|
||||||
|
<PackageName Value="CEF4Delphi_Lazarus"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<PackageName Value="LCL"/>
|
||||||
|
</Item2>
|
||||||
|
</RequiredPackages>
|
||||||
|
<Units Count="2">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="MediaRouter.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="uMediaRouterFrm.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="MediaRouterFrm"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
</Unit1>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="..\..\..\bin\MediaRouter"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Parsing>
|
||||||
|
<SyntaxOptions>
|
||||||
|
<SyntaxMode Value="Delphi"/>
|
||||||
|
</SyntaxOptions>
|
||||||
|
</Parsing>
|
||||||
|
<Linking>
|
||||||
|
<Options>
|
||||||
|
<Win32>
|
||||||
|
<GraphicApplication Value="True"/>
|
||||||
|
</Win32>
|
||||||
|
</Options>
|
||||||
|
</Linking>
|
||||||
|
<Other>
|
||||||
|
<CustomOptions Value="-dBorland -dVer150 -dDelphi7 -dCompiler6_Up -dPUREPASCAL"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions Count="3">
|
||||||
|
<Item1>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item1>
|
||||||
|
<Item2>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item2>
|
||||||
|
<Item3>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item3>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
72
demos/Lazarus/MediaRouter/MediaRouter.lpr
Normal file
72
demos/Lazarus/MediaRouter/MediaRouter.lpr
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// ************************************************************************
|
||||||
|
// ***************************** CEF4Delphi *******************************
|
||||||
|
// ************************************************************************
|
||||||
|
//
|
||||||
|
// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based
|
||||||
|
// browser in Delphi applications.
|
||||||
|
//
|
||||||
|
// The original license of DCEF3 still applies to CEF4Delphi.
|
||||||
|
//
|
||||||
|
// For more information about CEF4Delphi visit :
|
||||||
|
// https://www.briskbard.com/index.php?lang=en&pageid=cef
|
||||||
|
//
|
||||||
|
// Copyright © 2020 Salvador Diaz Fau. All rights reserved.
|
||||||
|
//
|
||||||
|
// ************************************************************************
|
||||||
|
// ************ vvvv Original license and comments below vvvv *************
|
||||||
|
// ************************************************************************
|
||||||
|
(*
|
||||||
|
* Delphi Chromium Embedded 3
|
||||||
|
*
|
||||||
|
* Usage allowed under the restrictions of the Lesser GNU General Public License
|
||||||
|
* or alternatively the restrictions of the Mozilla Public License 1.1
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||||
|
* the specific language governing rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* Unit owner : Henri Gourvest <hgourvest@gmail.com>
|
||||||
|
* Web site : http://www.progdigy.com
|
||||||
|
* Repository : http://code.google.com/p/delphichromiumembedded/
|
||||||
|
* Group : http://groups.google.com/group/delphichromiumembedded
|
||||||
|
*
|
||||||
|
* Embarcadero Technologies, Inc is not permitted to use or redistribute
|
||||||
|
* this source code without explicit permission.
|
||||||
|
*
|
||||||
|
*)
|
||||||
|
|
||||||
|
program MediaRouter;
|
||||||
|
|
||||||
|
{$MODE Delphi}
|
||||||
|
|
||||||
|
{$I cef.inc}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF DELPHI16_UP}
|
||||||
|
Vcl.Forms,
|
||||||
|
WinApi.Windows,
|
||||||
|
{$ELSE}
|
||||||
|
Windows,
|
||||||
|
Forms,
|
||||||
|
LCLIntf, LCLType, LMessages, Interfaces,
|
||||||
|
{$ENDIF }
|
||||||
|
uCEFApplication,
|
||||||
|
uMediaRouterFrm in 'uMediaRouterFrm.pas' {MediaRouterFrm};
|
||||||
|
|
||||||
|
{.$R *.res}
|
||||||
|
|
||||||
|
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
|
||||||
|
|
||||||
|
begin
|
||||||
|
CreateGlobalCEFApp;
|
||||||
|
|
||||||
|
if GlobalCEFApp.StartMainProcess then
|
||||||
|
begin
|
||||||
|
Application.Initialize;
|
||||||
|
Application.MainFormOnTaskbar := True;
|
||||||
|
Application.CreateForm(TMediaRouterFrm, MediaRouterFrm);
|
||||||
|
Application.Run;
|
||||||
|
end;
|
||||||
|
|
||||||
|
DestroyGlobalCEFApp;
|
||||||
|
end.
|
44
demos/Lazarus/MediaRouter/MediaRouter.lps
Normal file
44
demos/Lazarus/MediaRouter/MediaRouter.lps
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectSession>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<BuildModes Active="Default"/>
|
||||||
|
<Units Count="2">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="MediaRouter.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<TopLine Value="42"/>
|
||||||
|
<CursorPos X="37" Y="66"/>
|
||||||
|
<UsageCount Value="20"/>
|
||||||
|
<Loaded Value="True"/>
|
||||||
|
<DefaultSyntaxHighlighter Value="Delphi"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="uMediaRouterFrm.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="MediaRouterFrm"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
<IsVisibleTab Value="True"/>
|
||||||
|
<EditorIndex Value="1"/>
|
||||||
|
<TopLine Value="553"/>
|
||||||
|
<CursorPos X="29" Y="49"/>
|
||||||
|
<UsageCount Value="20"/>
|
||||||
|
<Loaded Value="True"/>
|
||||||
|
<LoadedDesigner Value="True"/>
|
||||||
|
<DefaultSyntaxHighlighter Value="Delphi"/>
|
||||||
|
</Unit1>
|
||||||
|
</Units>
|
||||||
|
<JumpHistory Count="1">
|
||||||
|
<Position1>
|
||||||
|
<Filename Value="MediaRouter.lpr"/>
|
||||||
|
<Caret Line="49" Column="11" TopLine="42"/>
|
||||||
|
</Position1>
|
||||||
|
</JumpHistory>
|
||||||
|
<RunParams>
|
||||||
|
<FormatVersion Value="2"/>
|
||||||
|
<Modes Count="0" ActiveMode=""/>
|
||||||
|
</RunParams>
|
||||||
|
</ProjectSession>
|
||||||
|
</CONFIG>
|
409
demos/Lazarus/MediaRouter/cef.inc
Normal file
409
demos/Lazarus/MediaRouter/cef.inc
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
// ************************************************************************
|
||||||
|
// ***************************** CEF4Delphi *******************************
|
||||||
|
// ************************************************************************
|
||||||
|
//
|
||||||
|
// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based
|
||||||
|
// browser in Delphi applications.
|
||||||
|
//
|
||||||
|
// The original license of DCEF3 still applies to CEF4Delphi.
|
||||||
|
//
|
||||||
|
// For more information about CEF4Delphi visit :
|
||||||
|
// https://www.briskbard.com/index.php?lang=en&pageid=cef
|
||||||
|
//
|
||||||
|
// Copyright © 2017 Salvador Diaz Fau. All rights reserved.
|
||||||
|
//
|
||||||
|
// ************************************************************************
|
||||||
|
// ************ vvvv Original license and comments below vvvv *************
|
||||||
|
// ************************************************************************
|
||||||
|
(*
|
||||||
|
* Delphi Chromium Embedded 3
|
||||||
|
*
|
||||||
|
* Usage allowed under the restrictions of the Lesser GNU General Public License
|
||||||
|
* or alternatively the restrictions of the Mozilla Public License 1.1
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||||
|
* the specific language governing rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* Unit owner : Henri Gourvest <hgourvest@gmail.com>
|
||||||
|
* Web site : http://www.progdigy.com
|
||||||
|
* Repository : http://code.google.com/p/delphichromiumembedded/
|
||||||
|
* Group : http://groups.google.com/group/delphichromiumembedded
|
||||||
|
*
|
||||||
|
* Embarcadero Technologies, Inc is not permitted to use or redistribute
|
||||||
|
* this source code without explicit permission.
|
||||||
|
*
|
||||||
|
*)
|
||||||
|
|
||||||
|
// The complete list of compiler versions is here :
|
||||||
|
// http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions
|
||||||
|
|
||||||
|
{$DEFINE DELPHI_VERSION_UNKNOW}
|
||||||
|
|
||||||
|
// Delphi 5
|
||||||
|
{$IFDEF VER130}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi 6
|
||||||
|
{$IFDEF VER140}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi 7
|
||||||
|
{$IFDEF VER150}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi 8
|
||||||
|
{$IFDEF VER160}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi 2005
|
||||||
|
{$IFDEF VER170}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF VER180}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
// Delphi 2007
|
||||||
|
{$IFDEF VER185}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
// Delphi 2006
|
||||||
|
{$ELSE}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi 2009
|
||||||
|
{$IFDEF VER200}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
//Delphi 2010
|
||||||
|
{$IFDEF VER210}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE
|
||||||
|
{$IFDEF VER220}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE2 (First FireMonkey and 64bit compiler)
|
||||||
|
{$IFDEF VER230}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE3
|
||||||
|
{$IFDEF VER240}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE4
|
||||||
|
{$IFDEF VER250}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE5
|
||||||
|
{$IFDEF VER260}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE6
|
||||||
|
{$IFDEF VER270}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE7
|
||||||
|
{$IFDEF VER280}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Delphi XE8
|
||||||
|
{$IFDEF VER290}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$DEFINE DELPHI22_UP}
|
||||||
|
{$ENDIF VER290}
|
||||||
|
|
||||||
|
// Rad Studio 10 - Delphi Seattle
|
||||||
|
{$IFDEF VER300}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$DEFINE DELPHI22_UP}
|
||||||
|
{$DEFINE DELPHI23_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Rad Studio 10.1 - Delphi Berlin
|
||||||
|
{$IFDEF VER310}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$DEFINE DELPHI22_UP}
|
||||||
|
{$DEFINE DELPHI23_UP}
|
||||||
|
{$DEFINE DELPHI24_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Rad Studio 10.2 - Delphi Tokyo
|
||||||
|
{$IFDEF VER320}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$DEFINE DELPHI22_UP}
|
||||||
|
{$DEFINE DELPHI23_UP}
|
||||||
|
{$DEFINE DELPHI24_UP}
|
||||||
|
{$DEFINE DELPHI25_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// Rad Studio 10.3 - Delphi Rio
|
||||||
|
{$IFDEF VER330}
|
||||||
|
{$UNDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$DEFINE DELPHI22_UP}
|
||||||
|
{$DEFINE DELPHI23_UP}
|
||||||
|
{$DEFINE DELPHI24_UP}
|
||||||
|
{$DEFINE DELPHI25_UP}
|
||||||
|
{$DEFINE DELPHI26_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF FPC}
|
||||||
|
{$DEFINE SUPPORTS_INLINE}
|
||||||
|
{$ELSE}
|
||||||
|
{$IFDEF DELPHI_VERSION_UNKNOW}
|
||||||
|
{$DEFINE DELPHI5_UP}
|
||||||
|
{$DEFINE DELPHI6_UP}
|
||||||
|
{$DEFINE DELPHI7_UP}
|
||||||
|
{$DEFINE DELPHI8_UP}
|
||||||
|
{$DEFINE DELPHI9_UP}
|
||||||
|
{$DEFINE DELPHI10_UP}
|
||||||
|
{$DEFINE DELPHI11_UP}
|
||||||
|
{$DEFINE DELPHI12_UP}
|
||||||
|
{$DEFINE DELPHI14_UP}
|
||||||
|
{$DEFINE DELPHI15_UP}
|
||||||
|
{$DEFINE DELPHI16_UP}
|
||||||
|
{$DEFINE DELPHI17_UP}
|
||||||
|
{$DEFINE DELPHI18_UP}
|
||||||
|
{$DEFINE DELPHI19_UP}
|
||||||
|
{$DEFINE DELPHI20_UP}
|
||||||
|
{$DEFINE DELPHI21_UP}
|
||||||
|
{$DEFINE DELPHI22_UP}
|
||||||
|
{$DEFINE DELPHI23_UP}
|
||||||
|
{$DEFINE DELPHI24_UP}
|
||||||
|
{$DEFINE DELPHI25_UP}
|
||||||
|
{$DEFINE DELPHI26_UP}
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF DELPHI9_UP}
|
||||||
|
{$DEFINE SUPPORTS_INLINE}
|
||||||
|
{$ENDIF}
|
||||||
|
|
316
demos/Lazarus/MediaRouter/uMediaRouterFrm.lfm
Normal file
316
demos/Lazarus/MediaRouter/uMediaRouterFrm.lfm
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
object MediaRouterFrm: TMediaRouterFrm
|
||||||
|
Left = 363
|
||||||
|
Height = 757
|
||||||
|
Top = 75
|
||||||
|
Width = 1029
|
||||||
|
Caption = 'Media Router'
|
||||||
|
ClientHeight = 757
|
||||||
|
ClientWidth = 1029
|
||||||
|
Color = clBtnFace
|
||||||
|
Font.Color = clWindowText
|
||||||
|
Font.Height = -11
|
||||||
|
Font.Name = 'Tahoma'
|
||||||
|
OnCloseQuery = FormCloseQuery
|
||||||
|
OnCreate = FormCreate
|
||||||
|
OnDestroy = FormDestroy
|
||||||
|
OnShow = FormShow
|
||||||
|
Position = poScreenCenter
|
||||||
|
LCLVersion = '2.0.8.0'
|
||||||
|
object CEFWindowParent1: TCEFWindowParent
|
||||||
|
Left = 184
|
||||||
|
Height = 0
|
||||||
|
Top = 56
|
||||||
|
Width = 0
|
||||||
|
TabOrder = 0
|
||||||
|
Visible = False
|
||||||
|
Enabled = False
|
||||||
|
end
|
||||||
|
object MainPnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 757
|
||||||
|
Top = 0
|
||||||
|
Width = 1029
|
||||||
|
Align = alClient
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 757
|
||||||
|
ClientWidth = 1029
|
||||||
|
TabOrder = 1
|
||||||
|
object SinksGbx: TGroupBox
|
||||||
|
Left = 0
|
||||||
|
Height = 757
|
||||||
|
Top = 0
|
||||||
|
Width = 250
|
||||||
|
Align = alLeft
|
||||||
|
Caption = ' Sinks on this network '
|
||||||
|
ClientHeight = 739
|
||||||
|
ClientWidth = 246
|
||||||
|
TabOrder = 0
|
||||||
|
object SinksLbx: TListBox
|
||||||
|
Left = 0
|
||||||
|
Height = 679
|
||||||
|
Top = 0
|
||||||
|
Width = 246
|
||||||
|
Align = alClient
|
||||||
|
ItemHeight = 0
|
||||||
|
OnClick = SinksLbxClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object SinksButtonsPnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 60
|
||||||
|
Top = 679
|
||||||
|
Width = 246
|
||||||
|
Align = alBottom
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 60
|
||||||
|
ClientWidth = 246
|
||||||
|
TabOrder = 1
|
||||||
|
object CreateRouteBtn: TButton
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 0
|
||||||
|
Width = 246
|
||||||
|
Align = alTop
|
||||||
|
Caption = 'Create route'
|
||||||
|
Enabled = False
|
||||||
|
OnClick = CreateRouteBtnClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object NotifySinksBtn: TButton
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 33
|
||||||
|
Width = 246
|
||||||
|
Align = alBottom
|
||||||
|
Caption = 'Notify sinks'
|
||||||
|
OnClick = NotifySinksBtnClick
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object CentralPnl: TPanel
|
||||||
|
Left = 250
|
||||||
|
Height = 757
|
||||||
|
Top = 0
|
||||||
|
Width = 529
|
||||||
|
Align = alClient
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 757
|
||||||
|
ClientWidth = 529
|
||||||
|
TabOrder = 1
|
||||||
|
object SourcePnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 21
|
||||||
|
Top = 0
|
||||||
|
Width = 529
|
||||||
|
Align = alTop
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 21
|
||||||
|
ClientWidth = 529
|
||||||
|
TabOrder = 0
|
||||||
|
object SourceLblPnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 21
|
||||||
|
Top = 0
|
||||||
|
Width = 65
|
||||||
|
Align = alLeft
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 21
|
||||||
|
ClientWidth = 65
|
||||||
|
TabOrder = 0
|
||||||
|
object SourceURNLbl: TLabel
|
||||||
|
Left = 0
|
||||||
|
Height = 21
|
||||||
|
Top = 0
|
||||||
|
Width = 65
|
||||||
|
Align = alClient
|
||||||
|
Caption = 'Source URN'
|
||||||
|
Layout = tlCenter
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object SourceURNCbx: TComboBox
|
||||||
|
Left = 65
|
||||||
|
Height = 21
|
||||||
|
Top = 0
|
||||||
|
Width = 464
|
||||||
|
Align = alClient
|
||||||
|
ItemHeight = 13
|
||||||
|
ItemIndex = 1
|
||||||
|
Items.Strings = (
|
||||||
|
'cast:<appId>?clientId=<clientId>'
|
||||||
|
'cast:CC1AD845?clientId=123456789'
|
||||||
|
'cast:4F8B3483?clientId=123456789'
|
||||||
|
)
|
||||||
|
TabOrder = 1
|
||||||
|
Text = 'cast:CC1AD845?clientId=123456789'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object MessageGbx: TGroupBox
|
||||||
|
Left = 0
|
||||||
|
Height = 430
|
||||||
|
Top = 327
|
||||||
|
Width = 529
|
||||||
|
Align = alClient
|
||||||
|
Caption = ' Message '
|
||||||
|
ClientHeight = 412
|
||||||
|
ClientWidth = 525
|
||||||
|
TabOrder = 1
|
||||||
|
object SendMessagePnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 385
|
||||||
|
Width = 525
|
||||||
|
Align = alBottom
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 27
|
||||||
|
ClientWidth = 525
|
||||||
|
TabOrder = 0
|
||||||
|
object SendMsgBtn: TButton
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 0
|
||||||
|
Width = 525
|
||||||
|
Align = alClient
|
||||||
|
Caption = 'Send message'
|
||||||
|
OnClick = SendMsgBtnClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object MessageMem: TMemo
|
||||||
|
Left = 0
|
||||||
|
Height = 385
|
||||||
|
Top = 0
|
||||||
|
Width = 525
|
||||||
|
Align = alClient
|
||||||
|
OnChange = MessageMemChange
|
||||||
|
ScrollBars = ssBoth
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object LogGbx: TGroupBox
|
||||||
|
Left = 0
|
||||||
|
Height = 296
|
||||||
|
Top = 21
|
||||||
|
Width = 529
|
||||||
|
Align = alTop
|
||||||
|
Caption = ' Log '
|
||||||
|
ClientHeight = 278
|
||||||
|
ClientWidth = 525
|
||||||
|
TabOrder = 2
|
||||||
|
object LogMem: TMemo
|
||||||
|
Left = 0
|
||||||
|
Height = 251
|
||||||
|
Top = 0
|
||||||
|
Width = 525
|
||||||
|
Align = alClient
|
||||||
|
ReadOnly = True
|
||||||
|
ScrollBars = ssBoth
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object ClearLogPnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 251
|
||||||
|
Width = 525
|
||||||
|
Align = alBottom
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 27
|
||||||
|
ClientWidth = 525
|
||||||
|
TabOrder = 1
|
||||||
|
object ClearLogBtn: TButton
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 0
|
||||||
|
Width = 525
|
||||||
|
Align = alClient
|
||||||
|
Caption = 'Clear log'
|
||||||
|
OnClick = ClearLogBtnClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object SpacerPnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 10
|
||||||
|
Top = 317
|
||||||
|
Width = 529
|
||||||
|
Align = alTop
|
||||||
|
BevelOuter = bvNone
|
||||||
|
TabOrder = 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object RoutesGbx: TGroupBox
|
||||||
|
Left = 779
|
||||||
|
Height = 757
|
||||||
|
Top = 0
|
||||||
|
Width = 250
|
||||||
|
Align = alRight
|
||||||
|
Caption = ' Established routes '
|
||||||
|
ClientHeight = 739
|
||||||
|
ClientWidth = 246
|
||||||
|
TabOrder = 2
|
||||||
|
object RoutesLbx: TListBox
|
||||||
|
Left = 0
|
||||||
|
Height = 679
|
||||||
|
Top = 0
|
||||||
|
Width = 246
|
||||||
|
Align = alClient
|
||||||
|
ItemHeight = 0
|
||||||
|
OnClick = RoutesLbxClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object RoutesButtonPnl: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 60
|
||||||
|
Top = 679
|
||||||
|
Width = 246
|
||||||
|
Align = alBottom
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 60
|
||||||
|
ClientWidth = 246
|
||||||
|
TabOrder = 1
|
||||||
|
object TerminateRouteBtn: TButton
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 0
|
||||||
|
Width = 246
|
||||||
|
Align = alTop
|
||||||
|
Caption = 'Terminate route'
|
||||||
|
Enabled = False
|
||||||
|
OnClick = TerminateRouteBtnClick
|
||||||
|
TabOrder = 0
|
||||||
|
end
|
||||||
|
object NotifyRoutesBtn: TButton
|
||||||
|
Left = 0
|
||||||
|
Height = 27
|
||||||
|
Top = 33
|
||||||
|
Width = 246
|
||||||
|
Align = alBottom
|
||||||
|
Caption = 'Notify routes'
|
||||||
|
OnClick = NotifyRoutesBtnClick
|
||||||
|
TabOrder = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object Chromium1: TChromium
|
||||||
|
OnMediaRouteCreateFinished = Chromium1MediaRouteCreateFinished
|
||||||
|
OnAfterCreated = Chromium1AfterCreated
|
||||||
|
OnBeforeClose = Chromium1BeforeClose
|
||||||
|
OnClose = Chromium1Close
|
||||||
|
OnSinks = Chromium1Sinks
|
||||||
|
OnRoutes = Chromium1Routes
|
||||||
|
OnRouteStateChanged = Chromium1RouteStateChanged
|
||||||
|
OnRouteMessageReceived = Chromium1RouteMessageReceived
|
||||||
|
left = 72
|
||||||
|
top = 56
|
||||||
|
end
|
||||||
|
object Timer1: TTimer
|
||||||
|
Enabled = False
|
||||||
|
Interval = 300
|
||||||
|
OnTimer = Timer1Timer
|
||||||
|
left = 72
|
||||||
|
top = 136
|
||||||
|
end
|
||||||
|
end
|
774
demos/Lazarus/MediaRouter/uMediaRouterFrm.pas
Normal file
774
demos/Lazarus/MediaRouter/uMediaRouterFrm.pas
Normal file
@ -0,0 +1,774 @@
|
|||||||
|
// ************************************************************************
|
||||||
|
// ***************************** CEF4Delphi *******************************
|
||||||
|
// ************************************************************************
|
||||||
|
//
|
||||||
|
// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based
|
||||||
|
// browser in Delphi applications.
|
||||||
|
//
|
||||||
|
// The original license of DCEF3 still applies to CEF4Delphi.
|
||||||
|
//
|
||||||
|
// For more information about CEF4Delphi visit :
|
||||||
|
// https://www.briskbard.com/index.php?lang=en&pageid=cef
|
||||||
|
//
|
||||||
|
// Copyright © 2020 Salvador Diaz Fau. All rights reserved.
|
||||||
|
//
|
||||||
|
// ************************************************************************
|
||||||
|
// ************ vvvv Original license and comments below vvvv *************
|
||||||
|
// ************************************************************************
|
||||||
|
(*
|
||||||
|
* Delphi Chromium Embedded 3
|
||||||
|
*
|
||||||
|
* Usage allowed under the restrictions of the Lesser GNU General Public License
|
||||||
|
* or alternatively the restrictions of the Mozilla Public License 1.1
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||||
|
* the specific language governing rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* Unit owner : Henri Gourvest <hgourvest@gmail.com>
|
||||||
|
* Web site : http://www.progdigy.com
|
||||||
|
* Repository : http://code.google.com/p/delphichromiumembedded/
|
||||||
|
* Group : http://groups.google.com/group/delphichromiumembedded
|
||||||
|
*
|
||||||
|
* Embarcadero Technologies, Inc is not permitted to use or redistribute
|
||||||
|
* this source code without explicit permission.
|
||||||
|
*
|
||||||
|
*)
|
||||||
|
|
||||||
|
unit uMediaRouterFrm;
|
||||||
|
|
||||||
|
{$MODE Delphi}
|
||||||
|
|
||||||
|
{$I cef.inc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics, Menus,
|
||||||
|
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd,
|
||||||
|
ActiveX, ShlObj, SyncObjs,
|
||||||
|
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
|
||||||
|
uCEFWinControl, uCEFSentinel, uCEFChromiumCore;
|
||||||
|
|
||||||
|
const
|
||||||
|
MEDIA_ROUTER_PENDING_LOG_LINES = WM_APP + $B00;
|
||||||
|
MEDIA_ROUTER_REFRESH_SINKS = WM_APP + $B01;
|
||||||
|
MEDIA_ROUTER_REFRESH_ROUTES = WM_APP + $B02;
|
||||||
|
MEDIA_ROUTER_UPDATE_BUTTONS = WM_APP + $B03;
|
||||||
|
|
||||||
|
type
|
||||||
|
TMediaRouterFrm = class(TForm)
|
||||||
|
Chromium1: TChromium;
|
||||||
|
CEFWindowParent1: TCEFWindowParent;
|
||||||
|
Timer1: TTimer;
|
||||||
|
MainPnl: TPanel;
|
||||||
|
SinksGbx: TGroupBox;
|
||||||
|
SinksLbx: TListBox;
|
||||||
|
SinksButtonsPnl: TPanel;
|
||||||
|
CreateRouteBtn: TButton;
|
||||||
|
CentralPnl: TPanel;
|
||||||
|
SourcePnl: TPanel;
|
||||||
|
SourceLblPnl: TPanel;
|
||||||
|
SourceURNLbl: TLabel;
|
||||||
|
RoutesGbx: TGroupBox;
|
||||||
|
RoutesLbx: TListBox;
|
||||||
|
RoutesButtonPnl: TPanel;
|
||||||
|
TerminateRouteBtn: TButton;
|
||||||
|
MessageGbx: TGroupBox;
|
||||||
|
SendMessagePnl: TPanel;
|
||||||
|
SendMsgBtn: TButton;
|
||||||
|
MessageMem: TMemo;
|
||||||
|
LogGbx: TGroupBox;
|
||||||
|
LogMem: TMemo;
|
||||||
|
SpacerPnl: TPanel;
|
||||||
|
NotifySinksBtn: TButton;
|
||||||
|
NotifyRoutesBtn: TButton;
|
||||||
|
ClearLogPnl: TPanel;
|
||||||
|
ClearLogBtn: TButton;
|
||||||
|
SourceURNCbx: TComboBox;
|
||||||
|
|
||||||
|
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
|
procedure FormDestroy(Sender: TObject);
|
||||||
|
procedure FormShow(Sender: TObject);
|
||||||
|
|
||||||
|
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
|
||||||
|
procedure Chromium1Sinks(Sender: TObject; const sinks: TCefMediaSinkArray);
|
||||||
|
procedure Chromium1Routes(Sender: TObject; const routes: TCefMediaRouteArray);
|
||||||
|
procedure Chromium1RouteStateChanged(Sender: TObject; const route: ICefMediaRoute; state: TCefMediaRouteConnectionState);
|
||||||
|
procedure Chromium1RouteMessageReceived(Sender: TObject; const route: ICefMediaRoute; const message_: ustring);
|
||||||
|
procedure Chromium1MediaRouteCreateFinished(Sender: TObject; result: Integer; const error: ustring; const route: ICefMediaRoute);
|
||||||
|
|
||||||
|
procedure Timer1Timer(Sender: TObject);
|
||||||
|
procedure SourceURNEdtChange(Sender: TObject);
|
||||||
|
procedure SinksLbxClick(Sender: TObject);
|
||||||
|
procedure CreateRouteBtnClick(Sender: TObject);
|
||||||
|
procedure TerminateRouteBtnClick(Sender: TObject);
|
||||||
|
procedure SendMsgBtnClick(Sender: TObject);
|
||||||
|
procedure NotifySinksBtnClick(Sender: TObject);
|
||||||
|
procedure NotifyRoutesBtnClick(Sender: TObject);
|
||||||
|
procedure ClearLogBtnClick(Sender: TObject);
|
||||||
|
procedure MessageMemChange(Sender: TObject);
|
||||||
|
procedure RoutesLbxClick(Sender: TObject);
|
||||||
|
|
||||||
|
protected
|
||||||
|
// Variables to control when can we destroy the form safely
|
||||||
|
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
|
||||||
|
FClosing : boolean; // Set to True in the CloseQuery event.
|
||||||
|
|
||||||
|
FMediaCS : TCriticalSection;
|
||||||
|
FLog : TStringList;
|
||||||
|
FSinks : TCefMediaSinkInfoArray;
|
||||||
|
FRoutes : TCefMediaRouteInfoArray;
|
||||||
|
|
||||||
|
procedure BrowserDestroyMsg(var aMessage : TMessage); message CEF_DESTROY;
|
||||||
|
procedure PendingLogLinesMsg(var aMessage : TMessage); message MEDIA_ROUTER_PENDING_LOG_LINES;
|
||||||
|
procedure RefreshSinksMsg(var aMessage : TMessage); message MEDIA_ROUTER_REFRESH_SINKS;
|
||||||
|
procedure RefreshRoutesMsg(var aMessage : TMessage); message MEDIA_ROUTER_REFRESH_ROUTES;
|
||||||
|
procedure UpdateButtonsMsg(var aMessage : TMessage); message MEDIA_ROUTER_UPDATE_BUTTONS;
|
||||||
|
|
||||||
|
procedure DestroySinksArray;
|
||||||
|
procedure DestroyRoutesArray;
|
||||||
|
procedure DestroyAllArrays;
|
||||||
|
procedure CopySinksArray(const aSinks : TCefMediaSinkArray);
|
||||||
|
procedure CopyRoutesArray(const aRoutes : TCefMediaRouteArray);
|
||||||
|
procedure UpdateAvailableSinks;
|
||||||
|
procedure UpdateAvailableRoutes;
|
||||||
|
procedure UpdateButtons;
|
||||||
|
procedure AppendPendingLogStrings;
|
||||||
|
procedure AddLogEntry(const aMessage1, aMessage2 : string; aRec : boolean); overload;
|
||||||
|
procedure AddLogEntry(const aMessage1 : string; const aMessage2 : string = ''); overload;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
MediaRouterFrm: TMediaRouterFrm;
|
||||||
|
|
||||||
|
procedure CreateGlobalCEFApp;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF DELPHI16_UP}
|
||||||
|
System.Math,
|
||||||
|
{$ELSE}
|
||||||
|
Math,
|
||||||
|
{$ENDIF}
|
||||||
|
uCEFMiscFunctions;
|
||||||
|
|
||||||
|
// This demo can use a MediaRouter to communicate with devices on the local
|
||||||
|
// network via the CAST and DIAL protocols.
|
||||||
|
|
||||||
|
// TChromium exposes all the ICefMediaObserver events and the ICefMediaRouter
|
||||||
|
// methods to show the available devices, to established communication routes
|
||||||
|
// and to send messages to those devices.
|
||||||
|
|
||||||
|
// Follow these steps to test this demo :
|
||||||
|
|
||||||
|
// STEP 1
|
||||||
|
// ------
|
||||||
|
// Turn on your ChromeCast receiver. It can be an Android TV or similar device
|
||||||
|
// like a Xiaomi MiBox. It must be on the same local network as the computer
|
||||||
|
// running this demo.
|
||||||
|
|
||||||
|
// STEP 2
|
||||||
|
// ------
|
||||||
|
// Run this demo and wait a few seconds. It will show all the available devices
|
||||||
|
// in the local network and the protocol used to communicate with them.
|
||||||
|
// In the case of the MiBox device it shows a DIAL and a CAST "sink" but after
|
||||||
|
// a couple of secods the list is updated and it only shows the CAST sink.
|
||||||
|
|
||||||
|
// STEP 3
|
||||||
|
// ------
|
||||||
|
// Select the CAST sink and click on the "Create route" button. This button will
|
||||||
|
// use the "Source URN" value to create the route and that value has a CAST URN
|
||||||
|
// with the "Application ID" of the "Default Media Receiver", which is CC1AD845.
|
||||||
|
// This ID can be used for tests.
|
||||||
|
|
||||||
|
// STEP 4
|
||||||
|
// ------
|
||||||
|
// The "Established routes" box will show the routes that you created.
|
||||||
|
|
||||||
|
// STEP 5
|
||||||
|
// ------
|
||||||
|
// Select the route, type the message and click on the "Send message" button.
|
||||||
|
|
||||||
|
// STEP 6
|
||||||
|
// ------
|
||||||
|
// Click on the "Terminate route" button.
|
||||||
|
|
||||||
|
// WARNING
|
||||||
|
// =======
|
||||||
|
// This demo has a known bug when you close the form and it will crash.
|
||||||
|
|
||||||
|
// References :
|
||||||
|
// ============
|
||||||
|
// https://bitbucket.org/chromiumembedded/cef/issues/2900/add-mediarouter-support-for-cast-receiver
|
||||||
|
// https://blog.oakbits.com/google-cast-protocol-overview.html
|
||||||
|
// https://developers.google.com/cast/docs/developers
|
||||||
|
// https://gist.github.com/jloutsenhizer/8855258
|
||||||
|
|
||||||
|
procedure CreateGlobalCEFApp;
|
||||||
|
begin
|
||||||
|
GlobalCEFApp := TCefApplication.Create;
|
||||||
|
GlobalCEFApp.LogFile := 'debug.log';
|
||||||
|
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1AfterCreated(Sender: TObject;
|
||||||
|
const browser: ICefBrowser);
|
||||||
|
begin
|
||||||
|
AddLogEntry('Browser initialized.');
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
begin
|
||||||
|
FCanClose := True;
|
||||||
|
PostMessage(Handle, WM_CLOSE, 0, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1Close(Sender: TObject;
|
||||||
|
const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
|
||||||
|
begin
|
||||||
|
PostMessage(Handle, CEF_DESTROY, 0, 0);
|
||||||
|
aAction := cbaDelay;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1MediaRouteCreateFinished(Sender: TObject;
|
||||||
|
result: Integer; const error: ustring; const route: ICefMediaRoute);
|
||||||
|
var
|
||||||
|
TempMsg, TempID : string;
|
||||||
|
begin
|
||||||
|
TempMsg := '';
|
||||||
|
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
if (result = CEF_MRCR_OK) then
|
||||||
|
begin
|
||||||
|
TempMsg := 'Route created';
|
||||||
|
if (route <> nil) then TempID := 'Route ID : ' + route.ID;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
TempMsg := error;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
if (length(TempMsg) > 0) then AddLogEntry(TempID, TempMsg);
|
||||||
|
PostMessage(Handle, MEDIA_ROUTER_UPDATE_BUTTONS, 0, 0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1RouteMessageReceived(Sender: TObject;
|
||||||
|
const route: ICefMediaRoute; const message_: ustring);
|
||||||
|
var
|
||||||
|
TempID : string;
|
||||||
|
begin
|
||||||
|
if (route <> nil) then
|
||||||
|
TempID := 'Route ID : ' + route.ID;
|
||||||
|
|
||||||
|
AddLogEntry(TempID, 'Message contents : ' + message_, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1Routes(Sender: TObject;
|
||||||
|
const routes: TCefMediaRouteArray);
|
||||||
|
begin
|
||||||
|
CopyRoutesArray(routes);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1RouteStateChanged(Sender: TObject;
|
||||||
|
const route: ICefMediaRoute; state: TCefMediaRouteConnectionState);
|
||||||
|
var
|
||||||
|
TempMsg, TempID : string;
|
||||||
|
begin
|
||||||
|
if (route <> nil) then TempID := 'Route ID : ' + route.ID;
|
||||||
|
|
||||||
|
case state of
|
||||||
|
CEF_MRCS_CONNECTING : TempMsg := 'Route state : Connecting.';
|
||||||
|
CEF_MRCS_CONNECTED : TempMsg := 'Route state : Connected.';
|
||||||
|
CEF_MRCS_CLOSED : TempMsg := 'Route state : Closed.';
|
||||||
|
CEF_MRCS_TERMINATED : TempMsg := 'Route state : Terminated.';
|
||||||
|
else TempMsg := 'Route state : Unknown.';
|
||||||
|
end;
|
||||||
|
|
||||||
|
TempMsg := TempMsg + ' ' + dateTimeToStr(now);
|
||||||
|
|
||||||
|
AddLogEntry(TempID, TempMsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Chromium1Sinks(Sender: TObject;
|
||||||
|
const sinks: TCefMediaSinkArray);
|
||||||
|
begin
|
||||||
|
CopySinksArray(sinks);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.ClearLogBtnClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
LogMem.Lines.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.FormCloseQuery(Sender: TObject;
|
||||||
|
var CanClose: Boolean);
|
||||||
|
begin
|
||||||
|
CanClose := FCanClose;
|
||||||
|
|
||||||
|
if not(FClosing) then
|
||||||
|
begin
|
||||||
|
FClosing := True;
|
||||||
|
Visible := False;
|
||||||
|
DestroyAllArrays;
|
||||||
|
Chromium1.CloseBrowser(True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.FormCreate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FCanClose := False;
|
||||||
|
FClosing := False;
|
||||||
|
FSinks := nil;
|
||||||
|
FRoutes := nil;
|
||||||
|
FMediaCS := TCriticalSection.Create;
|
||||||
|
FLog := TStringList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.FormDestroy(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FLog.Free;
|
||||||
|
FMediaCS.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.FormShow(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateButtons;
|
||||||
|
|
||||||
|
if not(Chromium1.CreateBrowser(CEFWindowParent1)) then
|
||||||
|
Timer1.Enabled := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.MessageMemChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.NotifyRoutesBtnClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Chromium1.NotifyCurrentRoutes;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.NotifySinksBtnClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Chromium1.NotifyCurrentSinks;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.SendMsgBtnClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
TempMsg, TempID : string;
|
||||||
|
begin
|
||||||
|
TempMsg := '';
|
||||||
|
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
if (RoutesLbx.Items.Count > 0) and
|
||||||
|
(FRoutes <> nil) and
|
||||||
|
(RoutesLbx.ItemIndex >= 0) and
|
||||||
|
(RoutesLbx.ItemIndex < length(FRoutes)) and
|
||||||
|
(MessageMem.Lines.Count > 0) then
|
||||||
|
begin
|
||||||
|
TempMsg := trim(MessageMem.Lines.Text);
|
||||||
|
|
||||||
|
if (length(TempMsg) > 0) and
|
||||||
|
(FRoutes[RoutesLbx.ItemIndex].RouteIntf <> nil) then
|
||||||
|
try
|
||||||
|
TempID := 'Route ID : ' + FRoutes[RoutesLbx.ItemIndex].RouteIntf.ID;
|
||||||
|
FRoutes[RoutesLbx.ItemIndex].RouteIntf.SendRouteMessage(TempMsg);
|
||||||
|
TempMsg := 'Message contents : ' + TempMsg;
|
||||||
|
except
|
||||||
|
on e : exception do
|
||||||
|
if CustomExceptionHandler('TMediaRouterFrm.SendMsgBtnClick', e) then raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
if (length(TempMsg) > 0) then AddLogEntry(TempID, TempMsg, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.SinksLbxClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.SourceURNEdtChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.TerminateRouteBtnClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
if (RoutesLbx.Items.Count > 0) and
|
||||||
|
(FRoutes <> nil) and
|
||||||
|
(RoutesLbx.ItemIndex >= 0) and
|
||||||
|
(RoutesLbx.ItemIndex < length(FRoutes)) and
|
||||||
|
(FRoutes[RoutesLbx.ItemIndex].RouteIntf <> nil) then
|
||||||
|
try
|
||||||
|
FRoutes[RoutesLbx.ItemIndex].RouteIntf.Terminate;
|
||||||
|
except
|
||||||
|
on e : exception do
|
||||||
|
if CustomExceptionHandler('TMediaRouterFrm.TerminateRouteBtnClick', e) then raise;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.Timer1Timer(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Timer1.Enabled := False;
|
||||||
|
if not(Chromium1.CreateBrowser(CEFWindowParent1)) and not(Chromium1.Initialized) then
|
||||||
|
Timer1.Enabled := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.BrowserDestroyMsg(var aMessage : TMessage);
|
||||||
|
begin
|
||||||
|
CEFWindowParent1.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.PendingLogLinesMsg(var aMessage : TMessage);
|
||||||
|
begin
|
||||||
|
if FClosing then exit;
|
||||||
|
|
||||||
|
AppendPendingLogStrings;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.AppendPendingLogStrings;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
if (FLog <> nil) and (FLog.Count > 0) then
|
||||||
|
begin
|
||||||
|
LogMem.Lines.AddStrings(FLog);
|
||||||
|
LogMem.SelLength := 0;
|
||||||
|
LogMem.SelStart := Length(LogMem.Text);
|
||||||
|
FLog.Clear;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.RefreshSinksMsg(var aMessage : TMessage);
|
||||||
|
begin
|
||||||
|
if FClosing then exit;
|
||||||
|
|
||||||
|
UpdateAvailableSinks;
|
||||||
|
AppendPendingLogStrings;
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.RoutesLbxClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.RefreshRoutesMsg(var aMessage : TMessage);
|
||||||
|
begin
|
||||||
|
if FClosing then exit;
|
||||||
|
|
||||||
|
UpdateAvailableRoutes;
|
||||||
|
AppendPendingLogStrings;
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.UpdateButtonsMsg(var aMessage : TMessage);
|
||||||
|
begin
|
||||||
|
if FClosing then exit;
|
||||||
|
|
||||||
|
AppendPendingLogStrings;
|
||||||
|
UpdateButtons;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.DestroyAllArrays;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
DestroyRoutesArray;
|
||||||
|
DestroySinksArray;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.DestroySinksArray;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
if (FSinks <> nil) then
|
||||||
|
begin
|
||||||
|
i := pred(length(FSinks));
|
||||||
|
while (i >= 0) do
|
||||||
|
begin
|
||||||
|
FSinks[i].SinkIntf := nil;
|
||||||
|
dec(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Finalize(FSinks);
|
||||||
|
FSinks := nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.DestroyRoutesArray;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
if (FRoutes <> nil) then
|
||||||
|
begin
|
||||||
|
i := pred(length(FRoutes));
|
||||||
|
while (i >= 0) do
|
||||||
|
begin
|
||||||
|
FRoutes[i].RouteIntf := nil;
|
||||||
|
dec(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Finalize(FRoutes);
|
||||||
|
FRoutes := nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.CopySinksArray(const aSinks : TCefMediaSinkArray);
|
||||||
|
var
|
||||||
|
i, TempLen : integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
FLog.Add('Sinks available : ' + inttostr(length(aSinks)));
|
||||||
|
FLog.Add('------------------------------------------');
|
||||||
|
|
||||||
|
DestroySinksArray;
|
||||||
|
|
||||||
|
if (aSinks <> nil) then
|
||||||
|
begin
|
||||||
|
TempLen := length(aSinks);
|
||||||
|
SetLength(FSinks, TempLen);
|
||||||
|
|
||||||
|
i := 0;
|
||||||
|
while (i < TempLen) do
|
||||||
|
begin
|
||||||
|
FSinks[i].ID := aSinks[i].ID;
|
||||||
|
FSinks[i].Name := aSinks[i].Name;
|
||||||
|
FSinks[i].Description := aSinks[i].Description;
|
||||||
|
FSinks[i].Valid := aSinks[i].IsValid;
|
||||||
|
FSinks[i].SinkIntf := aSinks[i];
|
||||||
|
|
||||||
|
if aSinks[i].IsCastSink then
|
||||||
|
FSinks[i].SinkType := mtCast
|
||||||
|
else
|
||||||
|
if aSinks[i].IsDialSink then
|
||||||
|
FSinks[i].SinkType := mtDial
|
||||||
|
else
|
||||||
|
FSinks[i].SinkType := mtUnknown;
|
||||||
|
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
PostMessage(Handle, MEDIA_ROUTER_REFRESH_SINKS, 0, 0);
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.CopyRoutesArray(const aRoutes : TCefMediaRouteArray);
|
||||||
|
var
|
||||||
|
i, TempLen : integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
FLog.Add('Routes available : ' + inttostr(length(aRoutes)));
|
||||||
|
FLog.Add('------------------------------------------');
|
||||||
|
|
||||||
|
DestroyRoutesArray;
|
||||||
|
|
||||||
|
if (aRoutes <> nil) then
|
||||||
|
begin
|
||||||
|
TempLen := length(aRoutes);
|
||||||
|
SetLength(FRoutes, TempLen);
|
||||||
|
|
||||||
|
i := 0;
|
||||||
|
while (i < TempLen) do
|
||||||
|
begin
|
||||||
|
FRoutes[i].ID := aRoutes[i].ID;
|
||||||
|
FRoutes[i].SourceID := aRoutes[i].GetSource.ID;
|
||||||
|
FRoutes[i].SinkID := aRoutes[i].GetSink.ID;
|
||||||
|
FRoutes[i].RouteIntf := aRoutes[i];
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
PostMessage(Handle, MEDIA_ROUTER_REFRESH_ROUTES, 0, 0);
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.CreateRouteBtnClick(Sender: TObject);
|
||||||
|
var
|
||||||
|
TempURN, TempErrorMsg : string;
|
||||||
|
TempSource : ICefMediaSource;
|
||||||
|
begin
|
||||||
|
TempURN := trim(SourceURNCbx.Text);
|
||||||
|
|
||||||
|
if (length(TempURN) = 0) then
|
||||||
|
begin
|
||||||
|
AddLogEntry('Invalid URN');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TempErrorMsg := '';
|
||||||
|
|
||||||
|
try
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
if (FSinks <> nil) and
|
||||||
|
(SinksLbx.Items.Count > 0) and
|
||||||
|
(SinksLbx.ItemIndex >= 0) and
|
||||||
|
(SinksLbx.ItemIndex < length(FSinks)) then
|
||||||
|
begin
|
||||||
|
TempSource := Chromium1.GetSource(TempURN);
|
||||||
|
|
||||||
|
if (TempSource <> nil) and TempSource.IsValid then
|
||||||
|
begin
|
||||||
|
if (FSinks[SinksLbx.ItemIndex].SinkIntf <> nil) and
|
||||||
|
FSinks[SinksLbx.ItemIndex].SinkIntf.IsValid then
|
||||||
|
begin
|
||||||
|
if FSinks[SinksLbx.ItemIndex].SinkIntf.IsCompatibleWith(TempSource) then
|
||||||
|
Chromium1.CreateRoute(TempSource, FSinks[SinksLbx.ItemIndex].SinkIntf)
|
||||||
|
else
|
||||||
|
TempErrorMsg := 'The selected Sink is not compatible with the Media Source.';
|
||||||
|
end
|
||||||
|
else
|
||||||
|
TempErrorMsg := 'The selected Sink is not valid.';
|
||||||
|
end
|
||||||
|
else
|
||||||
|
TempErrorMsg := 'The Media Source is not valid.';
|
||||||
|
end
|
||||||
|
else
|
||||||
|
TempErrorMsg := 'The sinks list is outdated.';
|
||||||
|
except
|
||||||
|
on e : exception do
|
||||||
|
begin
|
||||||
|
TempErrorMsg := e.Message;
|
||||||
|
if CustomExceptionHandler('TMediaRouterFrm.CreateRouteBtnClick', e) then raise;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
TempSource := nil;
|
||||||
|
FMediaCS.Release;
|
||||||
|
if (length(TempErrorMsg) > 0) then AddLogEntry(TempErrorMsg);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.UpdateAvailableSinks;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
SinksLbx.Items.Clear;
|
||||||
|
|
||||||
|
if (FSinks <> nil) then
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
while (i < length(FSinks)) do
|
||||||
|
begin
|
||||||
|
case FSinks[i].SinkType of
|
||||||
|
mtCast : SinksLbx.Items.Add(FSinks[i].Name + ' (CAST)');
|
||||||
|
mtDial : SinksLbx.Items.Add(FSinks[i].Name + ' (DIAL)');
|
||||||
|
else SinksLbx.Items.Add(FSinks[i].Name + ' (UNKNOWN)');
|
||||||
|
end;
|
||||||
|
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.UpdateAvailableRoutes;
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
RoutesLbx.Items.Clear;
|
||||||
|
|
||||||
|
if (FRoutes <> nil) then
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
while (i < length(FRoutes)) do
|
||||||
|
begin
|
||||||
|
RoutesLbx.Items.Add('ID : ' + quotedstr(FRoutes[i].ID));
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.UpdateButtons;
|
||||||
|
begin
|
||||||
|
TerminateRouteBtn.Enabled := (RoutesLbx.ItemIndex >= 0) and
|
||||||
|
(RoutesLbx.Items.Count > 0);
|
||||||
|
|
||||||
|
SendMsgBtn.Enabled := TerminateRouteBtn.Enabled and
|
||||||
|
(length(trim(MessageMem.Lines.Text)) > 0);
|
||||||
|
|
||||||
|
CreateRouteBtn.Enabled := not(TerminateRouteBtn.Enabled) and
|
||||||
|
(length(trim(SourceURNCbx.Text)) > 0) and
|
||||||
|
(SinksLbx.ItemIndex >= 0) and
|
||||||
|
(SinksLbx.Items.Count > 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.AddLogEntry(const aMessage1, aMessage2 : string; aRec : boolean);
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
|
||||||
|
if aRec then
|
||||||
|
FLog.Add('Message received ' + dateTimeToStr(now))
|
||||||
|
else
|
||||||
|
FLog.Add('Message sent ' + dateTimeToStr(now));
|
||||||
|
|
||||||
|
FLog.Add(aMessage1);
|
||||||
|
if (length(aMessage2) > 0) then FLog.Add(aMessage2);
|
||||||
|
FLog.Add('------------------------------------------');
|
||||||
|
finally
|
||||||
|
PostMessage(Handle, MEDIA_ROUTER_PENDING_LOG_LINES, 0, 0);
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMediaRouterFrm.AddLogEntry(const aMessage1, aMessage2 : string);
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
FMediaCS.Acquire;
|
||||||
|
FLog.Add(aMessage1);
|
||||||
|
if (length(aMessage2) > 0) then FLog.Add(aMessage2);
|
||||||
|
FLog.Add('------------------------------------------');
|
||||||
|
finally
|
||||||
|
PostMessage(Handle, MEDIA_ROUTER_PENDING_LOG_LINES, 0, 0);
|
||||||
|
FMediaCS.Release;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
@ -22,8 +22,8 @@
|
|||||||
<ResourceBaseClass Value="Form"/>
|
<ResourceBaseClass Value="Form"/>
|
||||||
<IsVisibleTab Value="True"/>
|
<IsVisibleTab Value="True"/>
|
||||||
<EditorIndex Value="1"/>
|
<EditorIndex Value="1"/>
|
||||||
<TopLine Value="544"/>
|
<TopLine Value="22"/>
|
||||||
<CursorPos X="38" Y="555"/>
|
<CursorPos X="37" Y="48"/>
|
||||||
<UsageCount Value="21"/>
|
<UsageCount Value="21"/>
|
||||||
<Bookmarks Count="3">
|
<Bookmarks Count="3">
|
||||||
<Item0 Y="840" ID="1"/>
|
<Item0 Y="840" ID="1"/>
|
||||||
|
@ -15,7 +15,7 @@ object MiniBrowserFrm: TMiniBrowserFrm
|
|||||||
OnDestroy = FormDestroy
|
OnDestroy = FormDestroy
|
||||||
OnShow = FormShow
|
OnShow = FormShow
|
||||||
Position = poScreenCenter
|
Position = poScreenCenter
|
||||||
LCLVersion = '2.0.6.0'
|
LCLVersion = '2.0.8.0'
|
||||||
object Splitter1: TSplitter
|
object Splitter1: TSplitter
|
||||||
Left = 1179
|
Left = 1179
|
||||||
Height = 663
|
Height = 663
|
||||||
|
@ -45,7 +45,7 @@ uses
|
|||||||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Menus,
|
Windows, Messages, SysUtils, Variants, Classes, Graphics, Menus,
|
||||||
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, ActiveX, ShlObj,
|
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Types, ComCtrls, ClipBrd, ActiveX, ShlObj,
|
||||||
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
|
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFApplication, uCEFTypes, uCEFConstants,
|
||||||
uCEFWinControl, uCEFChromiumEvents, uCEFSentinel;
|
uCEFWinControl, uCEFChromiumEvents;
|
||||||
|
|
||||||
const
|
const
|
||||||
MINIBROWSER_SHOWDEVTOOLS = WM_APP + $101;
|
MINIBROWSER_SHOWDEVTOOLS = WM_APP + $101;
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Description Value="CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC."/>
|
<Description Value="CEF4Delphi is an open source project created by Salvador Díaz Fau to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC."/>
|
||||||
<License Value="MPL 1.1"/>
|
<License Value="MPL 1.1"/>
|
||||||
<Version Major="81" Minor="2" Release="22"/>
|
<Version Major="81" Minor="2" Release="24"/>
|
||||||
<Files Count="154">
|
<Files Count="154">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="..\source\uCEFAccessibilityHandler.pas"/>
|
<Filename Value="..\source\uCEFAccessibilityHandler.pas"/>
|
||||||
|
@ -62,7 +62,7 @@ uses
|
|||||||
const
|
const
|
||||||
CEF_SUPPORTED_VERSION_MAJOR = 81;
|
CEF_SUPPORTED_VERSION_MAJOR = 81;
|
||||||
CEF_SUPPORTED_VERSION_MINOR = 2;
|
CEF_SUPPORTED_VERSION_MINOR = 2;
|
||||||
CEF_SUPPORTED_VERSION_RELEASE = 22;
|
CEF_SUPPORTED_VERSION_RELEASE = 24;
|
||||||
CEF_SUPPORTED_VERSION_BUILD = 0;
|
CEF_SUPPORTED_VERSION_BUILD = 0;
|
||||||
|
|
||||||
CEF_CHROMEELF_VERSION_MAJOR = 81;
|
CEF_CHROMEELF_VERSION_MAJOR = 81;
|
||||||
|
@ -1276,8 +1276,8 @@ end;
|
|||||||
|
|
||||||
procedure TChromiumCore.DestroyMediaObserver;
|
procedure TChromiumCore.DestroyMediaObserver;
|
||||||
begin
|
begin
|
||||||
FRegistration := nil;
|
|
||||||
FMediaObserver := nil;
|
FMediaObserver := nil;
|
||||||
|
FRegistration := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TChromiumCore.CreateMediaObserver;
|
procedure TChromiumCore.CreateMediaObserver;
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
"UpdateLazPackages" : [
|
"UpdateLazPackages" : [
|
||||||
{
|
{
|
||||||
"ForceNotify" : true,
|
"ForceNotify" : true,
|
||||||
"InternalVersion" : 124,
|
"InternalVersion" : 125,
|
||||||
"Name" : "cef4delphi_lazarus.lpk",
|
"Name" : "cef4delphi_lazarus.lpk",
|
||||||
"Version" : "81.2.22.0"
|
"Version" : "81.2.24.0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"UpdatePackageData" : {
|
"UpdatePackageData" : {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user