【问题标题】:SwitchToThisWindow [duplicate]SwitchToThisWindow [重复]
【发布时间】:2012-10-20 01:48:50
【问题描述】:

可能重复:
How can I bring my application window to the front?

我遇到了 SwitchToThisWindow 的问题

using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace BringToFront
{
    public partial class Form1 : Form
    {
        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(String className, String windowName);

        [DllImport("user32.dll", SetLastError = true)]
        static extern void SwitchToThisWindow(IntPtr hWnd, bool turnOn);

        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        IntPtr activeWindowHandle = GetForegroundWindow();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (!checkBox1.Checked)
                    bringToFront(comboBox1.SelectedItem.ToString());
                else
                    timer1.Enabled = true;
            }
            catch
            {
                MessageBox.Show("Please choose a Process Name");
            }
        }

        public static void bringToFront(string title)
        {
            IntPtr handle = FindWindow(null, title);
            if (handle == IntPtr.Zero)
            {
                return;
            }
            SwitchToThisWindow(handle, true);
        }

        private void comboBox1_Click(object sender, EventArgs e)
        {
            comboBox1.Items.Clear();
            Process[] process = Process.GetProcesses();
            foreach (Process processes in process)
            {
                if (!String.IsNullOrEmpty(processes.MainWindowTitle))
                    comboBox1.Items.Add(processes.MainWindowTitle.ToString());
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Process process = Process.GetCurrentProcess();
            string title = process.ProcessName.ToString();
            IntPtr handle = FindWindow(null, title);

            if (activeWindowHandle != handle)
                bringToFront(comboBox1.SelectedItem.ToString());
            if (!checkBox1.Checked)
                timer1.Enabled = false;
        }
    }
}

如您所见,我正在尝试将选定的进程置于最前面,并通过每 5 秒执行一次计时器并将其重新置于最前面来将其保持在最前面。通过 Microsoft Visual Studios 运行应用程序时,它可以完美运行,但是当我作为独立程序运行该程序时,它的工作方式与其他所有类似的功能一样,只是让它在任务栏中闪烁,而不是把它带到前面。

为什么权限不同,有办法解决这个问题吗?

【问题讨论】:

  • 不,你不能也不应该解决这个问题。它是故意破坏的,以防止烦人的应用程序一直窃取焦点。如果您想保持领先,请将您的应用标记为最顶层窗口。
  • @Jon 但是我需要让可执行文件保持在最上面,而不是我的应用程序,我不想做任何恶意的事情,事实上我需要我的其他应用程序保持焦点,同时其他的东西在后台运行,如果应用程序重新启动将它带回到前面。我可以看到人们如何滥用它,但我出于合法目的需要它>.
  • 我很同情,Angel,但你不需要说服我们,你需要说服微软。

标签: c# winforms


【解决方案1】:

通过@ReedCopsy here 的解决方案,我建议您在切换到该窗口后将所选句柄设为TopMost。使用此解决方案,任何新应用都不会超过所选窗口。

将以下内容添加到您的代码中:

 [DllImport("user32.dll")]
 static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

 static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
 const UInt32 SWP_NOSIZE = 0x0001;
 const UInt32 SWP_NOMOVE = 0x0002;
 const UInt32 SWP_SHOWWINDOW = 0x0040;

并通过添加对SetWindowPos 的调用来更改您的bringToFront:

   public static void bringToFront(string title)
    {
        IntPtr handle = FindWindow(null, title);
        if (handle == IntPtr.Zero)
        {
            return;
        }
        SwitchToThisWindow(handle, true);


        // Call this way:
        SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    }

【讨论】:

    猜你喜欢
    • 2011-01-20
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 2012-06-22
    • 2016-07-08
    • 2020-06-14
    • 2014-09-14
    • 2015-06-20
    相关资源
    最近更新 更多