AutoHotkey - 使窗口停留在任务栏右侧

AutoHotkey - 使窗口停留在任务栏右侧

有没有办法使用 autohotkey 来实现这一点:无论我打开了多少个程序,我希望某些窗口始终位于任务栏的右上角。例如,目前它是这样的。但是,我希望记事本始终位于任务栏的最右侧。因此,例如。因此,无论我打开多少个程序,我都希望记事本在任务栏上始终位于最右边。

我使用的是 Windows 8.1 和最新版本的 AutoHotkey。一些解释:我不希望记事本窗口本身位于屏幕的最右侧。不,而是我希望记事本任务栏上的图标位于最右侧。因此,如果我例如打开新程序,我希望图标自动移动到右侧,这样记事本图标后面就不会出现任何图标。

我在网上搜索了一下,没有找到任何有用或类似的东西。所以,我想做的是让记事本的图标始终位于右侧。我不在乎我打开的所有记事本是否会移到右侧,或者只是打开的记事本会移到右侧,这无所谓,我只打开 4 个记事本并保留它们,直到我关闭电脑,所以我永远不会关闭它们。

如何实现呢?我相信一定有办法,因为 AutoHotkey 是一款非常好的软件,而且有很多增强功能。

提前谢谢您。这是我在这个网站上的第一个问题,所以请保持尊重。谢谢。

答案1

据我所知,移动任务栏上的图标的唯一方法是拖动它们,因此这是一个以编程方式执行该过程的 AHK 脚本:

^F1::
    toggle = true
    Window = 0
    while (toggle) {
        OldWindow = %Window%
        WinGet Window, List

        if (Window > OldWindow) {
            SetTitleMatchMode, RegEx
            IfWinExist, Notepad$
            {
                WinActivate
            } Else {
                ; MsgBox Cannot find Notepad window.
                Continue
            }
            ; absolute coordinate
            CoordMode Pixel, Screen
            CoordMode Mouse, Screen
            Sleep, 100 ; wait for the Notepad icon to be fully highlighted, because Windows have animation of lighting icon
            ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *5 *TransWhite D:\np.bmp
            ; allow some variation because Windows have anti-aliasing etc.

            ; ImageSearch, FoundX, FoundY, 0, 0, A_ScreenWidth, A_ScreenHeight, *10 *Icon1 %A_WinDir%\system32\notepad.exe
            ; because of some reason the above command does not work
            if ErrorLevel = 2
                MsgBox Could not conduct the search.
            else if ErrorLevel = 1
                MsgBox Icon could not be found on the screen.
            else {
                MouseGetPos OldX, OldY
                SetDefaultMouseSpeed, 0
                MouseMove, %FoundX%, %FoundY%
                Click down left
                MouseMove, A_ScreenWidth, %FoundY% ; move the mouse all the way to the right
                Click up left
                MouseMove, %OldX%, %OldY% ; move mouse to old position
            }
        }

        Sleep, 500 ; can be omitted
    }
Return

^F2::
    toggle = false
Return

笔记:

  • 由于某些原因,我无法使用*Icon1 %A_WinDir%\system32\notepad.exe或类似的东西,您需要D:\np.bmp在记事本处于焦点时提供一个由记事本托盘图标组成的文件。
  • 按下^F1打开,^F2按下关闭。
  • 用于拖动记事本任务图标的部分在每次报告的窗口数量WinGet增加时(即打开新窗口时)执行。
  • 每次将记事本窗口拖到右侧时,它都会获得焦点。
  • 除了使用无限循环(),我不知道每次运行命令的任何方法while (toogle)。这可能会消耗 CPU。

答案2

我不知道有任何内置或低门槛的解决方案可以解决此问题。如果您真的需要此功能,我想您必须制作自己的辅助应用程序,以便您指定进程并重新排列任务栏上的窗口按钮。这可以实现,但需要一些 Win32 和 C++/C# 知识。我尝试了 30 分钟(我的个人极限)。

这就是我所做的:这个线程是一个完美的起点:如何获取具有系统托盘图标的进程 第 6 点. 为您提供针对过时(32 位)Windows 版本的有效解决方案:用于在任务栏中排序窗口按钮的工具 不幸的是,它不能在 64 位操作系统和 Windows 10 下运行。

尽管如此,我在探索示例 6 的过程中发现了一些问题:要在 Windows 10 上找到任务栏,请使用以下代码:

...
//IntPtr hToolbar = User32.FindWindowEx( hTask, IntPtr.Zero, "ToolbarWindow32", null ); xp +
IntPtr taskBarWnd = User32.FindWindowEx(hTask, IntPtr.Zero, "MSTaskListWClass", null);

您将需要 TBBUTTON 结构的 64 位定义:

[StructLayout(LayoutKind.Sequential)]
public struct TBBUTTON
{
    public int iBitmap;
    public int idCommand;
    [StructLayout(LayoutKind.Explicit)]
    private struct TBBUTTON_U
    {
        [FieldOffset(0)]
        public byte fsState;
        [FieldOffset(1)]
        public byte fsStyle;
        [FieldOffset(0)]
        private IntPtr bReserved;
    }
    private TBBUTTON_U union;
    public byte fsState { get { return union.fsState; } set { union.fsState = value; } }
    public byte fsStyle { get { return union.fsStyle; } set { union.fsStyle = value; } }
    public UIntPtr dwData;
    public IntPtr iString;
}

这应该为您提供一个自行制定解决方案的良好起点。

另一个有用的起点可能是7+ 任务栏调整器,它有一些非常方便的任务栏调整(顾名思义)。7+TT 还提供了一个库,可以为您完成大部分(黑色)魔法,也可以作为 DIY 解决方案的起点(此外,它甚至可以在 Windows 1607 上运行。查看打印任务栏内容示例;AppId 是一个很好的钩子,可以找到正确的任务栏按钮窗口/按钮组)。

祝你好运。

更新
在 7+TT Lib 的帮助下,您的目标很容易实现。
这里工作样本我已经制作了(存档包含我的示例源代码以及 x64/Release 文件夹中的二进制文件,名为 taskbar_pusher,它应该适用于 Windows 7 - 10 直至最新版本 v1709)。

您必须指定要推送到任务栏后端的按钮组的 AppId,就像命令行参数一样:

./taskbar_pusher {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\notepad.exe

您可以从我的工具的 CLI 输出中获取 AppId。
您应该能够像这样使用 AHK 进行参数化(尽管我对 AHK 不太熟悉)。

附言:我的辅助任务栏出现了一些问题,因此禁用了代码来检测它。

相关内容