main.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. unit main;
  2. interface
  3. {$I cef.inc}
  4. uses
  5. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  6. Dialogs, StdCtrls, ceflib, cefvcl, Buttons, ActnList, Menus, ComCtrls,
  7. ExtCtrls, XPMan, Registry, ShellApi, SyncObjs, System.Actions;
  8. type
  9. TMainForm = class(TForm)
  10. crm: TChromium;
  11. DevTools: TChromiumDevTools;
  12. StatusBar: TStatusBar;
  13. ActionList: TActionList;
  14. actPrev: TAction;
  15. actNext: TAction;
  16. actHome: TAction;
  17. actReload: TAction;
  18. actGoTo: TAction;
  19. MainMenu: TMainMenu;
  20. File1: TMenuItem;
  21. est1: TMenuItem;
  22. mGetsource: TMenuItem;
  23. mGetText: TMenuItem;
  24. actGetSource: TAction;
  25. actGetText: TAction;
  26. actZoomIn: TAction;
  27. actZoomOut: TAction;
  28. actZoomReset: TAction;
  29. Zoomin1: TMenuItem;
  30. Zoomout1: TMenuItem;
  31. Zoomreset1: TMenuItem;
  32. actExecuteJS: TAction;
  33. ExecuteJavaScript1: TMenuItem;
  34. Exit1: TMenuItem;
  35. Print1: TMenuItem;
  36. actFileScheme1: TMenuItem;
  37. actDom: TAction;
  38. VisitDOM1: TMenuItem;
  39. SaveDialog: TSaveDialog;
  40. actDevTool: TAction;
  41. DevelopperTools1: TMenuItem;
  42. Panel1: TPanel;
  43. SpeedButton1: TSpeedButton;
  44. SpeedButton2: TSpeedButton;
  45. SpeedButton3: TSpeedButton;
  46. SpeedButton4: TSpeedButton;
  47. edAddress: TEdit;
  48. SpeedButton5: TSpeedButton;
  49. actDoc: TAction;
  50. Help1: TMenuItem;
  51. Documentation1: TMenuItem;
  52. actGroup: TAction;
  53. Googlegroup1: TMenuItem;
  54. actFileScheme: TAction;
  55. actPrint: TAction;
  56. Splitter: TSplitter;
  57. procedure edAddressKeyPress(Sender: TObject; var Key: Char);
  58. procedure actPrevExecute(Sender: TObject);
  59. procedure actNextExecute(Sender: TObject);
  60. procedure actHomeExecute(Sender: TObject);
  61. procedure actReloadExecute(Sender: TObject);
  62. procedure actReloadUpdate(Sender: TObject);
  63. procedure actGoToExecute(Sender: TObject);
  64. procedure FormCreate(Sender: TObject);
  65. procedure actHomeUpdate(Sender: TObject);
  66. procedure actGetSourceExecute(Sender: TObject);
  67. procedure actGetTextExecute(Sender: TObject);
  68. procedure actZoomInExecute(Sender: TObject);
  69. procedure actZoomOutExecute(Sender: TObject);
  70. procedure actZoomResetExecute(Sender: TObject);
  71. procedure actExecuteJSExecute(Sender: TObject);
  72. procedure Exit1Click(Sender: TObject);
  73. procedure actFileSchemeExecute(Sender: TObject);
  74. procedure actDomExecute(Sender: TObject);
  75. procedure actNextUpdate(Sender: TObject);
  76. procedure actPrevUpdate(Sender: TObject);
  77. procedure crmAddressChange(Sender: TObject; const browser: ICefBrowser;
  78. const frame: ICefFrame; const url: ustring);
  79. procedure crmLoadEnd(Sender: TObject; const browser: ICefBrowser;
  80. const frame: ICefFrame; httpStatusCode: Integer);
  81. procedure crmLoadStart(Sender: TObject; const browser: ICefBrowser;
  82. const frame: ICefFrame);
  83. procedure crmStatusMessage(Sender: TObject; const browser: ICefBrowser;
  84. const value: ustring);
  85. procedure crmTitleChange(Sender: TObject; const browser: ICefBrowser;
  86. const title: ustring);
  87. procedure actDevToolExecute(Sender: TObject);
  88. procedure actDocExecute(Sender: TObject);
  89. procedure actGroupExecute(Sender: TObject);
  90. procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  91. procedure crmBeforeDownload(Sender: TObject; const browser: ICefBrowser;
  92. const downloadItem: ICefDownloadItem; const suggestedName: ustring;
  93. const callback: ICefBeforeDownloadCallback);
  94. procedure crmDownloadUpdated(Sender: TObject; const browser: ICefBrowser;
  95. const downloadItem: ICefDownloadItem;
  96. const callback: ICefDownloadItemCallback);
  97. procedure crmProcessMessageReceived(Sender: TObject;
  98. const browser: ICefBrowser; sourceProcess: TCefProcessId;
  99. const message: ICefProcessMessage; out Result: Boolean);
  100. procedure actPrintExecute(Sender: TObject);
  101. procedure crmBeforeContextMenu(Sender: TObject; const browser: ICefBrowser;
  102. const frame: ICefFrame; const params: ICefContextMenuParams;
  103. const model: ICefMenuModel);
  104. procedure crmContextMenuCommand(Sender: TObject; const browser: ICefBrowser;
  105. const frame: ICefFrame; const params: ICefContextMenuParams;
  106. commandId: Integer; eventFlags: TCefEventFlags; out Result: Boolean);
  107. procedure crmCertificateError(Sender: TObject; const browser: ICefBrowser;
  108. certError: Integer; const requestUrl: ustring; const sslInfo: ICefSslInfo;
  109. const callback: ICefRequestCallback; out Result: Boolean);
  110. procedure crmBeforePopup(Sender: TObject; const browser: ICefBrowser;
  111. const frame: ICefFrame; const targetUrl, targetFrameName: ustring;
  112. targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
  113. var popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo;
  114. var client: ICefClient; var settings: TCefBrowserSettings;
  115. var noJavascriptAccess: Boolean; out Result: Boolean);
  116. procedure crmBeforeResourceLoad(Sender: TObject; const browser: ICefBrowser;
  117. const frame: ICefFrame; const request: ICefRequest;
  118. const callback: ICefRequestCallback; out Result: TCefReturnValue);
  119. procedure Help1Click(Sender: TObject);
  120. private
  121. { Déclarations privées }
  122. FLoading: Boolean;
  123. function IsMain(const b: ICefBrowser; const f: ICefFrame = nil): Boolean;
  124. end;
  125. TCustomRenderProcessHandler = class(TCefRenderProcessHandlerOwn)
  126. protected
  127. procedure OnWebKitInitialized; override;
  128. end;
  129. TTestExtension = class
  130. class function hello: string;
  131. class procedure mouseover(const data: string);
  132. end;
  133. var
  134. MainForm: TMainForm;
  135. implementation
  136. const
  137. CUSTOMMENUCOMMAND_INSPECTELEMENT = 7241221;
  138. {$R *.dfm}
  139. procedure TMainForm.actDevToolExecute(Sender: TObject);
  140. begin
  141. if actDevTool.Checked then
  142. begin
  143. DevTools.Visible := True;
  144. Splitter.Visible := True;
  145. DevTools.ShowDevTools(crm.Browser);
  146. end else
  147. begin
  148. DevTools.CloseDevTools(crm.Browser);
  149. Splitter.Visible := False;
  150. DevTools.Visible := False;
  151. end;
  152. end;
  153. procedure TMainForm.actDocExecute(Sender: TObject);
  154. begin
  155. crm.Load('http://magpcss.org/ceforum/apidocs3');
  156. end;
  157. procedure TMainForm.actDomExecute(Sender: TObject);
  158. begin
  159. if crm.Browser <> nil then
  160. crm.Browser.MainFrame.ExecuteJavaScript(
  161. 'document.body.addEventListener("mouseover", function(evt){'+
  162. 'function getpath(n){'+
  163. 'var ret = "<" + n.nodeName + ">";'+
  164. 'if (n.parentNode){return getpath(n.parentNode) + ret} else '+
  165. 'return ret'+
  166. '};'+
  167. 'app.mouseover(getpath(evt.target))}'+
  168. ')', 'about:blank', 0);
  169. end;
  170. procedure TMainForm.actExecuteJSExecute(Sender: TObject);
  171. begin
  172. if crm.Browser <> nil then
  173. crm.Browser.MainFrame.ExecuteJavaScript(
  174. 'alert(''JavaScript execute works!'');', 'about:blank', 0);
  175. end;
  176. procedure TMainForm.actFileSchemeExecute(Sender: TObject);
  177. begin
  178. if crm.Browser <> nil then
  179. crm.Browser.MainFrame.LoadUrl('local://c/');
  180. end;
  181. procedure CallbackGetSource(const src: ustring);
  182. var
  183. source: ustring;
  184. begin
  185. source := src;
  186. source := StringReplace(source, '<', '&lt;', [rfReplaceAll]);
  187. source := StringReplace(source, '>', '&gt;', [rfReplaceAll]);
  188. source := '<html><body>Source:<pre>' + source + '</pre></body></html>';
  189. MainForm.crm.Browser.MainFrame.LoadString(source, 'source://html');
  190. end;
  191. procedure TMainForm.actGetSourceExecute(Sender: TObject);
  192. begin
  193. crm.Browser.MainFrame.GetSourceProc(CallbackGetSource);
  194. end;
  195. procedure CallbackGetText(const txt: ustring);
  196. var
  197. source: ustring;
  198. begin
  199. source := txt;
  200. source := StringReplace(source, '<', '&lt;', [rfReplaceAll]);
  201. source := StringReplace(source, '>', '&gt;', [rfReplaceAll]);
  202. source := '<html><body>Text:<pre>' + source + '</pre></body></html>';
  203. MainForm.crm.Browser.MainFrame.LoadString(source, 'source://text');
  204. end;
  205. procedure TMainForm.actGetTextExecute(Sender: TObject);
  206. begin
  207. crm.Browser.MainFrame.GetTextProc(CallbackGetText);
  208. end;
  209. procedure TMainForm.actGoToExecute(Sender: TObject);
  210. begin
  211. if crm.Browser <> nil then
  212. crm.Browser.MainFrame.LoadUrl(edAddress.Text);
  213. end;
  214. procedure TMainForm.actGroupExecute(Sender: TObject);
  215. begin
  216. crm.Load('https://groups.google.com/forum/?fromgroups#!forum/delphichromiumembedded');
  217. end;
  218. procedure TMainForm.actHomeExecute(Sender: TObject);
  219. begin
  220. if crm.Browser <> nil then
  221. crm.Browser.MainFrame.LoadUrl(crm.DefaultUrl);
  222. end;
  223. procedure TMainForm.actHomeUpdate(Sender: TObject);
  224. begin
  225. TAction(Sender).Enabled := crm.Browser <> nil;
  226. end;
  227. procedure TMainForm.actNextExecute(Sender: TObject);
  228. begin
  229. if crm.Browser <> nil then
  230. crm.Browser.GoForward;
  231. end;
  232. procedure TMainForm.actNextUpdate(Sender: TObject);
  233. begin
  234. if crm.Browser <> nil then
  235. actNext.Enabled := crm.Browser.CanGoForward else
  236. actNext.Enabled := False;
  237. end;
  238. procedure TMainForm.actPrevExecute(Sender: TObject);
  239. begin
  240. if crm.Browser <> nil then
  241. crm.Browser.GoBack;
  242. end;
  243. procedure TMainForm.actPrevUpdate(Sender: TObject);
  244. begin
  245. if crm.Browser <> nil then
  246. actPrev.Enabled := crm.Browser.CanGoBack else
  247. actPrev.Enabled := False;
  248. end;
  249. procedure TMainForm.actPrintExecute(Sender: TObject);
  250. begin
  251. crm.Browser.Host.Print;
  252. end;
  253. procedure TMainForm.actReloadExecute(Sender: TObject);
  254. begin
  255. if crm.Browser <> nil then
  256. if FLoading then
  257. crm.Browser.StopLoad else
  258. crm.Browser.Reload;
  259. end;
  260. procedure TMainForm.actReloadUpdate(Sender: TObject);
  261. begin
  262. if FLoading then
  263. TAction(sender).Caption := 'X' else
  264. TAction(sender).Caption := 'R';
  265. TAction(Sender).Enabled := crm.Browser <> nil;
  266. end;
  267. function TMainForm.IsMain(const b: ICefBrowser; const f: ICefFrame): Boolean;
  268. begin
  269. Result := (b <> nil) and (b.Identifier = crm.BrowserId) and ((f = nil) or (f.IsMain));
  270. end;
  271. procedure TMainForm.actZoomInExecute(Sender: TObject);
  272. begin
  273. if crm.Browser <> nil then
  274. crm.Browser.Host.ZoomLevel := crm.Browser.Host.ZoomLevel + 0.5;
  275. end;
  276. procedure TMainForm.actZoomOutExecute(Sender: TObject);
  277. begin
  278. if crm.Browser <> nil then
  279. crm.Browser.Host.ZoomLevel := crm.Browser.Host.ZoomLevel - 0.5;
  280. end;
  281. procedure TMainForm.actZoomResetExecute(Sender: TObject);
  282. begin
  283. if crm.Browser <> nil then
  284. crm.Browser.Host.ZoomLevel := 0;
  285. end;
  286. procedure TMainForm.crmAddressChange(Sender: TObject;
  287. const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
  288. begin
  289. if IsMain(browser, frame) then
  290. edAddress.Text := url;
  291. end;
  292. procedure TMainForm.crmBeforeContextMenu(Sender: TObject;
  293. const browser: ICefBrowser; const frame: ICefFrame;
  294. const params: ICefContextMenuParams; const model: ICefMenuModel);
  295. begin
  296. model.AddItem(CUSTOMMENUCOMMAND_INSPECTELEMENT, 'Inspect Element');
  297. end;
  298. procedure TMainForm.crmBeforeDownload(Sender: TObject;
  299. const browser: ICefBrowser; const downloadItem: ICefDownloadItem;
  300. const suggestedName: ustring; const callback: ICefBeforeDownloadCallback);
  301. begin
  302. callback.Cont(ExtractFilePath(ParamStr(0)) + suggestedName, True);
  303. end;
  304. procedure TMainForm.crmBeforePopup(Sender: TObject; const browser: ICefBrowser;
  305. const frame: ICefFrame; const targetUrl, targetFrameName: ustring;
  306. targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean;
  307. var popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo;
  308. var client: ICefClient; var settings: TCefBrowserSettings;
  309. var noJavascriptAccess: Boolean; out Result: Boolean);
  310. begin
  311. // prevent popup
  312. crm.Load(targetUrl);
  313. Result := True;
  314. end;
  315. procedure TMainForm.crmBeforeResourceLoad(Sender: TObject;
  316. const browser: ICefBrowser; const frame: ICefFrame;
  317. const request: ICefRequest; const callback: ICefRequestCallback;
  318. out Result: TCefReturnValue);
  319. var
  320. u: TUrlParts;
  321. begin
  322. // redirect home to google
  323. if CefParseUrl(request.Url, u) then
  324. if (u.host = 'home') then
  325. begin
  326. u.host := 'www.google.com';
  327. request.Url := CefCreateUrl(u);
  328. end;
  329. end;
  330. procedure TMainForm.crmCertificateError(Sender: TObject;
  331. const browser: ICefBrowser; certError: Integer; const requestUrl: ustring;
  332. const sslInfo: ICefSslInfo; const callback: ICefRequestCallback;
  333. out Result: Boolean);
  334. begin
  335. // let use untrusted certificates (ex: cacert.org)
  336. MainForm.Caption := sslInfo.GetIssuer.GetDisplayName;
  337. callback.Cont(True);
  338. Result := True;
  339. end;
  340. procedure TMainForm.crmContextMenuCommand(Sender: TObject;
  341. const browser: ICefBrowser; const frame: ICefFrame;
  342. const params: ICefContextMenuParams; commandId: Integer;
  343. eventFlags: TCefEventFlags; out Result: Boolean);
  344. var
  345. mousePoint: TCefPoint;
  346. begin
  347. Result := False;
  348. if (commandId = CUSTOMMENUCOMMAND_INSPECTELEMENT) then
  349. begin
  350. mousePoint.x := params.XCoord;
  351. mousePoint.y := params.YCoord;
  352. Splitter.Visible := True;
  353. DevTools.Visible := True;
  354. actDevTool.Checked := True;
  355. DevTools.CloseDevTools(crm.Browser);
  356. application.ProcessMessages;
  357. DevTools.ShowDevTools(crm.Browser,@mousePoint);
  358. Result := True;
  359. end;
  360. end;
  361. procedure TMainForm.crmDownloadUpdated(Sender: TObject;
  362. const browser: ICefBrowser; const downloadItem: ICefDownloadItem;
  363. const callback: ICefDownloadItemCallback);
  364. begin
  365. if downloadItem.IsInProgress then
  366. StatusBar.SimpleText := IntToStr(downloadItem.PercentComplete) + '%' else
  367. StatusBar.SimpleText := '';
  368. end;
  369. procedure TMainForm.crmLoadEnd(Sender: TObject; const browser: ICefBrowser;
  370. const frame: ICefFrame; httpStatusCode: Integer);
  371. begin
  372. if IsMain(browser, frame) then
  373. FLoading := False;
  374. end;
  375. procedure TMainForm.crmLoadStart(Sender: TObject; const browser: ICefBrowser;
  376. const frame: ICefFrame);
  377. begin
  378. if IsMain(browser, frame) then
  379. FLoading := True;
  380. end;
  381. procedure TMainForm.crmProcessMessageReceived(Sender: TObject;
  382. const browser: ICefBrowser; sourceProcess: TCefProcessId;
  383. const message: ICefProcessMessage; out Result: Boolean);
  384. begin
  385. if (message.Name = 'mouseover') then
  386. begin
  387. StatusBar.SimpleText := message.ArgumentList.GetString(0);
  388. Result := True;
  389. end else
  390. Result := False;
  391. end;
  392. procedure TMainForm.crmStatusMessage(Sender: TObject;
  393. const browser: ICefBrowser; const value: ustring);
  394. begin
  395. StatusBar.SimpleText := value
  396. end;
  397. procedure TMainForm.crmTitleChange(Sender: TObject; const browser: ICefBrowser;
  398. const title: ustring);
  399. begin
  400. if IsMain(browser) then
  401. Caption := title;
  402. end;
  403. procedure TMainForm.edAddressKeyPress(Sender: TObject; var Key: Char);
  404. begin
  405. if Key = #13 then
  406. begin
  407. if crm.Browser <> nil then
  408. begin
  409. crm.Browser.MainFrame.LoadUrl(edAddress.Text);
  410. Abort;
  411. end;
  412. end;
  413. end;
  414. procedure TMainForm.Exit1Click(Sender: TObject);
  415. begin
  416. Close;
  417. end;
  418. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  419. begin
  420. // avoid AV when closing application
  421. if CefSingleProcess then
  422. crm.Load('about:blank');
  423. CanClose := True;
  424. end;
  425. procedure TMainForm.FormCreate(Sender: TObject);
  426. begin
  427. FLoading := False;
  428. end;
  429. procedure TMainForm.Help1Click(Sender: TObject);
  430. begin
  431. end;
  432. { TCustomRenderProcessHandler }
  433. function getpath(const n: ICefDomNode): string;
  434. begin
  435. Result := '<' + n.Name + '>';
  436. if (n.Parent <> nil) then
  437. Result := getpath(n.Parent) + Result;
  438. end;
  439. procedure TCustomRenderProcessHandler.OnWebKitInitialized;
  440. begin
  441. {$IFDEF DELPHI14_UP}
  442. TCefRTTIExtension.Register('app', TTestExtension);
  443. {$ENDIF}
  444. end;
  445. { TTestExtension }
  446. class procedure TTestExtension.mouseover(const data: string);
  447. var
  448. msg: ICefProcessMessage;
  449. begin
  450. msg := TCefProcessMessageRef.New('mouseover');
  451. msg.ArgumentList.SetString(0, data);
  452. TCefv8ContextRef.Current.Browser.SendProcessMessage(PID_BROWSER, msg);
  453. end;
  454. class function TTestExtension.hello: string;
  455. begin
  456. Result := 'Hello from Delphi';
  457. end;
  458. initialization
  459. CefRemoteDebuggingPort := 9000;
  460. CefRenderProcessHandler := TCustomRenderProcessHandler.Create;
  461. CefBrowserProcessHandler := TCefBrowserProcessHandlerOwn.Create;
  462. end.