CEF4Delphi/demos/Lazarus_Linux_GTK2/TabbedBrowser2/uMainForm.pas
salvadordf 7f3e3415ef Added partial GTK3 support
Converted the OSRExternalPumpBrowser demo to GTK3
Converted the TinyBrowser demo to GTK3
Converted the TinyBrowser2 demo to GTK3
Moved all Lazarus demos for Linux to the Lazarus_Linux_GTK2 directory
Fixed the Copy.CEF.DLLs tool thanks to fraurino
2022-06-25 16:41:34 +02:00

317 lines
8.8 KiB
ObjectPascal

// ************************************************************************
// ***************************** 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 © 2022 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 uMainForm;
{$mode objfpc}{$H+}
{$I cef.inc}
interface
uses
LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ComCtrls, ToolWin, Buttons, ExtCtrls,
uCEFApplication, uCEFTypes, uCEFConstants;
const
CEF_INITIALIZED = $100;
CEF_DESTROYTAB = $101;
HOMEPAGE_URL = 'https://www.google.com';
DEFAULT_TAB_CAPTION = 'New tab';
type
{ TMainForm }
TMainForm = class(TForm)
BrowserPageCtrl: TPageControl;
ButtonPnl: TPanel;
AddTabBtn: TSpeedButton;
RemoveTabBtn: TSpeedButton;
procedure AddTabBtnClick(Sender: TObject);
procedure RemoveTabBtnClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
protected
// Variables to control when can we destroy the form safely
FCanClose : boolean;
FClosing : boolean;
FLastTabID : cardinal; // Used by NextTabID to generate unique tab IDs
function GetNextTabID : cardinal;
procedure EnableButtonPnl;
function CloseAllTabs : boolean;
procedure CloseTab(aIndex : integer);
procedure NotifyMoveOrResizeStarted;
procedure BrowserInitializedMsg(Data: PtrInt);
procedure BrowserDestroyedTabMsg(Data: PtrInt);
procedure WMMove(var aMessage: TLMMove); message LM_MOVE;
procedure WMSize(var aMessage: TLMSize); message LM_SIZE;
procedure WMWindowPosChanged(var aMessage: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED;
property NextTabID : cardinal read GetNextTabID;
public
procedure SendCompMessage(aMsg : cardinal; aData : PtrInt = 0);
end;
var
MainForm: TMainForm = nil;
procedure CreateGlobalCEFApp;
implementation
{$R *.lfm}
uses
uBrowserTab;
// This demo shows how to use a TPageControl with TFrames that include
// CEF4Delphi browsers.
// Instead of a regular TTabSheet we use a custom TBrowserTab class that
// inherits from TTabSheet and instead of a regular TFrame we use a custom
// TBrowserFrame class that inherits from TFrame.
// To create a new tab you need to call TBrowserTab.CreateBrowser in the last
// step to create all the browser components and initialize the browser.
// To close a tab you have to call TBrowserTab.CloseBrowser and wait for a
// CEF_DESTROYTAB message with the TBrowserTab.TabID value.
// Then you find the tab with that unique TabID and free it.
// Most of the TChromium events store the parameter values in a set of class
// fields which are protected by a critial section and then they call
// TBrowserFrame.SendCompMessage to execute the GUI code in the main thread.
// TBrowserFrame has all the usual code to close CEF4Delphi browsers following
// a similar destruction sequence than the MiniBrowser demo :
//
// 1. TBrowserTab.CloseBrowser calls TChromium.CloseBrowser which triggers the
// TChromium.OnClose event.
// 2. TChromium.OnClose sets aAction to cbaClose which trigges the
// TChromium.OnBeforeClose event.
// 3. TChromium.OnBeforeClose executes the TBrowserFrame.OnBrowserDestroyed
// event which will be used in TBrowserTab to send a CEF_DESTROYTAB message
// to the main form to free the tab.
// To close safely this demo you must close all the browser tabs first following
// this steps :
//
// 1. FormCloseQuery sets CanClose to FALSE and calls CloseAllTabs and FClosing
// is set to TRUE.
// 2. Each tab will send a CEF_DESTROYTAB message to free that tab.
// 3. When TPageControl has no tabs then we can set FCanClose to TRUE and
// close the main form.
procedure GlobalCEFApp_OnContextInitialized;
begin
if (MainForm <> nil) and MainForm.Showing and MainForm.Focused then
MainForm.SendCompMessage(CEF_INITIALIZED);
end;
procedure CreateGlobalCEFApp;
begin
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.OnContextInitialized := @GlobalCEFApp_OnContextInitialized;
end;
procedure TMainForm.EnableButtonPnl;
begin
if not(ButtonPnl.Enabled) then
begin
ButtonPnl.Enabled := True;
Caption := 'Tabbed Browser 2';
cursor := crDefault;
if (BrowserPageCtrl.PageCount = 0) then AddTabBtn.Click;
end;
end;
function TMainForm.GetNextTabID : cardinal;
begin
inc(FLastTabID);
Result := FLastTabID;
end;
procedure TMainForm.AddTabBtnClick(Sender: TObject);
var
TempNewTab : TBrowserTab;
begin
TempNewTab := TBrowserTab.Create(self, NextTabID, DEFAULT_TAB_CAPTION);
TempNewTab.PageControl := BrowserPageCtrl;
BrowserPageCtrl.ActivePageIndex := pred(BrowserPageCtrl.PageCount);
TempNewTab.CreateBrowser(HOMEPAGE_URL);
end;
procedure TMainForm.FormActivate(Sender: TObject);
begin
if (GlobalCEFApp <> nil) and GlobalCEFApp.GlobalContextInitialized then
EnableButtonPnl;
end;
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := FCanClose;
if not(FClosing) then
begin
FClosing := True;
ButtonPnl.Enabled := False;
if not(CloseAllTabs) then
begin
FCanClose := True;
CanClose := True;
end;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
FCanClose := False;
FClosing := False;
FLastTabID := 0;
end;
procedure TMainForm.RemoveTabBtnClick(Sender: TObject);
begin
CloseTab(BrowserPageCtrl.ActivePageIndex);
end;
function TMainForm.CloseAllTabs : boolean;
var
i : integer;
begin
Result := False;
i := pred(BrowserPageCtrl.PageCount);
while (i >= 0) do
begin
TBrowserTab(BrowserPageCtrl.Pages[i]).CloseBrowser;
Result := True;
dec(i);
end;
end;
procedure TMainForm.CloseTab(aIndex : integer);
begin
if (aIndex >= 0) and (aIndex < BrowserPageCtrl.PageCount) then
TBrowserTab(BrowserPageCtrl.Pages[aIndex]).CloseBrowser;
end;
procedure TMainForm.NotifyMoveOrResizeStarted;
var
i : integer;
begin
i := 0;
while (i < BrowserPageCtrl.PageCount) do
begin
TBrowserTab(BrowserPageCtrl.Pages[i]).NotifyMoveOrResizeStarted;
inc(i);
end;
end;
procedure TMainForm.WMMove(var aMessage : TLMMove);
begin
inherited;
NotifyMoveOrResizeStarted;
end;
procedure TMainForm.WMSize(var aMessage: TLMSize);
begin
inherited;
NotifyMoveOrResizeStarted;
end;
procedure TMainForm.WMWindowPosChanged(var aMessage: TLMWindowPosChanged);
begin
inherited;
NotifyMoveOrResizeStarted;
end;
procedure TMainForm.BrowserInitializedMsg(Data: PtrInt);
begin
EnableButtonPnl;
end;
procedure TMainForm.BrowserDestroyedTabMsg(Data: PtrInt);
var
i : integer;
TempTab : TBrowserTab;
begin
i := 0;
while (i < BrowserPageCtrl.PageCount) do
begin
TempTab := TBrowserTab(BrowserPageCtrl.Pages[i]);
if (TempTab.TabID = cardinal(Data)) then
begin
TempTab.Free;
break;
end
else
inc(i);
end;
if FClosing and (BrowserPageCtrl.PageCount = 0) then
begin
FCanClose := True;
close;
end;
end;
procedure TMainForm.SendCompMessage(aMsg : cardinal; aData : PtrInt);
begin
case aMsg of
CEF_INITIALIZED : Application.QueueAsyncCall(@BrowserInitializedMsg, aData);
CEF_DESTROYTAB : Application.QueueAsyncCall(@BrowserDestroyedTabMsg, aData);
end;
end;
end.