快捷搜索:

WPF 下无边框窗体改变大小和移动

近来不停在进修 WPF,看着别人做的WPF法度榜样那么漂亮,眼红啊~ 很多漂亮的法度榜样都是无边框的。于是无边框窗口操作便是最紧张的了。无边框窗口的操作不停以来相关的资料就很少。WPF 下的就更少了,有的大年夜多是无边框窗体的移动。在获得群里高人的辅导,再查了一些资料之后,终于把问题办理了。

废话不多说,直接来看看若何实现吧!着实现道理很简单:拦截并处置惩罚 Windows 消息:WM_NCHITTEST。

WPF 处置惩罚 Windows 消息的模式和 WinForm 不一样了。Window 类里没有 WndProc 函数了,想要截取 Windows 消息必须借助 HwndSource 添加 Hook。

借助 HwndSource 注册 WndProc

1protected override void OnSourceInitialized(EventArgs e)

2{

3  base.OnSourceInitialized(e);

4  HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;

5  if (hwndSource != null)

6  {

7    hwndSource.AddHook(new HwndSourceHook(this.WndProc));

8  }

9}

10

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

12{

13  return IntPtr.Zero;

14}

OK,WndProc 注册完成之后就可以经由过程 WndProc 函数完成对Windows消息的处置惩罚了。可以发明,这里的 WndProc 和标准的 Win32 消息轮回很像,只是多了一个 ref bool handled 参数,对付该参数MSDN是这样阐明的:唆使该消息是否已处置惩罚的值。假如该消息已处置惩罚,请将值设置为 true;否则请将其设置为 false。 鄙人面我们将会应用到这个参数数。

经由过程 WndProc 实现无边框窗体改变大年夜小和拖动

1private const int WM_NCHITTEST = 0x0084;

2private readonly int agWidth = 12; //拐角宽度

3private readonly int bThickness = 4; // 边框宽度

4private Point mousePoint = new Point(); //鼠标坐标

5

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

7{

8  switch (msg)

9  {

10    case WM_NCHITTEST:

11    this.mousePoint.X = (lParam.ToInt32() &0xFFFF);

12    this.mousePoint.Y = (lParam.ToInt32() >> 16);

13

14    测试鼠标位置#region 测试鼠标位置

15

16     // 窗口左上角

17     if (this.mousePoint.Y - this.Top

从上面的代码可以看出,事情道理很简单:截取 WM_NCHITTEST 消息,得到鼠标坐标,再在你盼望的地方返回不合的消息以模拟鼠标的状态即可。必要留意的是,返回消息之前必须将handled 设为 true。奉告系统你已经处置惩罚过该消息,不然无效果。

关于 HitTest 是自定义的罗列类,里面包孕了鼠标的各类消息。

HitTest

1public enum HitTest:int

2{

3  HTERROR = -2,

4  HTTRANSPARENT = -1,

5  HTNOWHERE = 0,

6  HTCLIENT = 1,

7  HTCAPTION = 2,

8  HTSYSMENU = 3,

9  HTGROWBOX = 4,

10  HTSIZE = HTGROWBOX,

11  HTMENU = 5,

12  HTHSCROLL = 6,

13  HTVSCROLL = 7,

14  HTMINBUTTON = 8,

15  HTMAXBUTTON = 9,

16  HTLEFT = 10,

17  HTRIGHT = 11,

18  HTTOP = 12,

19  HTTOPLEFT = 13,

20  HTTOPRIGHT = 14,

21  HTBOTTOM = 15,

22  HTBOTTOMLEFT = 16,

23  HTBOTTOMRIGHT = 17,

24  HTBORDER = 18,

25  HTREDUCE = HTMINBUTTON,

26  HTZOOM = HTMAXBUTTON,

27  HTSIZEFIRST = HTLEFT,

28  HTSIZELAST = HTBOTTOMRIGHT,

29  HTOBJECT = 19,

30  HTCLOSE = 20,

31  HTHELP = 21,

32}

在停止之前,先要谢谢一下 WPF SL 技巧超级群(10458228) 和群主 法拉力 还有高手 萧长老 是 法拉力 供给了一个异常好的交流情况,群里的同伙都很热心。

您可能还会对下面的文章感兴趣: