如何以编程方式移动 Windows 任务栏?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2067497/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to programmatically move Windows taskbar?
提问by minjang
I'd like to know any sort of API or workaround (e.g., script or registry) to move (or resize) Windows taskbar to another position including another monitor (if dual monitors). Definitely, we can move task bar by using mouse, but I want to move it by a program, or a sort of automated way.
我想知道任何类型的 API 或解决方法(例如,脚本或注册表)将 Windows 任务栏移动(或调整大小)到另一个位置,包括另一个显示器(如果是双显示器)。当然,我们可以通过鼠标移动任务栏,但我想通过程序或一种自动化的方式来移动它。
I tried to find Win32 API, but it seems no one does this job.
我试图找到 Win32 API,但似乎没有人做这项工作。
EDIT: I was surprised by many people's opinion. Let me explain why I wanted it. In my workplace, I'm using dual monitors (resolutions are different), and the taskbar is placed on the left monitor while the primary monitor is the right monitor. However, I often connect to my workplace computer via remote desktop. After the remote connection, the taskbar position is switched. That's why I wanted to make a simple program that can save/restore taskbar's position. Everyday I have to rearrange my taskbar. That's it. I just want it for me.
编辑:我对很多人的意见感到惊讶。让我解释一下我为什么想要它。在我的工作场所,我使用双显示器(分辨率不同),任务栏位于左侧显示器上,而主显示器位于右侧显示器上。但是,我经常通过远程桌面连接到我的工作场所计算机。远程连接后,任务栏位置切换。这就是为什么我想制作一个可以保存/恢复任务栏位置的简单程序。每天我都必须重新排列我的任务栏。就是这样。我只是想要它给我。
采纳答案by Bob Moore
As far as I can tell, Vista and onwards ignore any program trying to move the taskbar. The old method was ABM_SETPOS + MoveWindow, and this no longer works on the taskbar. The only way that I am aware of that still works is simulating a mouse move (click-move-release). I've read about that method, but I've never done it myself.
据我所知,Vista 及以后的版本会忽略任何试图移动任务栏的程序。旧方法是 ABM_SETPOS + MoveWindow,这不再适用于任务栏。我知道仍然有效的唯一方法是模拟鼠标移动(点击-移动-释放)。我读过这种方法,但我自己从来没有做过。
回答by wangzq
I also have this need on Windows 7. Here is my take to do this using autohotkey script:
我在 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
I have tested this on Windows 7 with classic window theme. To use this, assign a hotkey to call this script, then position mouse cursor to where you want to drag the taskbar to, then press the hotkey.
我已经在带有经典窗口主题的 Windows 7 上对此进行了测试。要使用它,请分配一个热键来调用此脚本,然后将鼠标光标定位到要将任务栏拖到的位置,然后按热键。
回答by i_am_jorf
The taskbar is a window. Use SetWindowPos()to move it. See also SHAppBarMessage()and ABM_WINDOWPOSCHANGED.
任务栏是一个窗口。使用SetWindowPos()移动它。另见SHAppBarMessage()和 ABM_WINDOWPOSCHANGED。
Though the taskbar may be special and Windows may not like you moving it around. There are a lot of special cases in the Shell appbar API implementation for the taskbar.
尽管任务栏可能很特别,Windows 可能不喜欢您四处移动它。任务栏的Shell appbar API实现中有很多特殊情况。
To move to another monitor, use EnumDisplayMonitors()with GetMonitorInfo(). Some monitors may have negative coordinates.
要移动到另一个监视器,请使用EnumDisplayMonitors()和GetMonitorInfo()。一些显示器可能有负坐标。
回答by Josh
I've had some luck with this task in an AutoHotkey script, just in case you don't care about the language used. It uses simulated keystrokes and mouse movements to move your taskbar. I stopped short of automatically unlocking/locking the taskbar.
我在 AutoHotkey 脚本中完成了这项任务,以防万一您不关心所使用的语言。它使用模拟的击键和鼠标移动来移动您的任务栏。我没有自动解锁/锁定任务栏。
The hard part was getting it to work reliably. A lot of the code is dedicated to making sure that the taskbar moved. It still doesn't work 100%... it fails like 10% of the time from what I've seen. However, it should be good enough to get you started!
困难的部分是让它可靠地工作。许多代码专门用于确保任务栏移动。它仍然不能 100% 工作......从我所看到的情况来看,它有 10% 的时间失败。但是,它应该足以让您入门!
If I ever come back to this script to make it work perfectly, I'll repost here.
如果我回到这个脚本以使其完美运行,我会在这里重新发布。
Here is the example script (highlighting is a bit odd here, as the language is AHK):
这是示例脚本(这里的突出显示有点奇怪,因为语言是 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}
}
回答by Anders
SHAppBarMessage(ABM_SETPOS,...)
SHAppBarMessage(ABM_SETPOS,...)
回答by étienne Bilodeau
Thank you for asking this question!
感谢您提出这个问题!
Its Windows 10 now and i got the same kind of problem where i made a script to switch between a 2 screens setup and only the tv for movies. After switching back to the 2 screens setup, the taskbar is back on the right monitor, just like you experienced.
它现在是 Windows 10,我遇到了同样的问题,我制作了一个脚本来在 2 个屏幕设置和电影电视之间切换。切换回 2 个屏幕设置后,任务栏又回到了正确的显示器上,就像您所经历的那样。
I found a solution involving modifying the registry keythat defines the taskbar location.
我找到了一个涉及修改定义任务栏位置的注册表项的解决方案。
This is the said key: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3
这是所说的键:HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3
Open the regisrty editor while your taskbar is at the right spot and size(Win+R, type regedit", the enter), then navigate to the key path above. You should find a binary value named "Settings" that looks like this:
在任务栏处于正确位置和大小时打开注册表编辑器(Win+R,键入 regedit”,回车),然后导航到上面的关键路径。您应该找到一个名为“Settings”的二进制值,如下所示:
30 00 00 00 fe ff 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 be f8 ff ff ea 05 00 00 60 00 00 00 01 00 00 00
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 0 0 0 ea
Your numbers may vary, but it doesn't matter. Simply click on file>export action in the menu once you navigated to the value, then use the file->export option from the top menu, and and save the .reg file in your system forlder (C:\Windows\System32). Make sure the export range is set to "Selected Branch" so only this value is affected. This will create a registry scriptthat will restore the exact position of your taskbar.
您的数字可能会有所不同,但这并不重要。导航到该值后,只需单击菜单中的文件>导出操作,然后使用顶部菜单中的文件->导出选项,并将 .reg 文件保存在您的系统文件夹 (C:\Windows\System32) 中。确保导出范围设置为“Selected Branch”,这样只有这个值会受到影响。这将创建一个注册表脚本,该脚本将恢复任务栏的确切位置。
However, if you just use the "merge" option on your script, you won't see the change since you will need to restart the explorer.exe process. To achieve this, you can simply make a batch scriptin noptepad looking like this:
但是,如果您只是在脚本上使用“合并”选项,您将看不到更改,因为您需要重新启动 explorer.exe 进程。为此,您可以简单地在 noptepad 中制作一个批处理脚本,如下所示:
@echo off
%windir%\system32\regedit.exe /s file.reg
taskkill /f /im explorer.exe
start explorer.exe
end
Simply replace in the 2nd line the "file.reg" by the complete file name of the .reg script you previously created, then save the file as a ".bat".
只需将第 2 行中的“file.reg”替换为您之前创建的 .reg 脚本的完整文件名,然后将该文件另存为“.bat”。
Running this script as an adminwill reset the taskbar to where it should be. You will see the ui flashing briefly, since the taskbar and desktop will reset.
以管理员身份运行此脚本会将任务栏重置到应有的位置。您将看到 ui 短暂闪烁,因为任务栏和桌面将重置。
You could call this script from a Task, or make a shortcutthat is set to run as admin to make it even easier!
您可以从 Task 调用此脚本,或者创建一个设置为以管理员身份运行的快捷方式,以使其更容易!
I hope this answer reaches you, even if is is a "little" late XD
我希望这个答案能传达给你,即使是“有点”迟到 XD
Your Welcome!
别客气!