I have a TChromium control in my Delphi application, and on the page I display, there's a link that minimizes the application. Currently, I detect when the user clicks that link by detecting the address change:
procedure TForm1.Chromium1AddressChange(Sender: TObject;const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
begin
if (url = 'file:///data/exiting.exit') then
Form1.Close;
if (url = 'file:///data/minimize.min') then
Application.Minimize;
end;
However, the side effect is that the browser's URL is changed, which I don't want. How can I detect when the user clicks the link without the URL changing?
If I get your problem right, you're having a link like this in your HTML document:
<a href="minimize.min">Minimize</a>
And you want to do something in your application when this link is clicked, but you don't want to navigate to that link, since it's just a fake link used only to recognize the action. Well, the OnAddressChange
is a wrong event to handle since it's being fired by the display handler when a frame's address has changed. So, it is too late to cancel the navigation to that fake site from there. In DCEF 1 you could write a handler for the OnBeforeBrowse
, but even that would not be "so clean" solution, because you'd have to parse the URL to which the frame navigates.
The proper way is to leave the fake site navigation and utilize DOM event listener. Then it doesn't matter what element nor event you use for your interaction. Let's have this minimalistic HTML document:
<html>
<body>
<a id="minimize" href="">Minimize</a>
</body>
</html>
As you can notice, it navigates to nowhere, but it will still be rendered as a link. It also has its own unique id
identifier needed for DOM explore identification. Now let's add the listener for the click
event for our minimize
element. This binding is done as soon as the frame is loaded, which is reported by firing the OnLoadEnd
event. There we will explore the DOM tree, find our minimize
element and attach the click
event listener to it:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cefvcl, ceflib;
type
TForm1 = class(TForm)
Chromium1: TChromium;
procedure FormCreate(Sender: TObject);
procedure Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer; out Result: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Chromium1.Load('C:\File.html');
end;
procedure MinimizeClickEvent(const AEvent: ICefDomEvent);
begin
ShowMessage('Here the application can be minimized.');
end;
procedure OnExploreDOM(const ADocument: ICefDomDocument);
var
DOMNode: ICefDomNode;
begin
// here we attempt to find our "minimize" element
DOMNode := ADocument.GetElementById('minimize');
// and if we find it, we attach to its click event our MinimizeClickEvent
// procedure so whenever the element will be clicked, that procedure will
// execute
if Assigned(DOMNode) then
DOMNode.AddEventListenerProc('click', True, MinimizeClickEvent);
end;
procedure TForm1.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer; out Result: Boolean);
begin
if Assigned(frame) then
frame.VisitDomProc(OnExploreDOM);
end;
end.
With small changes in the code or a HTML document you can listen to any event or element you choose, so you can have e.g. a button on your site:
<html>
<body>
<button id="minimize" type="button">Minimize</button>
</body>
</html>
Of course, you can attach event listeners for as much elements as you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With