AutoHotkey - 讓視窗保持在工作列右側

AutoHotkey - 讓視窗保持在工作列右側

有沒有辦法使用自動熱鍵來實現此目的:無論我打開多少個程序,我都希望某些視窗始終位於任務欄的右上角。所以,例如,目前就像。但是,我希望記事本始終位於工作列的最右側。所以,例如像。因此,無論我打開多少個程序,我都希望任務欄上的記事本始終位於最右側。

我使用的是 Windows 8.1 和最新版本的 AutoHotkey。一些解釋:我不希望記事本的視窗本身位於螢幕的最右側。不,但我希望記事本任務欄上的圖示位於最右側。因此,如果我打開新程序,我希望圖標自動移動到右側,以便記事本圖示後面沒有圖示。

我在互聯網上搜索,沒有找到任何有用或類似的東西。所以,我想做的就是讓記事本的圖示始終位於右側。我不在乎我打開的所有記事本是否都會移到右側或只是打開的記事本位於右側,沒關係,我只是打開4個記事本並保留它們直到我關閉計算機,所以我永遠不要關閉它們。

如何實現?我確信一定有辦法,因為 AutoHotkey 是非常好的軟體並且有很多增強功能。

先感謝您。這是我在這個網站上的第一個問題,所以請尊重。感謝。

答案1

AFAIK 在工作列上移動圖示的唯一方法是拖曳它們,因此這是以程式設計方式執行該程序的 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#的知識。

這就是我所做的:該線程是完美的起點:如何取得具有系統托盤圖示的進程 第 6 點. 為您提供適用於過時(32 位元)版本的 Windows 的有效解決方案:用於對工作列中的視窗按鈕進行排序的工具 不幸的是,它無法在 64 位元作業系統和 Windows 10 下運行。

儘管如此,我在探索 6 中提供的範例時發現了一些發現:要在 Window 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 不是很熟悉)。

PS:我的輔助工作列出現了一些問題,因此禁用了程式碼來偵測它。

相關內容