views:

3245

answers:

2

I have the code below:

namespace WindowMover
{
    using System.Windows.Forms;

    static class Logic
    {
        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

        public static void Move()
        {
            const short SWP_NOMOVE = 0X2;
            const short SWP_NOSIZE = 1;
            const short SWP_NOZORDER = 0X4;
            const int SWP_SHOWWINDOW = 0x0040;

            Process[] processes = Process.GetProcesses(".");
            foreach (var process in processes)
            {
                var handle = process.MainWindowHandle;
                var form = Control.FromHandle(handle);

                if (form == null) continue;

                SetWindowPos(handle, 0, 0, 0, form.Bounds.Width, form.Bounds.Height, SWP_NOZORDER | SWP_SHOWWINDOW);
            }
        }
    }
}

This is supposed to move every window on my desktop to 0,0 (x,y) and keep the same sizes. My problem is that only the calling app (built in C#) is getting moved.

Should I be using something else other than Control.FromHandle(IntPtr)? Will this only find dotnet controls? If so what should I use?

Also, the second 0 in SetWindowPos was just a random int I stick in there, I'm not sure what to use for int hWndInsertAfter

What about processes with multiple windows like pidgin?

+2  A: 

Just take out your Control.FromHandle and the form == null check. You should be able to just do:

IntPtr handle = process.MainWindowHandle;
if (handle != IntPtr.Zero)
{
    SetWindowPos(handle, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
}

If you add SWP_NOSIZE, it will not resize the window, but will still reposition it.

If you want to effect all windows, not just the main window, of each process, you might want to consider using P/Invoke with EnumWindows instead of iterating through the Process list and using MainWindowHandle.

Reed Copsey
It's getting there, but some windows (seems like those processes that have multiple windows) are not all moving.BTW, you answer so many of my questions, I hope I someday have as much programming know-how....
Matt
Matt: I added the solution for that - I didn't see that response until just the end. EnumWindows will iterate through all of the Top-level windows (not just MainWindowHandle windows), which should give you what you want.
Reed Copsey
A: 

Played with this. See if it helps.

using System.Windows.Forms;

using System.Runtime.InteropServices; using System.Diagnostics;

namespace ConsoleTestApp { class Program { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool SetForegroundWindow(IntPtr hWnd);

    static void Main(string[] args)
    {

        Process[] processes = Process.GetProcesses();

        foreach (var process in processes)
        {
            Console.WriteLine("Process Name: {0} ", process.ProcessName); 

            if (process.ProcessName == "WINWORD")
            {
                IntPtr handle = process.MainWindowHandle;

                bool topMost =  SetForegroundWindow(handle); 
            }
        }
}

}

Dagne