1. 程式人生 > >Delphi中Chrome Chromium、Cef3學習筆記(二)

Delphi中Chrome Chromium、Cef3學習筆記(二)

原文   http://blog.csdn.net/xtfnpgy/article/details/46635739   用Tchromium替換webbrowser

  用慣了EmbeddedWB,不想換,但是IE核心一直存在記憶體洩漏問題,沒辦法,只有尋找替代品了。

  要把用習慣的EmbeddedWB換成完全不一樣的TChromium,有點挑戰,特別是在資料不多,英語沒過三級的情況下。未來趨勢是這樣,只有慢慢啃了。

  首先,想到的是跨域,如果不能跨域,就沒辦法替代手上的成品。TChromium的跨域比想像中的簡單,直接通過chrm.Browser.GetFrameNames(list);//list:tstringList;取得各個IFrame/Frame的名稱(所謂名稱不是指name屬性,只是一個標識,在有name時,返回name,沒有name時,ID 也行,都沒有時,自動生成一個唯一名稱),如:

  ff                                                                       //這個是一個框架的ID

  <!--framePath //ff/<!--frame0-->--> 

  <!--framePath //ff/<!--frame1-->-->

  <!--framePath //ff/<!--frame2-->-->                   //後面三個是自動生成的唯一名稱

獲取指定Frame時,通過chrm1.Browser.Frame['frame 的名稱'],取得ICefFrame介面,後面的操作請隨意。

 

常用方法:

獲取主框架 chrm1.browser.MainFrame

獲取原始碼 s := chrm1.browser.MainFrame.Source;

  其次是填表,用過google瀏覽器的都知道,其填表功能實在強大,在webbrowser時代,一般都是獲取表單元素的各種介面,然後設定其value、checked等屬性,而在TChromium中,一切皆js,把想做的事都讓js去執行吧,所以,用TChromium,js功力深厚的會輕鬆很多了。比如:

strTemp := 'document.forms[0].inmembername.value="User_Name";'; 
  JavaExec(strTemp); 
  strTemp := 'document.forms[0].inpassword.value="Password";'; JavaExec(strTemp); strTemp := 'document.forms[0].submit.click();'; chrm.browser.Frame['ff'].ExecuteJavaScript(str,'about:blank',0);; //想在哪一層frame執行,就呼叫哪一層

直接在某一個frame下執行JS

例如:

<frame id="IndexFrame" name="IndexFrame" scrolling="auto" noresize="noresize" style="overflow-x:hidden" src="Mark_Six.aspx?uid=42a0d760-1cdf-4004-90ed-bb5fef01a2c0">

 

網頁原始碼如上: 我要在是frame id="IndexFrame下給紅色的Input 賦值。並不需要遍歷Ifame 直接  直接找到

var inputs = framesEl.contentWindow.document.getElementsByName('input');
inputs = inputs && inputs.length > 0 ?inputs:framesEl.contentDocument.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
input = inputs[i];
if(input){
var point = input.getAttribute('data-fx');
var css = input.getAttribute('class');
if(point == index && css=='input'){
break;。。。。。。

 

 

 

更神奇的是,還可以通過以下方法載入屬於自己的jquery到瀏覽器中:

複製程式碼
procedure TForm3.chrm1LoadEnd(Sender: TCustomChromium;
  const browser: ICefBrowser; const frame: ICefFrame; httpStatusCode: Integer;
  out Result: TCefRetval);
var
  str:string;
begin
   str:='var oHead = document.getElementsByTagName(''HEAD'').item(0);'#13#10+ 'var oScript = document.createElement( "script" );'#13#10+ 'oScript.language = "javascript";'#13#10+ 'oScript.type = "text/javascript";'#13#10+ 'oScript.id = "sid";'#13#10+ 'oScript.defer = true;'#13#10+ 'oScript.src = "jquery.js";'#13#10+ 'oHead.appendChild( oScript );'#13#10+ 'alert("8")' ; Frame.ExecuteJavaScript(str,'about:blank',0); end;
複製程式碼

直接連線本地的js!!!這段程式碼最後寫在LoadEnd中,每載入完成一個frame,就讓這個frame載入自己的jquery,如果在需要使用的時候再去載入jquery,jquery載入是需要時間的,可能會導致緊接著的js程式碼不能生效。

 

注意事項:Delphi執行JS的程式碼,必須注意大小寫,特別是自己寫的JS函式,因為JS是區分大小寫的!~

下一篇主要講解DELPHI與JS互動的更深層次方面。

  用慣了EmbeddedWB,不想換,但是IE核心一直存在記憶體洩漏問題,沒辦法,只有尋找替代品了。

  要把用習慣的EmbeddedWB換成完全不一樣的TChromium,有點挑戰,特別是在資料不多,英語沒過三級的情況下。未來趨勢是這樣,只有慢慢啃了。

  首先,想到的是跨域,如果不能跨域,就沒辦法替代手上的成品。TChromium的跨域比想像中的簡單,直接通過chrm.Browser.GetFrameNames(list);//list:tstringList;取得各個IFrame/Frame的名稱(所謂名稱不是指name屬性,只是一個標識,在有name時,返回name,沒有name時,ID 也行,都沒有時,自動生成一個唯一名稱),如:

  ff                                                                       //這個是一個框架的ID

  <!--framePath //ff/<!--frame0-->--> 

  <!--framePath //ff/<!--frame1-->-->

  <!--framePath //ff/<!--frame2-->-->                   //後面三個是自動生成的唯一名稱

獲取指定Frame時,通過chrm1.Browser.Frame['frame 的名稱'],取得ICefFrame介面,後面的操作請隨意。

 

常用方法:

獲取主框架 chrm1.browser.MainFrame

獲取原始碼 s := chrm1.browser.MainFrame.Source;

  其次是填表,用過google瀏覽器的都知道,其填表功能實在強大,在webbrowser時代,一般都是獲取表單元素的各種介面,然後設定其value、checked等屬性,而在TChromium中,一切皆js,把想做的事都讓js去執行吧,所以,用TChromium,js功力深厚的會輕鬆很多了。比如:

strTemp := 'document.forms[0].inmembername.value="User_Name";'; 
  JavaExec(strTemp); 
  strTemp := 'document.forms[0].inpassword.value="Password";'; JavaExec(strTemp); strTemp := 'document.forms[0].submit.click();'; chrm.browser.Frame['ff'].ExecuteJavaScript(str,'about:blank',0);; //想在哪一層frame執行,就呼叫哪一層

直接在某一個frame下執行JS

例如:

<frame id="IndexFrame" name="IndexFrame" scrolling="auto" noresize="noresize" style="overflow-x:hidden" src="Mark_Six.aspx?uid=42a0d760-1cdf-4004-90ed-bb5fef01a2c0">

 

網頁原始碼如上: 我要在是frame id="IndexFrame下給紅色的Input 賦值。並不需要遍歷Ifame 直接  直接找到

var inputs = framesEl.contentWindow.document.getElementsByName('input');
inputs = inputs && inputs.length > 0 ?inputs:framesEl.contentDocument.getElementsByTagName('input');
for (var i = 0; i < inputs.length; i++) {
input = inputs[i];
if(input){
var point = input.getAttribute('data-fx');
var css = input.getAttribute('class');
if(point == index && css=='input'){
break;。。。。。。

 

 

 

更神奇的是,還可以通過以下方法載入屬於自己的jquery到瀏覽器中:

複製程式碼
procedure TForm3.chrm1LoadEnd(Sender: TCustomChromium;
  const browser: ICefBrowser; const frame: ICefFrame; httpStatusCode: Integer;
  out Result: TCefRetval);
var
  str:string;
begin
   str:='var oHead = document.getElementsByTagName(''HEAD'').item(0);'#13#10+ 'var oScript = document.createElement( "script" );'#13#10+ 'oScript.language = "javascript";'#13#10+ 'oScript.type = "text/javascript";'#13#10+ 'oScript.id = "sid";'#13#10+ 'oScript.defer = true;'#13#10+ 'oScript.src = "jquery.js";'#13#10+ 'oHead.appendChild( oScript );'#13#10+ 'alert("8")' ; Frame.ExecuteJavaScript(str,'about:blank',0); end;
複製程式碼

直接連線本地的js!!!這段程式碼最後寫在LoadEnd中,每載入完成一個frame,就讓這個frame載入自己的jquery,如果在需要使用的時候再去載入jquery,jquery載入是需要時間的,可能會導致緊接著的js程式碼不能生效。

 

注意事項:Delphi執行JS的程式碼,必須注意大小寫,特別是自己寫的JS函式,因為JS是區分大小寫的!~

下一篇主要講解DELPHI與JS互動的更深層次方面。