事情起因

最近换上了基于 Chromium 内核的 Edge 浏览器, 不用 FQ 就能同步数据真香, 不过由于还处于开发阶段, 很多功能还在慢慢添加.

为了能尽快用上新功能, 我选择了据说是每天都会更新的 Canary 版本(比测试版更新还要频繁), 使用过程中多多少少遇到过一些 BUG , 但是不是什么大问题, 而且基本上反馈后24小时就能解决(毕竟一天一更).

但是今天, 我遇到了一个严重影响体验的问题—— Edge 浏览器会将自己设为置顶, 而且没提供取消的功能...导致我在开着浏览器窗口的时候根本没法运行其他软件, 只能最小化或者关闭才能解决, 而且因为浏览器始终置顶, 也间接影响了内部菜单的显示(浏览器界面覆盖了右键菜单, 导致虽然用户打开了菜单但是看不到内容)

虽然不知道是不是个例, 但我还是急忙反馈了这个问题, 然后坐等更新, 然而——第二天打开浏览器一看居然没收到任何更新, 上社区看了一眼才知道微软员工因为国际节假日全体放假, 更新延期...然后看了眼其他用户的反馈, 清一色的窗口被置顶. 有人建议不要用 Canary, BUG 就是会很多, 让改用 Dev 版, 这我肯定是拒绝的, 所以就决定自己搞.

问题分析

众所周知, Windows窗体置顶是通过调用 SetWindowPos 这个 API 来实现的, 那么我们需要用简单粗暴, 并且不会对程序本身代码进行破坏的方式来解决问题:

要用魔法打败魔法——鲁迅

我没说过——鲁迅

简而言之, 就是再调用一下这个 API , 然后取消置顶就可以了.

接下来就是 Coding 了,

本着助人为乐的想法, 这个程序做完可以分享给遇到同样问题的人用, 那么我就应该用脚本与语言来写这个程序.

又考虑到不是所有用户都装了一堆运行库的, 所以应该用一种裸机就能跑的脚本语言来编写.

所以决定用VBScript来写这个脚本

但是写的过程中, 在调用 WinAPI 方面又遇到了一些坑, 各种查资料之后, 发现了一个大佬写的脚本, 里面通过调用 PowerShell 来间接调用 WinAPI, 而且语法跟写 C# 差不多(原来PowerShell这么强大的么...)

于是加以改动, 一个简单的 FixIt 就诞生了

步入正题

直接上代码:

'Make edge calcel always on top.
AlwaysOnTop "msedge", ".", False

Sub AlwaysOnTop(appName, regExpTitle, setOnTop)
' @author: Jeremy England (SimplyCoded)
' @user: Spencer Lyo
  If (setOnTop) Then setOnTop = "-1" Else setOnTop = "-2"
  CreateObject("wscript.shell").Run "powershell -Command """ & _    
    "$Code = Add-Type -MemberDefinition '" & vbcrlf & _
    "  [DllImport(\""user32.dll\"")] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,int Y, int cx, int cy, uint uFlags);" & vbcrlf & _
    "  [DllImport(\""user32.dll\"")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);" & vbcrlf & _
    "  public static void AlwaysOnTop (IntPtr fHandle, int insertAfter) {" & vbcrlf & _
    "    if (insertAfter == -1) { ShowWindow(fHandle, 7); ShowWindow(fHandle, 9); }" & vbcrlf & _
    "    SetWindowPos(fHandle, new IntPtr(insertAfter), 0, 0, 0, 0, 3);" & vbcrlf & _
    "  }' -Name PS -PassThru" & vbcrlf & _
    "for ($s=0;$s -le 9; $s++){$hWnd = (GPS " & appName & " -EA 0 | ? {$_.MainWindowTitle -Match '" & regExpTitle & "'}).MainWindowHandle;Start-Sleep 1;if ($hWnd){break}}" & vbcrlf & _  
    "$Code::AlwaysOnTop($hWnd, " & setOnTop & ")""", 0, True
  End Sub

保存为 xxx.vbs 文件, 每次打开浏览器后运行一下就可以了

嫌麻烦也可以写个bat:

start msedge.exe && cscript xxx.vbs

写在最后

上网搜了搜之后发现, 这个 BUG 在Chrome Canary里面也有, 所以也不能全赖微软, 不过谷歌那边已经在最新版修复了, 微软这边可能因为过节没法加班... 只好先自己搞喽.

如果觉得我的文章对你有用,请随意赞赏