在C#中使用SetWindowPos移动窗口

在C#中使用SetWindowPos移动窗口,c#,windows,interop,C#,Windows,Interop,我的代码如下: 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

我的代码如下:

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);
            }
        }
    }
}
这应该将我桌面上的每个窗口都移动到0,0(x,y)并保持相同的大小。 我的问题是,只有呼叫应用程序(内置C#)被移动

我应该使用Control.FromHandle(IntPtr)以外的其他东西吗?这只会找到dotnet控件吗?如果是,我应该用什么

另外,SetWindowPos中的第二个0只是一个随机的int,我把它放在那里,我不确定int hwninsertafter使用什么


像pidgin这样有多个窗口的进程呢?

只需去掉控件。FromHandle和form==null检查。你应该能够做到:

IntPtr handle = process.MainWindowHandle;
if (handle != IntPtr.Zero)
{
    SetWindowPos(handle, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
}
如果添加SWP_NOSIZE,它不会调整窗口大小,但仍会重新定位窗口


如果要实现每个进程的所有窗口,而不只是主窗口,那么您可能需要考虑使用,而不是迭代进程列表和使用主窗口句柄。

。看看是否有帮助




它正在实现,但是一些窗口(看起来像是有多个窗口的进程)并没有全部移动。顺便说一句,你回答了我这么多的问题,我希望有一天我也能拥有同样多的编程诀窍……马特:我添加了解决方案——直到最后我才看到这样的回答。EnumWindows将遍历所有顶级窗口(不仅仅是MainWindowHandle窗口),这将为您提供所需的内容。
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); 
            }
        }
 }
}