开发者

WPF : Move and resize window at once time

In Win32 API, function SetWindowPos provided an easy way to move and resize window at once.

However, in WPF class Window doesn't have a method like SetWindowPos. So I must code like the following:

        this.Left += e.HorizontalChange;
        this.Top += e.VerticalChange;
        this.Width = newWidth;
        this.Height = newHeight;

Of course, it 开发者_开发知识库works well, but it's not simple. And it looks dirty.

How can i move a window and resize at once?

Is there an API?


I know you've already solved your problem, but I'll post a solution that I found in case it helps others.

Basically, You must declare that SetWindowsPos as an imported function from Win32 this is the signature

[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

The function needs the hWnd of your window, in order to get it you can add an handler on the initialization of your windows (for example you could listen for the "SourceInitialized" event) and store that value in a private member of the class:

hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;

WPF manages device independent pixels, so you needs even a converter from dip to real pixel for your screen. This is done with these lines:

var source = PresentationSource.FromVisual(this);
Matrix transformToDevice = source.CompositionTarget.TransformToDevice;
Point[] p = new Point[] { new Point(this.Left + e.HorizontalChange, this.Top), new Point(this.Width - e.HorizontalChange, this.Height) };
transformToDevice.Transform(p);

Finally you can call SetWindowsPos:

SetWindowPos(this.hwndSource.Handle, IntPtr.Zero, Convert.ToInt32(p[0].X), Convert.ToInt32(p[0].Y), Convert.ToInt32(p[1].X), Convert.ToInt32(p[1].Y), SetWindowPosFlags.SWP_SHOWWINDOW);

Sources:

  • Win32 SetWindowPos
  • WPF Graphics Rendering


You could wrap your code in a helper method. Just like this:

public static class WindowExtensions {
    public static void MoveAndResize( this Window value, double horizontalChange, double verticalChange, double width, double height ) {
        value.Left += horizontalChange;
        value.Top += verticalChange;
        value.Width = width;
        value.Height = height;
    }
}

So your calling code looks like this:

this.MoveAndResize( 10, 10, 1024, 768 );

I've left off namespace and using declaration, keep that in mind when copying.

Edit:

You could also use the API. Personally I stick with the managed code unless I really need to use the API. But that is up to you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜