WinAutoHide – 让窗口贴边隐藏(更新到v1.02)

V2 用户的话,推荐用 H 版,AutoHotkey 的最富集,兼容 L 版

EdgeHiding(hwnd, to := 1) {
	if InStr('|Progman|Shell_TrayWnd|WorkerW|', '|' WinGetClass(hwnd) '|')
		return

	if id := DllCall('FindWindowW', "ptr", 0, "str", 'EdgeHiding_' hwnd, "ptr")
		return SendMessage(40400, , , , id)

	if DllCall("IsZoomed", "ptr", hwnd)
	{
		WinRestore hwnd
		Sleep 20
	}

	WinGetPos &x, &y, &w, &h, hwnd
	b := SysGet(4)

	switch to ;1下 ,2左, 3上, 4右
	{
		case 1:
			mx := x
			my := A_ScreenHeight - h
			ax := x
			ay := A_ScreenHeight - 2
			aw := w
			ah := 2
		case 2:
			mx := 0
			my := y
			ax := -20
			ay := y
			aw := 22
			ah := h - b
		case 3:
			mx := x
			my := -20
			ax := x
			ay := 0
			aw := w
			ah := 22
		default:
			mx := A_ScreenWidth - w
			my := y
			ax := A_ScreenWidth - 1
			ay := y
			aw := 1
			ah := h - b
	}

	WinMove mx, my, , , hwnd
	ui := Gui('+Owner' hwnd ' -Caption AlwaysOnTop +ToolWindow +E0x8000000', 'EdgeHiding_' hwnd)

	ui.exsty := DllCall("GetWindowLongW", "ptr", hwnd, "int", -20, "int")
	ui.sty := DllCall("GetWindowLongW", "ptr", hwnd, "int", -16, "int")

	WinSetAlwaysOnTop 1, hwnd
	WinHide hwnd


	WinSetStyle -0xC00000, hwnd ; 隐藏标题栏

	;WinSetExStyle +0x80, hwnd ;隐藏三按钮
	;WinSetStyle +0x80000000, hwnd ;弹窗模式,特点是无边框


	ui.show("NoActivate  x" ax " y" ay " w" aw " h" ah)

	WinSetTransparent 1, ui.hwnd
	ui.OnMessage(0x200, EdgeHiding_show)
	ui.OnMessage(40400, EdgeHiding_destroy)

	ui.win := hwnd
	ui.x := x
	ui.y := y
}


EdgeHiding_destroy(ui, *) {
	ui.de := 1
	WinActivate ui.hwnd
	Sleep 20

	;WinSetExStyle -0x80, ui.win
	;WinSetStyle -0x80000000, ui.win

	WinSetStyle +0xC00000, ui.win
	DllCall("SetWindowLongW", "ptr", ui.win, "int", -20, "int", ui.exsty)
	DllCall("SetWindowLongW", "ptr", ui.win, "int", -16, "int", ui.sty)

	WinSetAlwaysOnTop 0, ui.win

	WinShow ui.win
	WinMove ui.x, ui.y, , , ui.win
	WinActivate ui.win

	ui.destroy()
}

EdgeHiding_show(ui, *) {
	ui.OnMessage(0x200, EdgeHiding_show, 0)
	ui.Hide()

	if !WinExist(ui.win)
		return SendMessage(40400, , , , ui.hwnd)

	WinShow ui.win
	WinActivate ui.win
	WinWaitNotActive ui.win
	if ui.HasOwnProp('de')
		return

	if !WinExist(ui.win)
		return SendMessage(40400, , , , ui.hwnd)

	WinHide ui.win
	ui.show('NoActivate')
	ui.OnMessage(0x200, EdgeHiding_show)
}

如果都要判断各个边缘的自动隐藏窗口在鼠标离开时的大小、位置变化然后是否该隐藏或隐藏要移动的距离,那这要得经过大改写了,原代码的架构要实现会非常冗余……

.OnMessage()

这个功能原来是 2.1 的新功能,不是 2.0。不过 H2.0 已经包含了。

1 Like

哈哈,我一般置顶就行了,隐藏类的程序用的少。 :grinning:

怎么把热键改为ctrl或者alt 加方向键啊?win键我占用了

脚本第19~22行的“#”代表的是Win键,改成“^”表示Ctrl键,改成“!”表示Alt键。

好的 感谢

有这么个软件preme for windows也有类似功能,而且更优雅,按住左键在最小化按钮处向某个方向拉,就会隐藏到对应的边缘.还有角触发,按键映射啥的,功能也不少

界面的确优雅有特色,而且很多便利功能。隐藏窗口还有流畅动画,值得推荐。
——
就是不明白为啥要整四份分身(还有一份在Program Files中):


而且必须安装,不能绿色运行。

我还真没注意过,放两个地方是权限问题吧,

为啥四个都一样我猜不出来,难道名字不一样还能有不同的功能么

才发现,这个东西也是ahk写的

还真是AHK:


似乎是通过不同的文件名来区分该执行哪部分功能……算是为了判断是否已安装,那也不用这么多份吧,况且其还释放了“Preme for Windows”文件夹来存放一些素材文件;而且放 AppData 文件夹并不能提升权限,放 Program Files 中才能。
我只能认为,作者希望Preme在使用者电脑中稳当住下,想尽了办法不让别人通过“复制-粘贴”就获得绿色版。

有点 low

反馈些bug,在桌面隐藏一个文本文件窗口到右侧,鼠标这时候再点击空白桌面,再按下快捷键会出现热键无法正确唤出刚才隐藏的文本文件窗口.另外鼠标悬停窗口后,移开也会有窗口无法隐藏的情况出现.
可否优化一下, 观测鼠标的代码.

反馈一个bug,把窗口设置为可隐藏的窗口后,在窗口里用输入法打字会导致窗口自动隐藏。使用场景:把微信贴边隐藏后,鼠标移到该边缘时弹出微信窗口,用输入法打字就会使窗口自动隐藏

是这样的,不激活(通过悬停使其显示)那个隐藏的窗口,快捷键的作用就是隐藏当前窗口;激活了才是取消隐藏;这脚本没有快捷键“唤出”(使隐藏窗口仅显示但不取消自动隐藏状态)的功能。

具体是怎样的窗口会出现这种情况呢?

你用的是什么输入法呢? 自动隐藏的微信窗口里打字不会让其自动隐藏的啊,至少我用的几种输入法(多多输入法框架、RIME输入法) 都不会这样。
——
嗯……我测试启程输入法的时候,只要鼠标移上其候选窗,就会让AHK认为鼠标已经移出自动隐藏的窗口……的确是个问题,后续看根据鼠标屏幕位置来判断是不是能解决这问题。

我用的是自带的微软输入法,鼠标没有移动,只要出现了拼音候选框就会自动隐藏
ahk_class ApplicationFrameWindow
ahk_exe explorer.exe
ahk_pid 24900
ahk_id 66726
用win+v打开剪切板也是,出现剪切板就会使窗口自动隐蔽
ahk_class Shell_LightDismissOverlay
ahk_exe explorer.exe
ahk_pid 24900
ahk_id 395672

我想要修改触发隐藏窗口弹回的鼠标焦点区域,比如左右屏幕边缘中间50%部分,但是没找到;
有人知道改哪里吗?