2017-05-02 3 views
0

現在、サイズ変更可能なパネルをC#winformsプロジェクトに追加しようとしています。サイズ変更可能なパネルを制限する(比率と最小/最大サイズ)

現在、私が欲しいものを得るために、このコードを使用しています:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

class ResizablePanel : Panel 
{ 
    private const int grab = 16; 

    public ResizablePanel() 
    { 
     this.ResizeRedraw = true; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     var rc = new Rectangle(this.ClientSize.Width - grab, this.ClientSize.Height - grab, grab, grab); 
     ControlPaint.DrawSizeGrip(e.Graphics, this.BackColor, rc); 
    } 

    protected override void WndProc(ref Message m) 
    { 
     base.WndProc(ref m); 

     if (m.Msg == 0x84) 
     { 
      var pos = this.PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16)); 

      if (pos.X >= this.ClientSize.Width - grab && pos.Y >= this.ClientSize.Height - grab) 
       m.Result = new IntPtr(17); 
     } 
    } 
} 

その細かい作業が、今、私はいくつかのことを制限したいと思います。

  1. 私はパネルを420x236より小さくしたくありません。 私はMinimumSizeを設定しようとしましたが、サイズを変更しようとすると無視しました。

  2. 16:9の縦横比を維持したいと考えています。

どのように私は上記のコードを取得できますか?それを行う方法はありますか?

+0

SetBoundsCore()を試しましたか?それは仮想的な方法であり、あなたのような状況で使用することができます。 – Bahrom

答えて

1

this answerから採用されたWM_SIZINGメッセージを処理します。

if (m.Msg == 0x84) 
{ 
    var pos = this.PointToClient(new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16)); 

    if (pos.X >= this.ClientSize.Width - grab && pos.Y >= this.ClientSize.Height - grab) 
    m.Result = new IntPtr(17); 
} 
else if (m.Msg == 0x216 || m.Msg == 0x214) 
{ 
    // WM_MOVING || WM_SIZING 
    // Keep the aspect and minimum size 
    RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT)); 
    int w = rc.Right - rc.Left; 
    int h = rc.Bottom - rc.Top; 
    w = w > 420 ? w : 420; 
    rc.Bottom = rc.Top + (int)(w * 9.0/16); 
    rc.Right = rc.Left + w; 
    Marshal.StructureToPtr(rc, m.LParam, false); 
    m.Result = (IntPtr)1; 
    return; 
} 

RECT構造体はIもはるかに簡単であるOnResizeイベントをオーバーライドする試み

[StructLayout(LayoutKind.Sequential)] 
public struct RECT { 
    public int Left; 
    public int Top; 
    public int Right; 
    public int Bottom; 
} 

として定義され、ただし、パネルのサイズが変更されたときに点滅しています。

protected override void OnResize(EventArgs eventargs) 
{ 
    base.OnResize(eventargs); 
    if (this.Width < 420) 
     this.Size = new Size(420, 236); 
    else 
     this.Size = new Size(this.Width, (int)(this.Width * 9.0/16)); 
} 

両方のアプローチは、メッセージキューを処理することは、より低レベルの「Win32の様」とオーバーライドさらにonResizeは、「Windowsフォーム道」であり、実際には同じものです。

+0

だから、私はOnResizeバージョンとそのうまく動作しようとしました。 DoubleBufferedを使用してCreateParamsをオーバーライドして、ちらつきを修正しました。 OnResizeが動作していても、私はあなたのアイデアの最初のバージョンをテストしたいと思いますが、それをどのように/どこで使用するのか分かりません。私はそのすべてのものに新しい、まだ学んでいる、あなたは多分それをどこでどのように使用するための小さな "チュートリアル"を与えることができますか? – Backslash

+0

ああ、私はまた、フォームのサイズに基づいて最大の高さ/幅に制限を含める必要があることを見た。なぜなら、あなたがそれを伸ばしすぎると、小さなアギンになるためにコーナーをつかむことができないからです。 :D – Backslash

+0

ちょうどあなたのWndProcメソッドにコードをコピーして、私はあなたの後にelseを追加します。 – kennyzx

関連する問題