2017-05-02 4 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를 무시하려고했지만 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 구조체가 나는 또한 크기를 조절할 때, 패널이 점멸, 훨씬 간단 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 Forms의 '방법'이다, 실제로 같은 일이다.

+0

그래서 나는 OnResize 버전과 그 잘 작동 해 보았습니다. DoubleBuffered를 사용하고 CreateParams를 재정 의하여 깜박임을 수정했습니다. OnResize가 작동하는 경우에도 여전히 아이디어의 첫 번째 버전을 테스트하고 싶지만 어떻게 사용하는지 이해하지는 못합니다. 나는 그 모든 것을 처음 사용하고 여전히 배우고 있습니다. 어쩌면 저의 사용법에 관한 작은 "튜토리얼"을 줄 수 있습니까? – Backslash

+0

오, 나는 또한 폼의 크기를 기준으로 최대 높이/너비에 대한 제한을 포함해야한다는 것을 알았습니다. 너무 크게 늘리면 구석을 잡아 작은 크기로 만들 수 있기 때문입니다. : D – Backslash

+0

코드를 WndProc 메소드에 복사하십시오. if 뒤에 if를 추가하면됩니다. – kennyzx

관련 문제