在Windows 8上设置前景窗口

本文关键字:窗口 设置 Windows | 更新日期: 2023-09-27 18:20:23

我读到了一些使用C#强制窗口显示在前台的方法,这些方法使用Win32的user32.dll

  • 如何将非托管应用程序窗口置于前台,并使其成为(模拟)用户输入的活动窗口
  • https://shlomio.wordpress.com/2012/09/04/solved-setforegroundwindow-win32-api-not-always-works/

除了一种情况外,这些都非常有效。在Windows 8上,如果"开始"菜单或Windows应用商店应用程序位于前台,则这些操作将失败。

不过,我只需要在"开始"菜单处于前台时才能使其工作。有没有隐藏的方法来实现这一点?

在Windows 8上设置前景窗口

            DispatcherHelper.CheckBeginInvokeOnUI(async () =>
            {
                try
                {  
                    if (!this.IsActive)
                    {
                        //pressing windows button
                        InputSimulator.SimulateKeyPress(VirtualKeyCode.LWIN);
                    }
                    await Task.Delay(1000);
                    ApplicationRunningHelper.GetCurrentProcessOnFocus();
                }
                catch (Exception ex)
                {
                 ...
                }
            });
 public static class ApplicationRunningHelper
    {
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        [DllImport("user32.dll")]
        private static extern bool IsIconic(IntPtr hWnd);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
        // When you don't want the ProcessId, use this overload and pass 
        // IntPtr.Zero for the second parameter
        [DllImport("user32.dll")]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
        [DllImport("kernel32.dll")]
        public static extern uint GetCurrentThreadId();
        /// The GetForegroundWindow function returns a handle to the 
        /// foreground window.
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();
        [DllImport("user32.dll")]
        public static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool BringWindowToTop(IntPtr hWnd);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool BringWindowToTop(HandleRef hWnd);
        [DllImport("user32.dll")]
        public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
        //one source
        private static int SW_HIDE = 0;
        private static int SW_SHOWNORMAL = 1;
        private static int SW_SHOWMINIMIZED = 2;
        private static int SW_SHOWMAXIMIZED = 3;
        private static int SW_SHOWNOACTIVATE = 4;
        private static int SW_RESTORE = 9;
        private static int SW_SHOWDEFAULT = 10;
        //other source
        private static int SW_SHOW = 5;
        /// <summary>
        /// check if current process already running. if runnung, set focus to 
        /// existing process and returns true otherwise returns false.
        /// </summary>
        /// <returns></returns>
        public static bool GetCurrentProcessOnFocus()
        {
            try
            {
                Process me = Process.GetCurrentProcess();
                Process[] arrProcesses = Process.GetProcessesByName(me.ProcessName);
                IntPtr hWnd = arrProcesses[0].MainWindowHandle;
                ForceForegroundWindow(hWnd);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        public static void ForceForegroundWindow(IntPtr hWnd)
        {
            uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
            uint appThread = GetCurrentThreadId();
            const uint SW_SHOW = 5;
            if (foreThread != appThread)
            {
                AttachThreadInput(foreThread, appThread, true);
                BringWindowToTop(hWnd);
                ShowWindow(hWnd, SW_SHOW);
                AttachThreadInput(foreThread, appThread, false);
            }
            else
            {
                BringWindowToTop(hWnd);
                ShowWindow(hWnd, SW_SHOW);
            }
        }
    }