1

It's working with other handles windows.

Process[] processes = Process.GetProcessesByName(processName);
SetProcessWindow.BringToFront(processes[0].Id);
SetProcessWindow.CenterProcessWindow(processes[0].Id);

If the processName for example is Taskmgr it will bring to the front of the screen and will center it the Task Manager.

But if for example the processName is explorer (not internet explorer but explorer that in this case is a directory on the hard disk) it won't bring it to the front it will not do anything.

This is the SetProcessWindow class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing;

namespace Automation
{
    class SetProcessWindow
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        private static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId);

        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("User32.dll")]
        private static extern bool ShowWindow(IntPtr handle, int nCmdShow);

        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_SHOWNORMAL = 1;

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left;        // x position of upper-left corner
            public int Top;         // y position of upper-left corner
            public int Right;       // x position of lower-right corner
            public int Bottom;      // y position of lower-right corner
        }

        private const int SWP_NOSIZE = 0x0001;
        private const int SWP_NOZORDER = 0x0004;
        private const int SWP_SHOWWINDOW = 0x0040;

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

        public static void BringToFront(int processId)
        {
            Process process = Process.GetProcessById(processId);
            IntPtr handle = process.MainWindowHandle;

            if (handle == IntPtr.Zero)
                return;

            ShowWindow(handle, SW_SHOWNORMAL);
            SetForegroundWindow(handle);
        }

        public static void CenterProcessWindow(int processId)
        {
            Process process = Process.GetProcessById(processId);

            while (process.MainWindowHandle == IntPtr.Zero)
            {
                process.Refresh();
                break;
            }

            IntPtr handle = process.MainWindowHandle;

            RECT rct;
            GetWindowRect(handle, out rct);
            Rectangle screen = Screen.FromHandle(handle).Bounds;
            Point pt = new Point(screen.Left + screen.Width / 2 - (rct.Right - rct.Left) / 2, screen.Top + screen.Height / 2 - (rct.Bottom - rct.Top) / 2);
            SetWindowPos(handle, IntPtr.Zero, pt.X, pt.Y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
        }
    }
}

Not sure maybe it doesn't bring some windows to the front since I changed in the project properties unchecked prefer 32-bit ?

Anyway some windows it bring to the front and some not.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Manuel Spechia
  • 389
  • 1
  • 3
  • 16
  • http://stackoverflow.com/questions/20224673/focus-windows-explorer-from-c-sharp-app-in-task-bar http://stackoverflow.com/questions/1132422/open-a-folder-using-process-start – Orel Eraki Jul 11 '15 at 07:29
  • 1
    Explorer creates *many* windows. When you use MainWindowHandle then you usually get the taskbar. Bringing it into the foreground could be useful, not very likely that's what you actually want. Always use the Spy++ utility to get insight. The ShellWindows COM object allows iterating the kind of window you are looking for. – Hans Passant Jul 11 '15 at 10:41
  • My idea is realy to allow the user to bring to the front only applications. Like Skype like taskbar and this are working. The rest I will work on it later. I think what I wanted in general is working. The main idea was to do it with Elgato hd game capture software and it's working. – Manuel Spechia Jul 11 '15 at 12:20

1 Answers1

0

Maybe you have the same problem with handle creation you had inside your CenterProcessWindow method. Try adding this piece of code to your BringToFront method aswell.

while (process.MainWindowHandle == IntPtr.Zero)
    process.Refresh();

before this line : IntPtr handle = process.MainWindowHandle;. Also, you don't need break; inside that while loop. If you place break there it will go out of your while loop even if MainWindoWHandle is still IntPtr.Zero. The way you wrote it is the same as this:

if (process.MainWindowHandle == IntPtr.Zero)
    process.Refresh();

If it's IntPtr.Zero, refresh and continue, you're willing to wait for it to get some value, therefore while loop.

msmolcic
  • 6,407
  • 8
  • 32
  • 56