2

Possible Duplicate:
How can I bring my application window to the front?

I am having an issue with 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;
        }
    }
}

As you can see I'm trying to bring the process that is selected to the front and keep it in the front by doing a timer every 5 seconds and rebringing it to the front. It works perfectly when running the application through Microsoft Visual Studios, but when I run the program as a standalone, it works how every other function like this does and only makes it flash in taskbar instead of bringing it to the front.

Why are the permissions different and is there anyway to fix this?

Community
  • 1
  • 1
  • No, you can't and shouldn't fix this. It's intentionally broken to keep annoying apps from stealing focus all the time. If you want to stay on top, mark your app as a topmost window. – Jon Oct 20 '12 at 01:51
  • @Jon But I need to make the executable stay top-most, not my app, I don't want to do anything malicious, it's the fact that I need my other application to stay in focus while other things run in background, and if the application restarts to bring it back to front. I can see how people could abuse this but I need it for a legit purpose >.< and Simon Wang, it's not. They want to use SetForegroundWindow and then that is for their own app. I want it for a different process. –  Oct 20 '12 at 01:55
  • 1
    I sympathize, Angel, but you don't need to convince us, you need to convince Microsoft. – Michael Petrotta Oct 20 '12 at 02:15

1 Answers1

3

Via the solution by @ReedCopsy here, I suggest to make the selected handle TopMost after you've switched to that window. Using this solution, no new app can become top over the selected window.

Add the following to your code:

 [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;

and change your bringToFront by adding a call to SetWindowPos:

   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);
    }
Community
  • 1
  • 1
Mohsen Afshin
  • 13,273
  • 10
  • 65
  • 90