![](/img/trans.png)
[英]How to hide the Taskbar on Windows 8 programmatically on a normal user environment?
[英]How to programmatically move Windows taskbar?
我想知道任何类型的 API 或解决方法(例如,脚本或注册表)以将 Windows 任务栏移动(或调整大小)到另一个 position 包括另一个显示器(如果双显示器)。 当然,我们可以使用鼠标移动任务栏,但我想通过程序或某种自动化方式移动它。
我试图找到 Win32 API,但似乎没有人做这项工作。
编辑:我对很多人的意见感到惊讶。 让我解释一下为什么我想要它。 在我的工作场所,我使用双显示器(分辨率不同),任务栏位于左侧显示器上,而主显示器是右侧显示器。 但是,我经常通过远程桌面连接到我工作场所的计算机。 远程连接后切换到任务栏position。 这就是为什么我想制作一个简单的程序来保存/恢复任务栏的 position。每天我都必须重新排列我的任务栏。 就是这样。 我只是想要它给我。
我在 Windows 7 上也有这个需求。这是我使用 autohotkey 脚本执行此操作的方法:
; This script will try to drag and move the taskbar to where the *current* mouse
; cursor is
; 0x111: WM_COMMAND, 424: lock/unlock taskbar, http://www.codeproject.com/KB/miscctrl/Taskbar_Manipulation.aspx
RegRead, TaskbarLocked, HKEY_CURRENT_USER, SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced, TaskbarSizeMove
If TaskbarLocked = 0
SendMessage 0x111, 424, , , ahk_class Shell_TrayWnd
WinActivate ahk_class Shell_TrayWnd
MouseGetPos targetX, targetY
ControlGetPos x, y, w, h, MSTaskListWClass1, ahk_class Shell_TrayWnd
MouseMove x+1, y+1
MouseClickDrag Left, x+1, y+1, targetX, targetY, 10
; often after dragging the taskbar to left or right side of a monitor, even though
; there are enough room to show two columns of icons, it will only show one column,
; it seems showing or hiding an icon will fix this
Menu, Tray, NoIcon
Menu, Tray, Icon
; lock the taskbar if it was previously locked
If TaskbarLocked = 0
SendMessage 0x111, 424, , , ahk_class Shell_TrayWnd
我已经在带有经典窗口主题的 Windows 7 上对此进行了测试。 要使用它,请分配一个热键来调用此脚本,然后将鼠标光标定位到要将任务栏拖到的位置,然后按热键。
任务栏是一个窗口。 使用SetWindowPos()移动它。 另见SHAppBarMessage()和 ABM_WINDOWPOSCHANGED。
尽管任务栏可能很特殊,Windows 可能不喜欢您四处移动它。 任务栏的Shell appbar API实现中有很多特殊情况。
要移动到另一个监视器,请使用EnumDisplayMonitors()和GetMonitorInfo() 。 一些显示器可能有负坐标。
我在 AutoHotkey 脚本中完成了这项任务,以防万一您不关心所使用的语言。 它使用模拟的击键和鼠标移动来移动您的任务栏。 我没有自动解锁/锁定任务栏。
困难的部分是让它可靠地工作。 许多代码专门用于确保任务栏移动。 它仍然不能 100% 工作......从我所看到的情况来看,它有 10% 的时间失败。 但是,它应该足以让您入门!
如果我回到这个脚本以使其完美运行,我会在这里重新发布。
这是示例脚本(这里的突出显示有点奇怪,因为语言是 AHK):
F3::
reload
return
F5::
MoveTaskbar(2,"bottom")
return
F6::
MoveTaskbar(2,"left")
return
F7::
MoveTaskbar(1,"top")
return
; Move the taskbar
; dspNumber: number. device number (primary display is 1, secondary display is 2...)
; edge: string. Top, Right, Bottom, or Left
MoveTaskbar(dspNumber, edge)
{
Critical
OutputDebug MoveTaskbar - called to move taskbar to display #%dspNumber% ("%edge%" edge)
; absolute coordinate system
CoordMode, Mouse, Screen
; error checking for dspNumber
SysGet, numMonitors, MonitorCount
if (numMonitors<dspNumber)
{
OutputDebug MoveTaskbar - [ERROR] target monitor does not exist (dspNumber = "%dspNumber%")
return
}
; get screen position for target monitor
SysGet, target, Monitor, %dspNumber%
oX := 7
oY := 7
; get coordinates for where to move the taskbar
if (edge = "Top")
{
oX := (targetRight-targetLeft)/2
trgX := oX+targetLeft
trgY := targetTop+15
}
else if (edge = "Right")
{
oY := -(targetBottom-targetTop)/2
trgX := targetRight-15
trgY := -oY + targetTop
}
else if (edge = "Bottom")
{
oX := -(targetRight-targetLeft)/2
trgX := -oX+targetLeft
trgY := targetBottom-15
}
else if (edge = "Left")
{
oY := (targetBottom-targetTop)/2
trgX := targetLeft+15
trgY := oY+targetTop
}
else
{
OutputDebug MoveTaskbar - [ERROR] target edge was improperly specified (edge = "%edge%")
return
}
trgX := round(trgX)
trgY := round(trgY)
oX := round(oX)
oY := round(oY)
OutputDebug MoveTaskbar - target location is (%trgX%,%trgY%)
MouseGetPos, startX, startY
OutputDebug MoveTaskbar - mouse is currently at (%startX%,%startY%)
; request the move mode (via context menu)
SendInput #b
SendInput !+{Space}
SendInput m
; wait for the move mode to be ready
Loop
{
if A_Cursor = SizeAll
break
}
OutputDebug MoveTaskbar - move mode is ready
; start the move mode
SendInput {Right}
; wait for the move mode to become active for mouse control
Loop
{
if A_Cursor = Arrow
break
}
OutputDebug MoveTaskbar - move mode is active for mouse control
; move taskbar (and making sure it actually does move)
offset := 7
count := 0
Loop
{
; move the taskbar to the desired location
OutputDebug MoveTaskbar - attempting to move mouse to (%trgX%,%trgY%)
MouseMove, %trgX%, %trgY%, 0
MouseGetPos, mX, mY, win_id
WinGetClass, win_class, ahk_id %win_id%
count += 1
; if the mouse didn't get where it was supposed to, try again
If ((mX != trgX) or (mY != trgY))
{
OutputDebug MoveTaskbar - mouse didn't get to its destination (currently at (%mX%,%mY%)). Trying the move again...
continue
}
; if the taskbar hasn't followed yet, wiggle the mouse!
if (win_class != "Shell_TrayWnd")
{
OutputDebug MoveTaskbar - window with class "%win_class%" is under the mouse... wiggling the mouse until the taskbar gets over here
;offset := - offset
trgX -= round(oX/2)
trgY -= round(oY/2)
oX := -oX
oY := -oY
if count = 50
{
OutputDebug, MoveTaskbar - wiggling isn't working, so I'm giving up.
return
}
}
else
break
}
OutputDebug MoveTaskbar - taskbar successfully moved
SendInput {Enter}
}
据我所知,Vista 及以后的版本会忽略任何试图移动任务栏的程序。 旧方法是 ABM_SETPOS + MoveWindow,这不再适用于任务栏。 我知道仍然有效的唯一方法是模拟鼠标移动(点击-移动-释放)。 我读过这种方法,但我自己从来没有做过。
感谢您提出这个问题!
它现在是 Windows 10,我遇到了同样的问题,我制作了一个脚本来在 2 个屏幕设置和电影电视之间切换。 切换回 2 个屏幕设置后,任务栏又回到了正确的显示器上,就像您所经历的那样。
我找到了一个解决方案,涉及修改定义任务栏位置的注册表项。
这是所说的键:HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects3
在任务栏处于正确位置和大小时打开注册表编辑器(Win+R,键入 regedit”,回车),然后导航到上面的关键路径。您应该找到一个名为“Settings”的二进制值,如下所示:
30 00 00 00 fe ff ff 02 00 00 00 03 00 00 00 4e 00 00 00 32 00 00 00 80 f8 ff ff b2 01 00 00 0 0 ff 0 0 0 ff 0 0 0 ea
您的数字可能会有所不同,但这并不重要。 导航到该值后,只需单击菜单中的文件>导出操作,然后使用顶部菜单中的文件->导出选项,并将 .reg 文件保存在您的系统文件夹 (C:\\Windows\\System32) 中。 确保导出范围设置为“Selected Branch”,这样只有这个值会受到影响。 这将创建一个注册表脚本,该脚本将恢复任务栏的确切位置。
但是,如果您只是在脚本上使用“合并”选项,您将看不到更改,因为您需要重新启动 explorer.exe 进程。 为此,您可以简单地在 noptepad 中制作一个批处理脚本,如下所示:
@echo off
%windir%\system32\regedit.exe /s file.reg
taskkill /f /im explorer.exe
start explorer.exe
end
只需将第二行中的“file.reg”替换为您之前创建的 .reg 脚本的完整文件名,然后将该文件另存为“.bat”。
以管理员身份运行此脚本会将任务栏重置到应有的位置。 您将看到 ui 短暂闪烁,因为任务栏和桌面将重置。
您可以从 Task 调用此脚本,或者创建一个设置为以管理员身份运行的快捷方式,以使其更容易!
我希望这个答案能传达给你,即使是“有点”迟到 XD
欢迎您!
这是 PowerShell 的解决方案。我的代码基于此处答案中提供的解决方案:
2,3 | ForEach-Object {
$local:regPath = "HKCU:\$(
)SOFTWARE\Microsoft\Windows\$(
)CurrentVersion\Explorer\StuckRects$_"
$s = Get-ItemProperty $regPath |
Select-Object -ExpandProperty Settings
$s[12] = 2
Set-ItemProperty -Path $regPath -Name Settings -Value $s
}
# Restart the Explorer process so that registry is read again
Get-Process Explorer | Stop-Process
$local:stop = $false
do {
Start-Sleep -Seconds 5
$stop = Get-Process Explorer -ErrorAction SilentlyContinue
if( $stop ) { continue }
Write-Host -ForegroundColor Yellow "$(
)Explorer hasn't auto-started, attempting to restart..."
Start-Process Explorer
} until ( $stop )
代码将更改为2
(右侧) Settings
注册表 stream 的第 13 个 position 在以下键:
HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StuckRects2
HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3
之后,它会杀死explorer.exe
进程,等待大约 5 秒,如果 explorer 没有再次启动,它将启动一个新实例。
SHAppBarMessage(ABM_SETPOS,...)
根据我的经验,左右两侧的任务栏与体验的 rest 不兼容。 即使是顶部也有预览出现在顶部屏幕之外的问题。
对我来说,这在 windows 11 中有效,可以在顶部和底部之间切换任务栏。
$RegistryPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3'
$Name = "Settings"
$NewValue = Get-ItemProperty -Path $RegistryPath
$NewValue.Settings[12] = 4-$NewValue.Settings[12]
Set-ItemProperty -Path $RegistryPath -Name $Name -Value $NewValue.Settings
Stop-Process -Name "Explorer"
资源管理器在被终止时自动启动,因此无需手动启动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.