喫茶XRAYトップページ

[▲前のスレッド]

[9134] エスパーは登場するのか返信 削除
2015/8/26 (水) 20:21:28 Mr.XRAY
あいかわらず,エスパーの登場を期待する質問がありますね.
そして,いつものように [典型的なパターン] です.

[chroniumのボタンをクリックするには?]
http://hpcgi3.nifty.com/e-papy/DelphiBBS/wwwlng.cgi?print+201508/15080007.txt

質問者が提示した具体的なものは,下のコードだけです.
これだけの HTML コードでもウェブブラウザで表示できますけどね (^^;

<Button class="submit" >送信</Button>
http://mrxray.on.coocan.jp/Delphi/Others/this_is_a_button.htm


上の HTML では,ボタンをクリックしても何も起きません.
何も起きなければ,クリックの確認が面倒です.

そこで,以下のようにして,ボタンをタグ名を検索してクリックするテストをしてみました.
質問されている方の言う,class 名からでも,もちろん処理すれば可能です.
でも,ほとんど意味ないですけど,
もちろん,この下のテストも,実際にはほとんど意味はないです.
タグ名やクラス名からボタンを検出しなければならないなんて考えられませんから.

<Button class="submit" onClick="location.href='http://mrxray.on.coocan.jp/index.htm'">SEND</Button>


//=============================================================================
//  ブラウザコンポーネントに指定のHTMLを表示
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
  URL : String;
begin
  URL := ExtractFilePath(Application.ExeName) + 'this_is_a_button.htm';
  Chromium1.Load(URL);
end;

//=============================================================================
//  HTMLコード内のbuttonタグの最初のタグ(0が1番目)のボタンをクリック
//  このコードは,JavaScriptを実行しているだけなので
//  JavaScriptを実行する部分を変更すれば,他のブラウザコンポでも使用可能
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LTagName : String;
  LJsText  : String;
begin
  if not Chromium1.Browser.HasDocument then exit;

  if Assigned(Chromium1.Browser.Mainframe) then begin
    LTagName := '''button''';
    LJsText  := 'document.getElementsByTagName(' + LTagName + ')[0].click();';
    Chromium1.Browser.MainFrame.ExecuteJavaScript(LJsText, 'about:blank', 0);
  end;
end;


興味ある方用に,プロジェクトをダウンロード可能にしています.EXE 付きです.
動作確認環境は,ソースコード内に書いてあります.
http://mrxray.on.coocan.jp/Delphi/zip/TChromium_ButtonClick.zip

下図が実行結果です.
下の図が [Button1] をクリックして,コードで [SEND] ボタンをクリックした結果です.

[9135] Re:エスパーは登場するのか返信 削除
2015/8/26 (水) 20:56:10 Mr.XRAY
HTML コードがそのまま表示できないみたいです.
&lt; はタグの左側のカッコのことです.


[9136] Re2:エスパーは登場するのか返信 削除
2015/8/26 (水) 23:05:14 Mr.XRAY
> HTML コードがそのまま表示できないみたいです.
> &lt; はタグの左側のカッコのことです.


≪に変更しました.

それとですね.[SEND] というボタンがあるのに,
何でわさわざ [Button1] でクリックするの ?
という追及は,してはいけないことになっています (笑)


[9137] Re3:エスパーは登場するのか返信 削除
2015/8/27 (木) 06:15:02 Mr.XRAY
> > HTML コードがそのまま表示できないみたいです.
> > &lt; はタグの左側のカッコのことです.
>
> ≪に変更しました.


分かりました.投稿する時に tag のチェックを外すと HTML コードが
そのまま表示されるようです.
知りませんでした.


[9138] Re:エスパーは登場するのか返信 削除
2015/8/27 (木) 06:22:12 Mr.XRAY
> 質問されている方の言う,class 名からでも,もちろん処理すれば可能です.

てなわけで,class 名で検出する例です.
class="submit"
とありますから,実際には入力用の form タグがあるものと思われますので,
このようなコードの実用性は... ですのであしからず.
でも,いろいろやってみるというのも勉強にはなります.
あくまでも,

<Button class="submit" >送信</Button>

というコードしかないという前提でのテストです.
私ゃエスパーじゃあないもんですから.

[0] は 1 番目の意味です.2 番目は [1] です.
JavaScript では " で囲まれた部分も文字列ですから,以下でも OK です.

    LClassName := '''submit''';  --> LClassName := '"submit"';


procedure TForm1.Button1Click(Sender: TObject);
var
  LClassName : String;
  LJsText    : String;
begin
  if not Chromium1.Browser.HasDocument then exit;

  if Assigned(Chromium1.Browser.Mainframe) then begin
    LClassName := '''submit''';
    LJsText  := 'document.getElementsByClassName(' + LClassName + ')[0].click();';
    Chromium1.Browser.MainFrame.ExecuteJavaScript(LJsText, 'about:blank', 0);
  end;
end;


[9139] Re2:エスパーは登場するのか返信 削除
2015/8/27 (木) 07:23:22 Mr.XRAY
> とありますから,実際には入力用の form タグがあるものと思われますので,

入力 Form に対する操作は,TChromium, TWebBrowser, IE のサンプル
に掲載しています.


[9140] Re:エスパーは登場するのか返信 削除
2015/8/27 (木) 15:34:35 Mr.XRAY
> 質問者が提示した具体的なものは,下のコードだけです.
> これだけの HTML コードでもウェブブラウザで表示できますけどね (^^;
>
> <Button class="submit" >送信</Button>


自分でテストする場合であっても,
最低限以下のようにしておいた方が無難です.

<html>
<head>
  <title>ボタンクリックテスト</title>
</head>
<body>
  <Button class="submit" >送信</Button>
</body>
</html>


[9141] JavaScriptのコードを生成して実行返信 削除
2015/8/27 (木) 17:16:45 Mr.XRAY
ところで,この一連のボタンクリックのコードは JavaScript を実行しています.
しかし,1 行だけです.
もし,複数行の JavaScript のコードを実行したい場合は,
JavaScript テキストを複数行にするとか,HTML にコードを挿入する方法もありますが
以下のような方法もあります.

[ PascalScript (Delphi XE2 以降)]
http://ht-deko.com/delphiforum/?vasthtmlaction=viewtopic&t=888

参考までに.

JavaScript を実行する関数の引数のテキストを,複数行にすれば,
複数行の実行となります.

  if Assigned(Chromium1.Browser.Mainframe) then begin
    LClassName := '''submit''';
    LJsText   := 'document.getElementsByClassName(' + LClassName + ')[0].click();';
    LJsText    := LJsText + sLineBreak + 'alert("ボタンクリックのテスト");';
    Chromium1.Browser.MainFrame.ExecuteJavaScript(LJsText, 'about:blank', 0);
  end;


このダイアログを閉じると,実際のボタンクリックの結果が表示される

[9142] IEのレンダリングの互換モード返信 削除
2015/8/28 (金) 09:01:04 Mr.XRAY
このスレッドのサンプルコードを TWebBrowser または TEmbeddedWB でテスト
する方は,IE のレンダリングモードを最新の値に変更してください.
古いバージョンの IE オブジェクトの DOM では getElementsByClassName
をサポートしていません.

[07_IE コンポーネントのレンダリングの互換モードを変更]
http://mrxray.on.coocan.jp/Delphi/plSamples/944_plGooleSearch.htm#07

プログラム名は,サーバに UP しているプロジェクトの場合は Project1.exe
です.


TEmbeddedWB の場合は以下のようなコードで実行可能です.

procedure TForm1.Button1Click(Sender: TObject);
var
  LClassName : String;
  LJsText    : String;
begin
  if EmbeddedWB1.Document = nil then exit;

  LClassName := '"submit"';
  LJsText   := 'document.getElementsByClassName(' + LClassName + ')[0].click();';
  EmbeddedWB1.ExecScript(LJsText, 'JavaScript');
end;


TWebBrowser の場合は,例えば以下のようにします.
uses に MSHTML が必要です.

procedure TForm1.Button1Click(Sender: TObject);
var
  LDoc        : IHTMLDocument2;
  LHTMLWindow : IHTMLWindow2;
  LClassName  : String;
  LJsText     : String;
begin
  LDoc := WebBrowser1.Document as IHTMLDocument2;
  if not Assigned(LDoc) then exit;

  LHTMLWindow := LDoc.parentWindow;
  if not Assigned(LHTMLWindow) then exit;

  try
    LClassName := '''submit''';
    LJsText  := 'document.getElementsByClassName(' + LClassName + ')[0].click();';
    LHTMLWindow.execScript(LJsText, 'JavaScript');
  except
  end;
end;


[9143] Re:IEのレンダリングの互換モード返信 削除
2015/8/28 (金) 13:09:03 Mr.XRAY
> 古いバージョンの IE オブジェクトの DOM では getElementsByClassName
> をサポートしていません.


MSDN オンラインの記事によると IE 9 からのようです.
ついでに,IE で表示している場合の操作例です.
TShell コンポーネントを使用しています.

[タイプライブラリの取り込み ( Delphi 2009 - XE5 )]
http://mrxray.on.coocan.jp/Delphi/CompoInstall/TypeLibraryD2009.htm

IE を新規に起動して,ローカルの this_is_a_button.htm を表示します.
そこのボタンをクリックします.
this_is_a_button.htm の中身は,これまでと同じで,
<Button class="submit" onClick="location.href='http://mrxray.on.coocan.jp/index.htm'">SEND</Button>
です.

動作確認は Windows 7 U64(SP1) + Delphi XE(UP1) Pro + IE 11 です.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SHDocVw, ExtCtrls, Shell32_TLB, OleServer;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Shell1: TShell;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses
  MSHTML,
  ShellAPI;

{$R *.dfm}

//=============================================================================
//  新規にIEを起動して,操作対象のページを表示
//
//  ShellExecuteの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LAppStr : String;
  LAppCmd : String;
begin
  //IEはフルパスでなくても起動可能
  LAppStr := 'IEXPLORE.EXE';
  LAppCmd := ExtractFilePath(Application.ExeName) + 'this_is_a_button.htm';
  ShellExecute(Handle, 'open', PChar(LAppStr), PChar(LAppCmd), nil, SW_SHOW);
end;

//=============================================================================
//  表示中のウェブページのボタンをクリックするサンプル
//  JavaScriptのコードとして実行
//
//  ShellWindowsの使用にはusesにSHDocVwが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LSHWindows  : ShellWindows;
  LIEObj      : InternetExplorer;
  LDoc2       : IHtmlDocument2;
  LHTMLWindow : IHTMLWindow2;
  LTagName    : String;
  LJsText     : String;
begin
  LSHWindows := Shell1.Windows as ShellWindows;
  LIEObj     := LSHWindows.Item(LSHWindows.Count - 1) as InternetExplorer;

  LDoc2 := LIEObj.Document as IHTMLDocument2;
  if Assigned(LDoc2) then begin
    LHTMLWindow := LDoc2.parentWindow as IHTMLWindow2;

    LTagName := '''button''';
    LJsText  := 'document.getElementsByTagName(' + LTagName + ')[0].click();';

    LHTMLWindow.execScript(LJsText, 'JavaScript');
  end;
end;

end.



[9144] submit返信 削除
2015/8/29 (土) 12:35:44 Mr.XRAY
ところで,

> <Button class="submit" >送信</Button>

には submit というのがあります.
下のサンプルコードは Google の画面で,検索語句を入力して検索を開始
するものです.このコードにはボタンクリックのコードはありません.

submit の操作の場合,何かを submit (サブミット) するのが目的です.
submit というのは,この場合,検索を開始するというぐらいの意味と
考えていいと思います.
例えば,山の頂上に立ったことを「サブミットした」と言います.

しかし,submit するには何かしらの操作が必要です.
下のコードは,submit を Delphi のコードで実行するものと言えます.
Google の検索画面では,[Enter] キーでも検索を開始します.
でも,ボタンがあれば,GUI 的には便利です.
そのためにボタンがあると考えてもいいと思います.

「ボタンをクリック」すると言うことに固執してしまうと本質を見失うことが
あります.
本当は submit という操作が目的です.
当サイトのサンプルプロクラム集の各ページに [Hide Index]というボタンが
あります.これは,左ペインの目次を非表示にするのが目的です.
[Hide Index] というボタンをクリックするのが目的ではありません.
同じく,ダウンロードというボタンは,ファイルのダウンロードが目的です.

プログラムは「勝てば官軍,動けば正義」です.
その意味では,このスレッドで書いたコードのように,
「何が何でもボタンをクリックする」
でもいいとは思います.


//=============================================================================
//  ブラウザコンポーネントに指定のHTMLを表示
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
var
  URL : String;
begin
  URL := 'https://www.google.co.jp/';
  EmbeddedWB1.Navigate(URL);
end;

//=============================================================================
//  Googleの検索画面に検索語句をセットして[Google 検索]ボタンをクリック
//  usesにMSHTML_EWBが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LiElement     : IHTMLElement;
  LiElementCol  : IHTMLElementCollection;
  LiFormElement : IHTMLFormElement;
  LMsgText      : String;
begin
  try
    //検索欄に文字列をセット
    LiElement := EmbeddedWB1.Doc3.getElementById('lst-ib');
    LiElement.setAttribute('value', 'Delphi', 0);

    //[Google 検索]ボタンをクリック
    //実際にはsubmitを実行する
    //したがって[Google 検索]ボタンが存在しなくてもsubmitは実行できる
    LiElementCol  := EmbeddedWB1.Doc2.forms;
    LiFormElement := LiElementCol.Item(0, 0) as IHTMLFormElement;
    LiFormElement.submit;
  except
    //細かいエラー処理は省略
    LMsgText := '操作できませんでした.';
    MessageBox(Handle, PChar(LMsgText), '操作結果', MB_ICONINFORMATION);
  end;
end;

//=============================================================================
//  [戻る]ボタン
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
begin
  EmbeddedWB1.GoBack;
end;

上のサンプルを含めて,これまでのサンプルもダウンロードのファイルに
追加しました.[ダウンロード] のボタンはありません(笑)
http://mrxray.on.coocan.jp/Delphi/zip/TChromium_ButtonClick.zip



[9156] Re:エスパーは登場するのか返信 削除
2015/8/31 (月) 16:13:58 Mr.XRAY
> そして,いつものように [典型的なパターン] です.
>
> [chroniumのボタンをクリックするには?]
> http://hpcgi3.nifty.com/e-papy/DelphiBBS/wwwlng.cgi?print+201508/15080007.txt


典型的なパターンなので,反応があるとすれば言い訳だと確信はしていましたが,
ここまでくるとすごいですね.
人は何故言い訳をするか,それは,自分の言動を正当化するためなのですが,
完全に墓穴を掘っていますね.
ご愁傷様です.ご親族の方からどうぞ.合掌.


[9181] Re2:エスパーは登場するのか返信 削除
2015/9/3 (木) 21:41:06 SO
▼ Mr.XRAYさん
> > そして,いつものように [典型的なパターン] です.
> >
> > [chroniumのボタンをクリックするには?]
> > http://hpcgi3.nifty.com/e-papy/DelphiBBS/wwwlng.cgi?print+201508/15080007.txt
>
> 典型的なパターンなので,反応があるとすれば言い訳だと確信はしていましたが,
> ここまでくるとすごいですね.
> 人は何故言い訳をするか,それは,自分の言動を正当化するためなのですが,
> 完全に墓穴を掘っていますね.
> ご愁傷様です.ご親族の方からどうぞ.合掌.


けれど、何かしらの反応を見せる方なので、
良い方かもしれません。

ただ、無事クリックできたなら、後の人のために最小限コードは欲しいですが...

[9182] Re3:エスパーは登場するのか返信 削除
2015/9/3 (木) 22:37:52 Mr.XRAY
▼ SOさん
> けれど、何かしらの反応を見せる方なので、
> 良い方かもしれません。


あぁ!! そうですよね.失礼しました.
 
> ただ、無事クリックできたなら、後の人のために最小限コードは欲しいですが...

御意 !!
「典型的なパターン」の方は,これがない方がいるんですよね.
で,後から検索した方が,迷ってしまう.
コミュニティの場を情報源としている方には,ちょっと寂しいです.

例によって,僭越なレスしちゃおうかな.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82