簡體   English   中英

如何將 outlook 2021 window 帶到前面

[英]How to bring outlook 2021 window to front

我想從 VSTO 加載項中將 Outlook 的主要 window 帶到前面。 我嘗試了這個問題的各種答案中描述的方法,但它似乎不起作用,至少對於 Outlook 2021 而言。

我得到 Outlook 主窗口的句柄(我使用 spy++ 驗證並且似乎是正確的),使用

Process.GetProcessesByName("outlook").FirstOrDefault().MainWindowHandle

或者

(Globals.ThisAddIn.Application.ActiveExplorer() as IOleWindow).GetWindow()

(兩者產生相同的結果)。

然后我嘗試將 window 放在前面(可能有一些多余的調用,我只是盡我所能讓它工作):

ShowWindow(proc.MainWindowHandle, SW_SHOWNORMAL);
ShowWindow(proc.MainWindowHandle, SW_RESTORE);
SetForegroundWindow(proc.MainWindowHandle);
SwitchToThisWindow(proc.MainWindowHandle, true);

我究竟做錯了什么?

所有 Outlook windows 都實現了IOleWindow接口,該接口提供了允許應用程序獲取參與就地激活的各種 windows 的句柄的方法。 So, you can use the retrieved window handle for calling Windows API functions such as SetForegroundWindow method which brings the thread that created the specified window into the foreground and activates the window. 此外,鍵盤輸入指向 window,並且為用戶更改了各種視覺提示。

您也可以考慮調用Explorer.ActivateInspector.Activate方法,通過將其置於前台並設置鍵盤焦點來激活資源管理器或檢查器 window。

事實證明,缺少的部分是在調用 SetForegroundWindow() 之前模擬 ALT 單擊(只需向上部分就足夠了)。 無需調用 SwitchToThisWindow()。

作為獎勵,設置 ActiveExplorer().CurrentFolder() =... 可靠地向上和向下滾動到所選文件夾(當 outlook 不在前台時,它沒有這樣做)。

只有前台進程可以使用SetForegroundWindow設置活動的 window 。 要欺騙 Windows 認為您的進程在前台,請使用AttachThreadInput 這是我使用的:

        public static bool ForceForegroundWindow(IntPtr hWnd)
        {
            bool Result = false;
            uint ForegroundThreadID = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
            uint ThisThreadID = GetWindowThreadProcessId(hWnd, IntPtr.Zero);
            if (AttachThreadInput(ThisThreadID, ForegroundThreadID, true))
            { 
                BringWindowToTop(hWnd); 
                SetForegroundWindow(hWnd);
                AttachThreadInput(ThisThreadID, ForegroundThreadID, false);
                Result = (GetForegroundWindow() == hWnd);
            }
            if (!Result)
            {
                int timeout = 0;
                SystemParametersInfo(SPI.SPI_GETFOREGROUNDLOCKTIMEOUT, 0, ref timeout, 0);
                int newTimeout = 0;
                SystemParametersInfo(SPI.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref newTimeout, SPIF.SPIF_SENDCHANGE);
                BringWindowToTop(hWnd); 
                SetForegroundWindow(hWnd);
                SystemParametersInfo(SPI.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, ref timeout, SPIF.SPIF_SENDCHANGE);
                Result = (GetForegroundWindow() == hWnd);
            }
            return Result;
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM