IEのウィンドウを検索をするには?

解決


ss  2011-10-30 10:31:55  No: 41138

いつもお世話になります。
以前ネット上で以下のコードを見つけて利用しています。
これまではXXXXXの部分が固定で問題なかったのですが、

このコードの中で以下のXXXXXの部分が変化するようになってしまったため、
XXXXXが『http://ABC.BCD.EFG/APP/』までは同じですが、それ以降が変化
するIE6のウインドウを検索してそのウインドウに対して操作する(ヘルプのボタンを押す等)ことはできるでしょうか?

よろしくお願いします。

BrowserCaption: String = 'XXXXX - Microsoft Internet Explorer';

unit UnitGetBrowser;

interface

uses Windows, SysUtils, Messages;

type
  TGetBrowser = class
  private
    FEdithWnd    : LongInt;     // Editのハンドル
    FURL         : String;      // URL
    FCaption     : String;      // Caption
    FBrowserHwnd : LongInt;     // ブラウザのハンドルのハンドル
    FIsBrowser   : Boolean;     // Browserが動作中  True

    function FindEdit(const MainhWnd: Longint; var EdithWnd:Longint): Boolean;
    procedure GetTitle;
  public
    constructor Create;
    function Get: Boolean;

    property URL:   String read FURL;
    property Title: String read FCaption;
    property BrowserHwnd : LongInt read FBrowserHwnd;
    property IsBrowser : Boolean read FIsBrowser;
  end;

implementation

uses Dialogs;

const
   {BrowserCaption: array[0..2] of String =
                  ('Microsoft Internet Explorer',
                   'Netscape',
                   'インターネット エクスプローラ'); }
   BrowserCaption: String = 'XXXXX - Microsoft Internet Explorer';

var
  Hnd: HWND;                            // ブラウザのハンドル
  Caption: String;                      // ブラウザのCaption
  flgHit: Boolean;                      // ブラウザの存在flag
  EnumEdithWnd: Longint;                // Editのハンドル

{ WindowsAPIコールバック関数 ウィンドウの列挙 }
function EnumWindowsProc(Wnd: HWND; lParam: Longint): Bool; stdcall;
var
  szCaption: array [0..255] of Char;
  S: String;
begin
  Result:= True;
  FillChar(szCaption, SizeOf(szCaption), #0);
  GetWindowText(Wnd, szCaption, 255);

  S := szCaption;
  If S = '' then Exit;

  //ShowMessage(S);
  {if (Pos(BrowserCaption[0], S) > 0) or
     (Pos(BrowserCaption[1], S) > 0) or
     (Pos(BrowserCaption[2], S) > 0) then }
  if (Pos(BrowserCaption, S) > 0) then
  begin
    If Pos('Hidden', S) >0 then Exit;
     // Netscape's hidden frameは除く

    If Pos('NetscapeSlaveWindow', S) > 0 then Exit;
    // NetscapeSlaveWindowを除く
    // ここでタイトルバーに該当する文字のあるウィンドウを検索

    Hnd := Wnd;
    Caption := S;
    flgHit := True;
    //ShowMessage(Caption);
    Result := false;                    // 発見したら終わり
   end;
end;

{ WindowsAPIコールバック関数 子ウィンドウの列挙 }
function EnumChildProc(const hWnd, lParam: Longint): Boolean; stdcall;
var
  cName: array[0..255] of Char;
  Name: String;
begin
  Result := True;
  FillChar(cName, SizeOf(cName), #0);
  if (lParam = 1) then begin
    if GetClassName(hWnd, cName, 255) <> 0 then
    begin
      Name := cName;
      if CompareText('Edit', Name) = 0 then
      begin// クラスがEdit(一行テキストボックス)ならば
        EnumEdithWnd := hWnd;
        // Editを取得してハンドルを格納
        //Result := false;
        {1回目の発見で終わらせるとNNで不具合が起こる。NNでは,
         ブラウザで表示されているeditも拾ってしまうから。
         IEはそうでない。}
      end;
    end;
  end;
end;

{ TGetBrowser }

{ constructor }
constructor TGetBrowser.Create;
begin
  { グローバル変数の初期化 }
  flgHit := false;
  Hnd := 0;                            // ブラウザのハンドル
  Caption := '';                      // ブラウザのCaption
  EnumEdithWnd := 0;                // Editのハンドル

  end;

{ Editのハンドルを取得 }
function TGetBrowser.FindEdit(const MainhWnd: Integer;
  var EdithWnd: Integer): Boolean;
begin
  Result := False;
  if IsWindow(MainhWnd) then            // ちゃんと存在するか
  begin
    EnumEdithWnd := 0;
    // 子ウィンドウを検索開始
    EnumChildWindows(MainhWnd, @EnumChildProc, 1);
    if (IsWindow(EnumEdithWnd)) then
    begin
      EdithWnd := EnumEdithWnd;
      Result := True;
    end;
  end;

end;

{ メインルーチン }
function TGetBrowser.Get: Boolean;
var
  Buf: array[0..255] of Char;
begin
  Result := false;

  { ブラウザのハンドルを取得 }
  EnumWindows(@EnumWindowsProc, 0);      // ウィンドウリスト取得
  { 各ウィンドウのハンドルをアプリケーション定義のコールバック関数に順に
    渡すことにより、 画面上のすべてのトップ レベル ウィンドウを列挙します。}

  If not flgHit then
  begin
   //ShowMessage('ブラウザはありません。');
   FIsBrowser := False;
   Exit;
  end;

  { Editのハンドルを取得 }
  if FindEdit(Hnd, FEdithWnd) then begin
  // Editを取得

    FillChar(Buf, SizeOf(Buf), #0);
    SendMessage(FEdithWnd, WM_GETTEXT, SizeOf(Buf), Integer(@Buf));
    // 文字列の取得
    FURL := Buf;
    FCaption := Caption;
    GetTitle;
    Result := True;
    FBrowserHwnd := Hnd;  //  動作中のBrowserのHwnd
    FIsBrowser := True;   //  Browser 動作中
  end;
end;

{ FCaptionからTitleを抜き出す }
procedure TGetBrowser.GetTitle;
var
  P : Integer;
  flagHit: Boolean;
begin
    flagHit := false;
  {
  repeat
    P := Pos(BrowserCaption[i], FCaption);
    If P > 4 then
    begin
      flagHit := True;
      Break;
    end;
    Inc(i);
  until i > 2;
      }

  P := Pos(BrowserCaption, FCaption);
    If P > 4 then
    begin
      flagHit := True;
    end;

  {P := Pos(IECaption, FCaption);
  If P <= 4 then
  begin
    P := Pos(NNCaption, FCaption);
    If P <= 4 then
    begin
      FCaption := '■タイトルなし';
      Exit;
    end;//if
  end;//if }

  If flagHit then
  begin
    FCaption := Copy(FCaption, 1, P-4);
  end else
  begin
    FCaption := '■タイトルなし';
  end;
end;

end.


Mr.XRAY  2011-12-05 10:22:22  No: 41139

こんにちは.
タイトルは,「IEのウィンドウ」となっていますが,コード中には「NN」がどうのこうの
という文章があります.また,

>IE6のウインドウを検索してそのウインドウに対して操作する(ヘルプのボタンを押す>>>等)ことはできるでしょうか?

意味がよく理解できませんので.解決方法ではありません.参考コードです.
(私のIE6にはヘルプボタンが見えないのです.間違って非表示にしたのかも知れません)
IEのウィンドウでしたら,以下の方法でも検索できます.

動作確認環境は,Windows XP(SP3) + Delphi 2010(UP5) Pro

unit Unit1;

interface

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

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  現在起動中のIEのオブジェクトを取得して操作する簡単な例
//  ここで使用しているShell(TShell)を使用するには,[タイプライブラリの取り込み]
//  で[Microsoft Shell Controls And Automation]をコンポーネントにする
//  以下を参照
//  http://mrxray.on.coocan.jp/Delphi/CompoInstall/TypeLibraryD2009.htm
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  IEObj     : InternetExplorer;
  IEHandle  : HWND;
  SHWindows : ShellWindows;
begin
  //IE関係オブジェクト
  SHWindows := Shell1.Windows as ShellWindows;

  //最後に起動したIEを検出(SHWindows.Count - 1が最後を意味する)
  IEObj := SHWindows.Item(SHWindows.Count - 1) as InternetExplorer;
  if IEObj = nil then begin
    ShowMessage('IEは起動していません');
  end else begin
    //位置を変更してしまう
    IEObj.Top     := 0;
    IEObj.Left    := 0;
    //ツールバーとメニューバーを非表示にする
    //ただし,IEを一度閉じて,再度開くとまた表示されてしまう
    //IEそのものの基本設定を変更するものではないので注意
    IEObj.ToolBar := 0;
    IEObj.MenuBar := False;

    //後の操作用にハンドルを取得しておく
    IEHandle := IEObj.HWnd;
    Self.Caption := IntToStr(IEHandle) + '  ' + IEObj.LocationName;
  end;
end;

end.


Mr.XRAY  2011-12-05 10:27:57  No: 41140

失礼しました.前のコードでは,エクスプローラも検出してしまいます.
エクスプローラよりも後にIEが起動していないとダメですね.
ゴメンなさい.


66.90.101.115  2011-12-06 22:41:42  No: 41141

<発言削除>


ss  2011-12-09 07:52:27  No: 41142

Mr.XRayさんいつもありがとうございます。
レスがなかなか付かなかったので諦めていまして、本日拝見しての
返答ですが、EnumWindowsProcでGetWindowtextでIEのタイトルを
取得しそれによりウインドウハンドルを得て処理する事ができました。
ありがとうございます。
それでIE6の操作ですが、IEのオブジェクトを取得して、IEのフレーム
内のボタン(おそらくJAVASCRIPTで表示)を操作操作する事はできる
のでしょうか?
追加で質問させていただきますがよろしくお願いします。


Mr.XRAY  2011-12-11 09:03:30  No: 41143

こんにちは.

>レスがなかなか付かなかったので諦めていまして、本日拝見しての

最近は,皆さん様子見が多いようですね(笑)
レスしても反応が中々ないとか.放置が多いのからでしょう.

>それでIE6の操作ですが、IEのオブジェクトを取得して、IEのフレーム
>内のボタン(おそらくJAVASCRIPTで表示)を操作操作する事はできる
>のでしょうか?

できるのかと訊かれれば,出来ます.
この掲示板にもその様な質問が過去にあります.具体的なコードもあります.
ただ,どんな語句で検索すればいいのかは,やってみないと分かりません.
「ブラウザ」とか「HTML」とかな?


monaa  2011-12-11 09:10:21  No: 41144

>最近は,皆さん様子見が多いようですね(笑)
いやいや、IE6なんて動いてる環境が無いんすよ!!


ss  2011-12-18 07:35:23  No: 41145

Mr.XRayさんmonaaさんありがとうございます。
検索して該当する項目を探して試したのですが、
試したのはマウスのクリックをシュミレートする方法ですが
PCにより位置がちがう場合があり、うまくいきません。
Internet explorer_serverウインドウの中に表示されていて
このハンドルは取得できたのですが、ここからどうすれば、
目的のボタンを探してクリックをプログラムからする方法
がよくわかりません。
なにかサンプルはないでしょうか?
よろしくお願いします。


Mr.XRAY  2011-12-20 16:05:24  No: 41146

こんにちは.

>いやいや、IE6なんて動いてる環境が無いんすよ!!

えっ!? そんな古いIE使ってんですか? 違うって... ?

>検索して該当する項目を探して試したのですが、

これも,えっ!?
と思って,私のサイトにサンプルでも掲載しようと思ったのですが,
結構,この掲示板にありますよ,monaaさんの感動するレスもあります.

>このハンドルは取得できたのですが、ここからどうすれば、

HTMLはIEのハンドルではなく,IEのオブジェクトで操作します.
どれがいいのか迷ったのですが,これはどうでしょう.

「ボタン」言ってもいろいろあります.そのうちの1つです.
HTMLの具体的なコードがないと,具体的な方法は分からないですね.当たり前ですが.
DelphiのバージョンやOSのバージョンも具体的な方法が知りたいと時は必要になるでしょう.
折角レスしたのに,「動かないです」と言われてしまっては,レスした甲斐がありません.
この場合,[送信]ボタンのクリックということになります.
IEのオブジェクトとは, WebBrowser1のことです,これを取得したIEオブジェクトに書き
換えます.IEオブジェクトの取得は,前にレスしたので省略します.

フォームに値を入力送信【パート2】
https://www.petitmonte.com/bbs/answers?question_id=6823

monaa 2010/02/19(金) 21:41:23 
https://www.petitmonte.com/bbs/answers?question_id=6824

のmonaa 2010/02/19(金) 21:41:23 を読んでみると,いろいろ勉強になると思います.
これも余計なお世話でしょうけど.


Mr.XRAY  2011-12-20 16:11:40  No: 41147

>この場合,[送信]ボタンのクリックということになります.

提示したURLのコードはあくまでも参考です,
HTMLがどのようになっているかによります.
また,いわゆる「ボタン」をクリックする方法は他にもあります.

クリックと言っても,実際にはHTMLのコードを,IEオブジェクトを操作するものです.
本当に「クリック」したいのであれば,実際にマウスカーソルをそこに移動するしか
ありません.


Mr.XRAY  2011-12-24 00:42:30  No: 41148

こんにちは.

サンプル作成してみました.
例によって「難解」ですので「何回」読んでも理解できない時はあきらめてください.

[941_ウェブページのテキスト入力とボタンクリック等]
http://mrxray.on.coocan.jp/Delphi/plSamples/941_IEObject_InputClick.htm


ss  2011-12-28 20:30:07  No: 41149

Mr.XRAYさんサンプルまでありがとうございました。
[941_ウェブページのテキスト入力とボタンクリック等]を参考
にしてやってみました。
なんとかなりそうな所までできました。
またよろしくお願いします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加