如何使用C#设置窗口的高度?

12

如何使用窗口句柄或进程句柄设置窗口的高度?

我已经有了以下代码,假设目标应用程序为记事本:

Process[] processes = Process.GetProcessesByName("notepad");

foreach (Process p in processes)
{

    if (p.MainWindowTitle == title)
    {

        handle = p.MainWindowHandle;

        while ((handle = p.MainWindowHandle) == IntPtr.Zero)
        {
            Thread.Sleep(1000);
            p.Refresh();
        }

        break;
    }

}

我能否利用handlep来设置窗口的高度?


2
使用窗口句柄,调用GetWindowRect函数获取矩形区域,修改高度后再调用MoveWindow函数。 - David Heffernan
2个回答

14

这是我会做的方法:

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

namespace ConsoleApplication1
{
    class Program
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT Rect);

        [DllImport("user32.dll", SetLastError = true)]
        static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int Width, int Height, bool Repaint);

        static void Main(string[] args)
        {
            Process[] processes = Process.GetProcessesByName("notepad");
            foreach (Process p in processes)
            {
                IntPtr handle = p.MainWindowHandle;
                RECT Rect = new RECT();
                if (GetWindowRect(handle, ref Rect))
                    MoveWindow(handle, Rect.left, Rect.right, Rect.right-Rect.left, Rect.bottom-Rect.top + 50, true);
            }
        }
    }
}

虽然您可以使用SetWindowPos来实现,而SetWindowPos是更新而且更能胜任的API,但MoveWindow只需要更容易的调用即可。


太好了!在Silverlight OOB中运行良好(可能在浏览器中也需要提升权限)。当然,它需要使用FindWindow来获取句柄。 - Konstantin Salavatov
我认为Rect结构体是错误的。它应该是Left、Top、Right、Bottom。 - atomaras

7
你应该能够使用Win32的SetWindowPos函数(用于位置和大小)。这里有一个链接,介绍如何在C#中使用它。
以下是快速示例。这将把记事本移动到屏幕上的(10,10)位置,并将其调整为(450,450)的大小:
class Program
{
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

    static void Main(string[] args)
    {
        Console.WriteLine("Start notepad and hit any key...");
        Console.ReadKey(true);
        Process[] processes = Process.GetProcessesByName("notepad");

        foreach (Process p in processes)
        {
            var handle = p.MainWindowHandle;

            SetWindowPos(handle, new IntPtr(SpecialWindowHandles.HWND_TOP), 10,10,450,450,SetWindowPosFlags.SWP_SHOWWINDOW);

            break;

        }

    }
}

public enum SpecialWindowHandles
{
    HWND_TOP = 0,
    HWND_BOTTOM = 1,
    HWND_TOPMOST = -1,
    HWND_NOTOPMOST = -2
}

[Flags]
public enum SetWindowPosFlags : uint
{
    SWP_ASYNCWINDOWPOS = 0x4000,

    SWP_DEFERERASE = 0x2000,

    SWP_DRAWFRAME = 0x0020,

    SWP_FRAMECHANGED = 0x0020,

    SWP_HIDEWINDOW = 0x0080,

    SWP_NOACTIVATE = 0x0010,

    SWP_NOCOPYBITS = 0x0100,

    SWP_NOMOVE = 0x0002,

    SWP_NOOWNERZORDER = 0x0200,

    SWP_NOREDRAW = 0x0008,

    SWP_NOREPOSITION = 0x0200,

    SWP_NOSENDCHANGING = 0x0400,

    SWP_NOSIZE = 0x0001,

    SWP_NOZORDER = 0x0004,

    SWP_SHOWWINDOW = 0x0040,
}

太棒了!我想保留窗口的原始宽度,我该怎么做? - Abs
1
调用 GetWindowRect。MoveWindow 比 SetWindowPos 更易于使用。 - David Heffernan
@David - 我不熟悉那个,也许你可以添加一个例子? - Abs
1
@Abs:像David建议的那样使用GetWindowRect函数来获取大小,并从中使用宽度。请参见此处:http://www.pinvoke.net/default.aspx/user32/getwindowrect.html - BFree
1
你忘记了将 explicit SpecialWindowHandles 转换为 int。 - Orhan Cinar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接