How to programmatically move Windows taskbar?

前端 未结 6 685
无人及你
无人及你 2021-02-06 23:32

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).

相关标签:
6条回答
  • 2021-02-07 00:01

    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.

    I found a solution involving modifying the registry key that defines the taskbar location.

    This is the said key: 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:

    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

    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 script that will restore the exact position of your taskbar.

    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 script in noptepad looking like this:

    @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".

    Running this script as an admin will reset the taskbar to where it should be. You will see the ui flashing briefly, since the taskbar and desktop will reset.

    You could call this script from a Task, or make a shortcut that is set to run as admin to make it even easier!

    I hope this answer reaches you, even if is is a "little" late XD

    Your Welcome!

    0 讨论(0)
  • 2021-02-07 00:03

    The taskbar is a window. Use SetWindowPos() to move it. See also SHAppBarMessage() and 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.

    To move to another monitor, use EnumDisplayMonitors() with GetMonitorInfo(). Some monitors may have negative coordinates.

    0 讨论(0)
  • 2021-02-07 00:08

    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.

    0 讨论(0)
  • 2021-02-07 00:12

    SHAppBarMessage(ABM_SETPOS,...)

    0 讨论(0)
  • 2021-02-07 00:26

    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.

    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!

    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):

    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}
    }
    
    0 讨论(0)
  • 2021-02-07 00:27

    I also have this need on Windows 7. Here is my take to do this using autohotkey script:

    ; 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.

    0 讨论(0)
提交回复
热议问题