- PR -

WebBrowser コントロールを貼ったフォームが、あたかも Activate() されたように前面に出てきてしまう

1
投稿者投稿内容
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-04 22:10
Visual C# 2005 + IE 7.0 + Windows XP Professional SP2 で Windows アプリケーションを作っています。(本題とは関係ありませんが、いわゆる巡回アプリケーションのようなものです。)

WebBrowser コントロール(System.Windows.Forms.WebBrowser)をフォームに貼って、つぎのようなコードで使っているのですが、特定のサイトにアクセスしたときだけ、そのフォームが前面に表示されてしまいます。

コード:
using System;
using System.Windows.Forms;

namespace TestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            webBrowser1.Navigate("〜");
            // this.Activate();
        }
    }
}



私としては裏でひっそりと動いてほしいのですが、たとえばこのアプリケーションを動かしながら、メモ帳(や IE や Excel 等)で入力作業をしているときに、このアプリケーションが突然勝手に前面に出てきてキーボードのフォーカスもこのアプリケーションに移ってしまうため、入力作業が中断してしまいます。

事情により、そのサイトの URL や HTML/JavaScript を示すことなどはできないのですが、フォームウィンドウの動きはあたかもフォームを Activate() したのと似たような挙動になります。上記のコード中でコメントアウトしている部分です。
しかし、普通に IE を立ち上げてそのサイトの URL にアクセスしても IE が前面になるということはありません。
なお、そのサイトを私は一利用者として使っているだけなので、サイトの構造をいじったり、あるいは、サイトの構造がどうなっているのかという詳しい仕様は分かりません。ただ、JavaScript をたくさん使っていて複雑な構造にはなっているようです。

漠然とした質問ですが、なにか解決の糸口はないでしょうか。検索のキーワードだけでも挙げていただけるとありがたいです。
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-05-04 22:47
コード:



<script>
window.attachEvent("onload",function() {

setTimeout(function() {
window.focus();
}, 5000 );
});
</script>

<body>
5秒したらアクティブね。
</body>




要はこんな仕掛けみたいに意図的なコードが介在していないのに、なぜか
アクティブになってしまう、ってことですよね?

追記:
M●D● ライブ●▲ とか?


[ メッセージ編集済み 編集者: ぴあちゃん 編集日時 2008-05-04 22:49 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-04 23:21
引用:

ぴあちゃんさんの書き込み (2008-05-04 22:47) より:
要はこんな仕掛けみたいに意図的なコードが介在していないのに、なぜか
アクティブになってしまう、ってことですよね?


今のところスクリプトのせいなのかも切り分けできていませんが、ご回答をヒントに、スクリプトが多そうなサイトをいろいろと試していたら、再現できるサイトを見つけました。(Google Mail です。)
もっとも、スクリプトよりもリダイレクトすることが影響しているのかもしれません。

下記のコードは、フォームに WebBrowser コントロールとボタンとタイマー(System.Windows.Forms.Timer)を貼り付けたものです。
ボタンを押したら、すぐになにか別のウィンドウを上にかぶせてください。3秒後にこのアプリケーションが前に出てきます。
(再現するためには Google Mail のアカウントが要るかもしれませんが。)
コード:
using System;
using System.Windows.Forms;

namespace TestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Interval = 3 * 1000;
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();
            webBrowser1.Navigate("http://mail.google.com/");
        }
    }
}


なお、このアプリケーションのウィンドウが前面に出てくるのを防ぎたいこともあるのですが、他のアプリケーションのウィンドウからフォーカスを奪うのを防ぎたい、ということが一番の目的です。
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-05-05 08:21
コード:


Public Class myWeb : Inherits WebBrowser
Const WM_SETFOCUS = 7
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

Console.WriteLine(String.Format("WM_GOTFOCUS:{0}:{1}", m.Msg.ToString, m))
If m.Msg = WM_SETFOCUS Then
Return
End If


MyBase.WndProc(m)

End Sub


Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)

Console.WriteLine("フォーカスIN")

Navigate("javascript:window.blur()")


'' MyBase.OnEnter(e)
End Sub
End Class





すんまそん。これで今日は勘弁してください。

とりあえず、邪魔はしなくなりました。フォーカスは失いますが・・・

ちょっと後退かなぁ・・・

だめだ。こりゃ。
フォーカス無いし、前に出てこないから少し前進したのかと
思っていたら、カスケード気味に全部の窓が見えるように配置して
実行してみたら、一番後ろでアクティブになっていました。
なんか変。


[ メッセージ編集済み 編集者: ぴあちゃん 編集日時 2008-05-05 08:28 ]
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-06 13:35
引用:

ぴあちゃんさんの書き込み (2008-05-05 08:21) より:
とりあえず、邪魔はしなくなりました。フォーカスは失いますが・・・

ちょっと後退かなぁ・・・

だめだ。こりゃ。
フォーカス無いし、前に出てこないから少し前進したのかと
思っていたら、カスケード気味に全部の窓が見えるように配置して
実行してみたら、一番後ろでアクティブになっていました。
なんか変。


ありがとうございます。
VB.NET を良く知らないのでまだ試せてはいないのですが、雰囲気は掴めました。

なお、私は、
引用:

unibonさんの書き込み (2008-05-04 22:10) より:
しかし、普通に IE を立ち上げてそのサイトの URL にアクセスしても IE が前面になるということはありません。


と書いたのですが、その後、自分のアプリケーションを使わず IE だけで GMail に対して同じことを何度も試してみると、IE が前面になるときもありました。しかし、ならないときもあります。IE を新規に立ち上げて最初にアクセスするとなりやすいような感じです。
IE がすでにこういう挙動だとしたら、それを使う WebBrowser コントロールの段階での対処は難しいような気がしてきました。しかし、なぜ IE がそのような挙動をするのかが謎です。IE の設定等で対処できないものでしょうか。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-15 14:13
引用:

ぴあちゃんさんの書き込み (2008-05-04 22:47) より:
コード:



<script>
window.attachEvent("onload",function() {

setTimeout(function() {
window.focus();
}, 5000 );
});
</script>

<body>
5秒したらアクティブね。
</body>




要はこんな仕掛けみたいに意図的なコードが介在していないのに、なぜか
アクティブになってしまう、ってことですよね?


遅くなってしまいましたが、その後、調べてみると、目的とする Web サイトにもこのような JavaScript のコードが入っていました。具体的にはつぎのような感じでした。
コード:

<html>
<head>
<script language="javascript">
いろいろなコード…

self.focus(); // function の中ではなくベタ書きのコード。

</script>
</head>
<body>
ほげほげ…
</body>
</html>


この self.focus() の存在が原因のようです。
(なお GMail のサイトもおそらく同様だと思うのですが、こちらはサイトの構造が複雑すぎて分かりませんでした。)

なお、この挙動(JavaScript で focus() すると、他のウィンドウからフォーカスを奪う)は IE がそういう挙動をするという仕様(?)のようなので、WebBrowser コントロールで IE を使う限りこの仕様は受け入れるしかないようです。

これ(self.focus())さえなかったものにしてしまえばそれで良いのですが、これだけを無効にすることができず、悩んでいます。
つぎの2つの方法を試してみましたがダメでした。


(1) WebBrowser コントロールを Form に貼らずに、自分で new して使う。
コード:

public partial class Form1 : Form
{
private WebBrowser wb;

public Form1()
{
InitializeComponent();
wb = new WebBrowser();
}
}


こうするとブラウザーの画面がおもてに現れないものの、普通に動くし、フォーム(Form1)は前面には出てこなくなり、ちょっとマシです。
しかし、やはり WebBrowser コントロールがフォーカスを奪ってしまうようであり、Form1 に貼り付けてあるテキストボックスや、他のアプリケーション(メモ帳等)からフォーカスがなくなってしまい、それらを使って入力作業をしていた場合、中断してしまいます。

なお、ぴあちゃんさんが書かれた WndProc をオーバーライドするやりかたは、WebBrowser へ他からフォーカスを設定されるという制御の方向ならばキャプチャーできそうですが、今回の件では WebBrowser が他からフォーカスを奪ってしまうという方向なので、WndProc をオーバーライドしてもメッセージを受け取らないことはできても、自身がフォーカスを獲得することを制御はできないだろうと思います。
WebBrowser から見れば自身の JavaScript で focus しているわけですが、その JavaScript は外部の Web サーバーが管理している HTML なので私はいじることができない、というのがもどかしいところです。


(2) DocumentCompleted の中で、WebBrowser のドキュメントをプログラムで加工してみる。
しかし、テキストボックス(<input type="text">)などの追加は比較的容易にできるのですが、スクリプトの削除や追加ができないようです。ネットを探しても、できた、という例を見つけることができませんでした。

( http://watcher.moe-nifty.com/memo/2008/03/webbrowser_user_af88.html などを参考にさせていただきました。 )

なお、目的とするサイトは HTTPS もあるので、外部から(HTTP/HTTPS プロキシーなど)で HTML をいじるのも不可能だと思っています。


今のところ、諦めモードに入りつつあります。

[ メッセージ編集済み 編集者: unibon 編集日時 2008-05-15 15:59 ]
ぴあちゃん
ぬし
会議室デビュー日: 2008/02/07
投稿数: 287
投稿日時: 2008-05-16 01:09
まず、Gmail に関して。
クッキーを使っている。フレーム内で表示されているかどうか判定しているっぽい>IFRAMEではNGの文言が出てくるため。

で、ブラウザのスクリプトOFFを設定すると、GMailの簡易表示版のURLが表示され
ます。

http://mail.google.com/mail/?ui=html&zy=c

これ。
とりあえず、このURLならば、JavaScriptを一切使わない版で動作します。
自動ログインもなぜか出来ます。

参考まで。

self.focus() しちゃってるHPはそんなに多くは無いと思うので個別対応
出来るものは対応して、Gmail以外なら、IFRAMEを documentText に書き出して
みて下さい。IFRAME 内でJavaScript の self.focus() した場合の挙動として、
タスクバーのアイコン?が点滅動作を数回繰り返すだけで、フォーカス移動
は起きません。



unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-05-18 18:28
引用:

ぴあちゃんさんの書き込み (2008-05-16 01:09) より:
で、ブラウザのスクリプトOFFを設定すると、GMailの簡易表示版のURLが表示され
ます。

http://mail.google.com/mail/?ui=html&zy=c

これ。
とりあえず、このURLならば、JavaScriptを一切使わない版で動作します。
自動ログインもなぜか出来ます。


ありがとうございます。このような別の入り口から入れないか調べてみます。

引用:

ぴあちゃんさんの書き込み (2008-05-16 01:09) より:
self.focus() しちゃってるHPはそんなに多くは無いと思うので個別対応
出来るものは対応して、Gmail以外なら、IFRAMEを documentText に書き出して
みて下さい。IFRAME 内でJavaScript の self.focus() した場合の挙動として、
タスクバーのアイコン?が点滅動作を数回繰り返すだけで、フォーカス移動
は起きません。


IFRAME だとフォーカスの挙動が違うということなのでしょうか?

ためしに
コード:
<html>
<head>
</head>
<body>
<iframe src="目的とするサイトのURL">
</iframe>
</body>
</html>


という html を自分で管理できる Web サーバーに置いて、アクセスしてみましたが、ドメインが違うため「アクセスが拒否されました。」という IE でおなじみのエラーが出てしまいました。
この制限は IE には昔からあって、いろいろとセキュリティーの設定を緩めても、これを解除することはできなかったと記憶しています。WebBrowser コントロールから IE を使っても同様に解除できないだろうと推測しています。それとも WebBrowser コントロールからだとできる抜け道のようなものはあるでしょうか。
このあたりからちょっと調べてみます。とりあえずご報告まで。

(なお前述のように「目的とするサイトのURL」にあるコンテンツは私はいじることができません。ファイルを追加して置くこともできません。)
1

スキルアップ/キャリアアップ(JOB@IT)