这个问题在日本的msdb论坛上(下面的URL)也有讨论,并且有了一定的结论,现在把结果转过来。
http://social.msdn.microsoft.com/Forums/ja-JP/internetexplorerja/thread/3a7e083c-c75c-4cac-ad23-a733ede6e04c
首先是这一现象的原因的简单分析。
从下面的url来看,微软宣称,从ie8开始,focus函数不再把激活的窗口带到最前面,而仅仅使之在任务栏闪烁。
http://msdn.microsoft.com/ja-jp/library/ms536425(en-us,VS.85).aspx
可从实际的测试中来看,在有些环境下,focus仍然有时候会成功(
成功:会把窗口带到最前面,失败:仅仅在任务栏闪烁)。
进一步的调查发现,
在系统参数
FOREGROUNDLOCKTIMEOUT设置为0时,focus的表现为有时成功,有时失败,
而当
FOREGROUNDLOCKTIMEOUT设置为200000时(系统的初始值),focus的表现为 完全失败。
根据推测,focus也应该是使用了SetForegroundWindow的方法来将窗口带到最前面(Z-order的顶端,前景窗口)。
由于ie8使用了LCIE的进程分离技术,父窗口和子窗口不再处于一个进程。当父窗口处于最前方的时候,
子窗口所属进程就不再是foreground。从而导致使SetForegroundWindow成功需要的前提条件,不再符合。
所以这一现象,更有可能是由于LCIE导致的边缘效果。
FOREGROUNDLOCKTIMEOUT:
http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx
SetForegroundWindow:
http://msdn.microsoft.com/en-us/library/ms633539(VS.85).aspx
这一现象有以下的回避或者解决手段。
1 LCIE无效(TabProcGrowth=1)
这样,父窗口和子窗口处于一个进程,focus就总能成功。
不过,一是要修改注册表,二是不能再享受LCIE带来的好处。
2
FOREGROUNDLOCKTIMEOUT设为0,连续调用focus(比如说,用一个100回的循环)
使用javascript和activeX修改FOREGROUNDLOCKTIMEOUT的方法如下(需要有安装Excel):
将下面的命令敲入ie的地址栏,回车即可。
TIMEOUT=0(focus有时成功,有时失败)
javascript:alert( (new ActiveXObject("Excel.Application")).ExecuteExcel4Macro('CALL("user32","SystemParametersInfoA","JJJJJ",8193,0,0,0)')?"设定完了!":"" );
TIMEOUT=200000(系统的初始值)
javascript:alert( (new ActiveXObject("Excel.Application")).ExecuteExcel4Macro('CALL("user32","SystemParametersInfoA","JJJJJ",8193,0,200000,0)')?"设定完了!":"" );
事实上,由于很多软件在安装的时候都会改变
FOREGROUNDLOCKTIMEOUT。参照上面的SetForegroundWindow的url。
3 如果不想改变系统设定的话,可以使用WScript.Shell这个Activex控件。使用WScript.Shell的
AppActivate方法。
Option Explicit
Dim win
Sub Activate
win.focus
win.document.focus
If win.document.hasFocus() Then Exit Sub
Dim wShell
Set wShell=CreateObject("WScript.Shell")
If wShell.AppActivate(win.document.title) Then Exit Sub
Dim LocationURL
LocationURL=win.location.href
If Left(LocationURL,8)="file:///" Then LocationURL=Replace(UnEscape(Mid(LocationURL,9)),"/","/")
If LocationURL="about:blank" Then LocationURL="空白页"
If wShell.AppActivate(LocationURL) Then Exit Sub
End Sub
更复杂的版本,请参照下面的url。
http://scripting.cocolog-nifty.com/blog/2009/08/ie7ie8windowope.html
4 如果Activex控件也不想利用的话,可以用下面的方法。
不过这个方法,会弹出【focus moving...】的警告窗口。
Sub MsgActivate
win.focus
win.document.focus
If win.document.hasFocus() Then Exit Sub
win.setTimeout "MsgBox ""focus moving..."",vbSystemModal",0,"vbscript"
End Sub
下面是一个完整的例子。
<html>
<head>
<title>opener</title>
<object id=wShell classid=clsid:72C24DD5-D70A-438B-8A42-98424B88AFB8></object>
<script language=vbscript>
Option Explicit
Dim win
Sub Activate(win)
win.focus
win.document.focus
If win.document.hasFocus() Then Exit Sub
Dim wShell
Set wShell=CreateObject("WScript.Shell")
If wShell.AppActivate(win.document.title) Then Exit Sub
Dim LocationURL
LocationURL=win.location.href
If Left(LocationURL,8)="file:///" Then LocationURL=Replace(UnEscape(Mid(LocationURL,9)),"/","/")
If LocationURL="about:blank" Then LocationURL="空白のページ"
If wShell.AppActivate(LocationURL) Then Exit Sub
End Sub
Sub MsgActivate(win)
win.focus
win.document.focus
If win.document.hasFocus() Then Exit Sub
win.setTimeout "MsgBox ""focus moving..."",vbSystemModal",0,"vbscript"
End Sub
</script>
<script language="javascript" type="text/javascript">
<!--
var newWin = null;
var myurl = 'child.htm';
function OpenNewWindow()
{
newWin = window.open('child.htm','popup','width=550, height=262, toolbar=0, resizable=false');
}
function FocusNewWindowByActivate(){
if (newWin != null && !newWin.closed){
Activate(newWin);
}
}
function FocusNewWindowByFocus(){
if (newWin != null && !newWin.closed){
newWin.focus();
}
}
function FocusNewWindowByMsgActivate(){
if (newWin != null && !newWin.closed){
MsgActivate(newWin);
}
}
-->
</script>
</head>
<body>
<button onclick='OpenNewWindow()'>open child.htm in window</button>
<button onclick="FocusNewWindowByFocus()">FocusNewWindowByFocus</button>
<button onclick="FocusNewWindowByActivate()">FocusNewWindowByActivate</button>
<button onclick="FocusNewWindowByMsgActivate()">FocusNewWindowByMsgActivate</button>
</body>
</html>
最后,有关这个现象还有一些没有解决的问题。除了上面提到的之外,focus的表现似乎还和其他条件有关。
不过暂时就先到这儿了。也许以后的ie会修正这个问题。
希望能对遇到类似问题的朋友有所帮助,祝大家愉快。