首页 文章

在C#中使用SetWindowPos来移动窗口

提问于
浏览
21

我有以下代码:

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 hWndInsertAfter

那些像pidgin这样的多个窗口的流程怎么样?

2 回答

  • 2

    只需取出你的Control.FromHandle和form == null check . 你应该能够做到:

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

    如果添加SWP_NOSIZE,它将不会调整窗口大小,但仍会重新定位它 .

    如果要影响每个进程的所有窗口,而不仅仅是主窗口,您可能需要考虑使用P/Invoke with EnumWindows而不是迭代进程列表并使用MainWindowHandle .

  • 25

    玩过这个 . 看看它是否有帮助 .


    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); 
                }
            }
     }
    }
    

相关问题