Make same app run on Win, Linux and Mac / Folder Lazarus_any_OS

This commit is contained in:
martin 2021-02-16 18:12:13 +01:00
parent 91f0c8d740
commit 15d6336dd0
13 changed files with 171 additions and 59 deletions

View File

@ -1,24 +0,0 @@
ExternalPumpBrowser
# ABOUT
This example uses
TCEFLinkedWindowParent
TCEFWorkScheduler
TCEFWorkScheduler feeds the CEF messageloop by calling DoMessageLoopWork(). On Mac this is currently the only way to run the CEF messageloop.
# SETUP
1) Go to "project options" and create the "App Bundle"
2) Download the CEF framework and place the content of the "Release" folder into ExternalPumpBrowser.app/Contents/Frameworks/Chromium Embedded Framework.framework
You should have:
Chromium Embedded Framework
Libraries/*
Resources/*
3) Open project "AppHelper", create App Bundle and compile the AppHelper.
Run create_mac_helper.sh
4) Open project ExternalPumpBrowser, compile and run

View File

Before

Width:  |  Height:  |  Size: 134 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<Version Value="11"/> <Version Value="12"/>
<General> <General>
<Flags>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/> <SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/> <MainUnit Value="0"/>
<Title Value="External Pump Browser"/> <Title Value="External Pump Browser"/>
@ -33,7 +36,7 @@
<PackageName Value="LCL"/> <PackageName Value="LCL"/>
</Item2> </Item2>
</RequiredPackages> </RequiredPackages>
<Units Count="3"> <Units Count="4">
<Unit0> <Unit0>
<Filename Value="ExternalPumpBrowser.lpr"/> <Filename Value="ExternalPumpBrowser.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -46,10 +49,15 @@
<ResourceBaseClass Value="Form"/> <ResourceBaseClass Value="Form"/>
</Unit1> </Unit1>
<Unit2> <Unit2>
<Filename Value="interfaces.pas"/> <Filename Value="initsubprocess.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="Interfaces"/> <UnitName Value="InitSubProcess"/>
</Unit2> </Unit2>
<Unit3>
<Filename Value="globalcefapplication.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="GlobalCefApplication"/>
</Unit3>
</Units> </Units>
</ProjectOptions> </ProjectOptions>
<CompilerOptions> <CompilerOptions>

View File

@ -56,9 +56,12 @@ uses
{$IFDEF UNIX}{$IFDEF UseCThreads} {$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads, cthreads,
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
{$IFDEF LINUX}
InitSubProcess, // On Linux this unit must be used *before* the "interfaces" unit.
{$ENDIF}
Interfaces, Interfaces,
uExternalPumpBrowser, Forms,
Forms uExternalPumpBrowser, GlobalCefApplication
{ you can add units after this } { you can add units after this }
; ;

View File

@ -0,0 +1,40 @@
ExternalPumpBrowser
# ABOUT
This example uses
TCEFLinkedWindowParent
TCEFWorkScheduler
TCEFWorkScheduler feeds the CEF messageloop by calling DoMessageLoopWork(). On Mac this is currently the only way to run the CEF messageloop.
# SETUP
** Windows
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
** Linux
1) Download the CEF framework and place the content of the "Release" folder into the same folder as your exe.
Alternatively you can point "GlobalCEFApp.FrameworkDirPath" to the location with the libraries.
2) Run the project
Note:
- For your own Linux project you must modify the project source (lpr) and add "InitSubProcess" to the "uses" clause, so that it is in the list *before* the unit "Interfaces".
- The call to "DestroyGlobalCEFApp" must be in a unit *not* used by "unit InitSubProcess" (including not used in any nested way).
** Mac
1) Go to "project options" and create the "App Bundle"
2) Download the CEF framework and place the content of the "Release" folder into ExternalPumpBrowser.app/Contents/Frameworks/Chromium Embedded Framework.framework
You should have:
Chromium Embedded Framework
Libraries/*
Resources/*
3) Open project "AppHelper", create App Bundle and compile the AppHelper.
Run create_mac_helper.sh
4) Open project ExternalPumpBrowser, compile and run

View File

@ -0,0 +1,47 @@
unit GlobalCefApplication;
{$mode ObjFPC}{$H+}
interface
uses
uCEFApplication, uCEFWorkScheduler;
procedure CreateGlobalCEFApp;
implementation
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure CreateGlobalCEFApp;
begin
if GlobalCEFApp <> nil then
exit;
// TCEFWorkScheduler will call cef_do_message_loop_work when
// it's told in the GlobalCEFApp.OnScheduleMessagePumpWork event.
// GlobalCEFWorkScheduler needs to be created before the
// GlobalCEFApp.StartMainProcess call.
GlobalCEFWorkScheduler := TCEFWorkScheduler.Create(nil);
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := @GlobalCEFApp_OnScheduleMessagePumpWork;
{$IFDEF LINUX}
// This is a workaround for the 'GPU is not usable error' issue :
// https://bitbucket.org/chromiumembedded/cef/issues/2964/gpu-is-not-usable-error-during-cef
GlobalCEFApp.DisableZygote := True; // this property adds the "--no-zygote" command line switch
{$ENDIF}
{
GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
}
end;
end.

View File

@ -0,0 +1,55 @@
// ************************************************************************
// ***************************** 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 © 2021 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 InitSubProcess;
{$mode ObjFPC}{$H+}
interface
uses
GlobalCefApplication, uCEFApplication;
implementation
initialization
CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then
halt(0); // exit the subprocess
end.

View File

@ -42,6 +42,7 @@ unit uExternalPumpBrowser;
interface interface
uses uses
GlobalCefApplication,
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, LMessages, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, LMessages,
uCEFChromium, uCEFWindowParent, uCEFConstants, uCEFTypes, uCEFInterfaces, uCEFChromium, uCEFWindowParent, uCEFConstants, uCEFTypes, uCEFInterfaces,
uCEFChromiumEvents, uCEFLinkedWindowParent, uCEFWorkScheduler; uCEFChromiumEvents, uCEFLinkedWindowParent, uCEFWorkScheduler;
@ -97,7 +98,6 @@ type
var var
Form1: TForm1; Form1: TForm1;
procedure CreateGlobalCEFApp;
implementation implementation
@ -131,30 +131,6 @@ uses
{ TForm1 } { TForm1 }
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure CreateGlobalCEFApp;
begin
// TCEFWorkScheduler will call cef_do_message_loop_work when
// it's told in the GlobalCEFApp.OnScheduleMessagePumpWork event.
// GlobalCEFWorkScheduler needs to be created before the
// GlobalCEFApp.StartMainProcess call.
GlobalCEFWorkScheduler := TCEFWorkScheduler.Create(nil);
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.OnScheduleMessagePumpWork := @GlobalCEFApp_OnScheduleMessagePumpWork;
{
GlobalCEFApp.LogFile := 'cef.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_VERBOSE;
}
end;
procedure TForm1.FormCreate(Sender: TObject); procedure TForm1.FormCreate(Sender: TObject);
begin begin
FCanClose := False; FCanClose := False;
@ -219,7 +195,10 @@ end;
procedure TForm1.Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure TForm1.Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction);
begin begin
// continue closing the browser // continue closing the browser
aAction := cbaClose; if CEFLinkedWindowParent1.DestroyChildWindow then
aAction := cbaDelay
else
aAction := cbaClose;
end; end;
procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure TForm1.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser);
@ -295,11 +274,15 @@ begin
end; end;
initialization initialization
CreateGlobalCEFApp; if GlobalCEFApp = nil then begin
GlobalCEFApp.StartMainProcess; CreateGlobalCEFApp;
if not GlobalCEFApp.StartMainProcess then
halt(0); // exit the subprocess
end;
finalization finalization
DestroyGlobalCEFApp; (* Destroy from this unit, which is used after "Interfaces". So this happens before the Application object is destroyed *)
DestroyGlobalCEFApp;
end. end.