等倍でウィンドウサイズを変更するように強制する。

ウィンドウの端っこピーって引っ張ってウィンドウサイズを変更する時に４：３を維持させたいみたいな事ってありますよね。
きっとありますよね。私だけじゃないはず・・・・きっと・・・
ほらViewBoxとか使ってるときとかね。

そんな時にこのロジックを使います。

```csharp

    public partial class WindowEx : Window
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        }

        //using System.Runtime.InteropServices;
        const double fixedRate = (double)1024 / 737;
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            IntPtr handle = (new WindowInteropHelper(this)).Handle;
            HwndSource hwndSource =
                            (HwndSource)HwndSource.FromVisual(this);
            hwndSource.AddHook(WndHookProc);
        }

        const int WM_SIZING = 0x214;
        const int WMSZ_LEFT = 1;
        const int WMSZ_RIGHT = 2;
        const int WMSZ_TOP = 3;
        const int WMSZ_TOPLEFT = 4;
        const int WMSZ_TOPRIGHT = 5;
        const int WMSZ_BOTTOM = 6;
        const int WMSZ_BOTTOMLEFT = 7;
        const int WMSZ_BOTTOMRIGHT = 8;


        private IntPtr WndHookProc(
            IntPtr hwnd, int msg, IntPtr wParam,
            IntPtr lParam, ref bool handled)
        {
            if (msg == WM_SIZING)
            {
                RECT r = (RECT)Marshal.PtrToStructure(
                                          lParam, typeof(RECT));
                RECT recCopy = r;
                int w = r.right - r.left;
                int h = r.bottom - r.top;
                int dw;
                int dh;
                dw = (int)(h * fixedRate + 0.5) - w;
                dh = (int)(w / fixedRate + 0.5) - h;

                switch (wParam.ToInt32())
                {
                    case WMSZ_TOP:
                    case WMSZ_BOTTOM:
                        r.right += dw;
                        break;
                    case WMSZ_LEFT:
                    case WMSZ_RIGHT:
                        r.bottom += dh;
                        break;
                    case WMSZ_TOPLEFT:
                        if (dw > 0) r.left -= dw;
                        else r.top -= dh;
                        break;
                    case WMSZ_TOPRIGHT:
                        if (dw > 0) r.right += dw;
                        else r.top -= dh;
                        break;
                    case WMSZ_BOTTOMLEFT:
                        if (dw > 0) r.left -= dw;
                        else r.bottom += dh;
                        break;
                    case WMSZ_BOTTOMRIGHT:
                        if (dw > 0) r.right += dw;
                        else r.bottom += dh;
                        break;
                }
                Marshal.StructureToPtr(r, lParam, false);
            }           
            return IntPtr.Zero;
        }
```

RECTというStructはPtrToStructで使うのでシーケンシャルを指定します。
でfixedRateの値に従って画面サイズの変更が行われたときに画面サイズの値に介入します。
単純に変更時にサイズを変更するだけだと操作性に違和感が出ますので
どこを引っ張ってサイズを変更しているかによって介入するサイズ部分を変えてます。
上と下を引っ張った場合は右側に
左と右を引っ張った場合は下側に
コーナーを引っ張った場合は縦横比に応じて
上下のダブルクリックには対応してませんが、同じような感覚でロジックを追加すればよいかと思います。

おしまい|дﾟ)