wpf自定义窗体resize

捕获一般事件实现,很容易出BUG,捕获window消息比较安全。方法如下:

一、消息枚举

public enum HitTest : int
{
HTERROR = -2,
HTTRANSPARENT = -1,
HTNOWHERE = 0,
HTCLIENT = 1,
HTCAPTION = 2,
HTSYSMENU = 3,
HTGROWBOX = 4,
HTSIZE = HTGROWBOX,
HTMENU = 5,
HTHSCROLL = 6,
HTVSCROLL = 7,
HTMINBUTTON = 8,
HTMAXBUTTON = 9,
HTLEFT = 10,
HTRIGHT = 11,
HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTBOTTOM = 15,
HTBOTTOMLEFT = 16,
HTBOTTOMRIGHT = 17,
HTBORDER = 18,
HTREDUCE = HTMINBUTTON,
HTZOOM = HTMAXBUTTON,
HTSIZEFIRST = HTLEFT,
HTSIZELAST = HTBOTTOMRIGHT,
HTOBJECT = 19,
HTCLOSE = 20,
HTHELP = 21,
}

 

二、注册消息处理函数WndProc

protected override void OnSourceInitialized(EventArgs e)
{
  base.OnSourceInitialized(e);
  HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
  if (hwndSource != null)
  {
    hwndSource.AddHook(new HwndSourceHook(this.WndProc));
  }
}

 

三、消息处理函数WndProc定义

private const int WM_NCHITTEST = 0x0084;
private Point mousePoint = new Point(); //鼠标坐标

private const int ResizeBorderAGWidth=12;//转角宽度 

private const int ResizeBorderThickness=4;//边框宽度

protected virtual IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{

  switch (msg)
  {
    case WM_NCHITTEST:
      this.mousePoint.X = (lParam.ToInt32() & 0xFFFF);
      this.mousePoint.Y = (lParam.ToInt32() >> 16);

      // 窗口左上角
      if (this.mousePoint.Y - this.Top <= this.ResizeBorderAGWidth
      && this.mousePoint.X - this.Left <= this.ResizeBorderAGWidth)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTTOPLEFT);
      }
      // 窗口左下角  
      else if (this.ActualHeight + this.Top - this.mousePoint.Y <= this.ResizeBorderAGWidth
      && this.mousePoint.X - this.Left <= this.ResizeBorderAGWidth)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTBOTTOMLEFT);
      }
      // 窗口右上角
      else if (this.mousePoint.Y - this.Top <= this.ResizeBorderAGWidth
      && this.ActualWidth + this.Left - this.mousePoint.X <= this.ResizeBorderAGWidth)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTTOPRIGHT);
      }
      // 窗口右下角
      else if (this.ActualWidth + this.Left - this.mousePoint.X <= this.ResizeBorderAGWidth
      && this.ActualHeight + this.Top - this.mousePoint.Y <= this.ResizeBorderAGWidth)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTBOTTOMRIGHT);
      }
      // 窗口左侧
      else if (this.mousePoint.X - this.Left <= this.ResizeBorderThickness)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTLEFT);
      }
      // 窗口右侧
      else if (this.ActualWidth + this.Left - this.mousePoint.X <= this.ResizeBorderThickness)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTRIGHT);
      }
      // 窗口上方
      else if (this.mousePoint.Y - this.Top <= this.ResizeBorderThickness)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTTOP);
      }
      // 窗口下方
      else if (this.ActualHeight + this.Top - this.mousePoint.Y <= this.ResizeBorderThickness)
      {
        handled = true;
        return new IntPtr((int)HitTest.HTBOTTOM);
      }
      else // 窗口移动
      {
        //handled = true;
        //return new IntPtr((int)HitTest.HTCAPTION);
        return IntPtr.Zero;
      }
  }

  return IntPtr.Zero;
}

posted @ 2011-12-20 17:49  罗虎  阅读(1864)  评论(1编辑  收藏  举报