简体   繁体   English

在Windows 8上设置前景窗口

[英]Set foreground window on Windows 8

I've read about a few ways to force a window to be displayed on the foreground with C#, making use of Win32's user32.dll. 我已经了解了几种使用Win32的user32.dll强制使用C#将窗口显示在前台的方法。

These work perfectly, except for one situation. 除一种情况外,这些都可以正常工作。 On Windows 8, if either the Start Menu or a Windows Store App is on the foreground, these will fail. 在Windows 8上,如果“开始”菜单或Windows Store应用程序位于前台,则这些操作将失败。

I only need to make this work when the Start Menu is on the foreground though. 我只需要在“开始”菜单位于前台时进行此工作。 Is there an hidden way to accomplish this? 有隐藏的方法可以做到这一点吗?

            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);
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将 Windows 任务栏设置为前台窗口/进程 - Set Windows taskbar as foreground window/process C#SendKeys到Windows 7中的前景窗口不起作用 - C# SendKeys to foreground window in Windows 7 not working 将 window 带到前台拒绝在 windows 中工作 10 - Bring window to foreground refuses to work in windows 10 如何通过部分标题名称设置前景window> - How to set foreground window by partial title name> 如何在窗口中将所有标签前景设置为白色? - How to set that all Lable foreground is White in Window? 启动旧桌面应用程序,即使Windows 8开始屏幕是前景窗口? - Launch legacy desktop app, even if Windows 8 Start Screen is foreground window? C# 从控制台进程设置前台 window - C# set foreground window from Console process 在Universal Windows中通过Storyboard设置TextBlock前景不起作用 - Set TextBlock Foreground via Storyboard in Universal Windows doesn't work 设置为Windows窗体应用程序中的第三方对话框 - Set to foreground a third party dialog in a Windows Form Application 如何在window.Deactivate事件上执行方法,除非新的前台/活动窗口在预定义的窗口列表中? - How to execute a method on the window.Deactivate event unless the new foreground/active window is in a predefined list of windows?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM