首页 > Windows开发 > 详细

WPF无边框捕获消息改变窗口大小

时间:2018-10-21 13:53:16      阅读:297      评论:0      收藏:0      [点我收藏+]
原文:WPF无边框捕获消息改变窗口大小

文章大部分转载自http://blog.csdn.net/fwj380891124,如有问题,请联系删除


?最近一直在学习 WPF,看着别人做的WPF程序那么漂亮,眼红啊~ 很多漂亮的程序都是无边框的。于是无边框窗口操作就是最重要的了。无边框窗口的操作一直以来相关的资料就很少。WPF 下的就更少了,有的大多是无边框窗体的移动。在得到群里高人的指点,再查了一些资料之后,终于把问题解决了。

? ? ? 废话不多说,直接来看看如何实现吧!其实现原理很简单:拦截并处理 Windows 消息:WM_NCHITTEST。

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

  1. protected?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. ??
  11. protected?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?在下面我们将会使用到这个参数数。
  1. private?const?int?WM_NCHITTEST?=?0x0084;??
  2. private?readonly?int?agWidth?=?12;?//拐角宽度??
  3. private?readonly?int?bThickness?=?4;?//?边框宽度??
  4. private?Point?mousePoint?=?new?Point();?//鼠标坐标??
  5. ???
  6. protected?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?<=?this.agWidth???
  18. ????????????&&?this.mousePoint.X?-?this.Left?<=?this.agWidth)???
  19. ????????{??
  20. ????????????handled?=?true;??
  21. ????????????return?new?IntPtr((int)HitTest.HTTOPLEFT);??
  22. ????????}??
  23. ????????//?窗口左下角??????
  24. ?????????else?if?(this.ActualHeight?+?this.Top?-?this.mousePoint.Y?<=?this.agWidth???
  25. ????????????&&?this.mousePoint.X?-?this.Left?<=?this.agWidth)??
  26. ????????{??
  27. ????????????handled?=?true;??
  28. ????????????return?new?IntPtr((int)HitTest.HTBOTTOMLEFT);??
  29. ????????}??
  30. ????????//?窗口右上角??
  31. ?????????else?if?(this.mousePoint.Y?-?this.Top?<=?this.agWidth???
  32. ????????????&&?this.ActualWidth?+?this.Left?-?this.mousePoint.X?<=?this.agWidth)??
  33. ????????{??
  34. ????????????handled?=?true;??
  35. ????????????return?new?IntPtr((int)HitTest.HTTOPRIGHT);??
  36. ????????}??
  37. ????????//?窗口右下角??
  38. ?????????else?if?(this.ActualWidth?+?this.Left?-?this.mousePoint.X?<=?this.agWidth???
  39. ????????????&&?this.ActualHeight?+?this.Top?-?this.mousePoint.Y?<=?this.agWidth)??
  40. ????????{??
  41. ????????????handled?=?true;??
  42. ????????????return?new?IntPtr((int)HitTest.HTBOTTOMRIGHT);??
  43. ????????}??
  44. ????????//?窗口左侧??
  45. ?????????else?if?(this.mousePoint.X?-?this.Left?<=?this.bThickness)??
  46. ????????{??
  47. ????????????handled?=?true;??
  48. ????????????return?new?IntPtr((int)HitTest.HTLEFT);??
  49. ????????}??
  50. ????????//?窗口右侧??
  51. ?????????else?if?(this.ActualWidth?+?this.Left?-?this.mousePoint.X?<=?this.bThickness)??
  52. ????????{??
  53. ????????????handled?=?true;??
  54. ????????????return?new?IntPtr((int)HitTest.HTRIGHT);??
  55. ????????}??
  56. ????????//?窗口上方??
  57. ?????????else?if?(this.mousePoint.Y?-?this.Top?<=?this.bThickness)??
  58. ????????{??
  59. ????????????handled?=?true;??
  60. ????????????return?new?IntPtr((int)HitTest.HTTOP);??
  61. ????????}??
  62. ????????//?窗口下方??
  63. ?????????else?if?(this.ActualHeight?+?this.Top?-?this.mousePoint.Y?<=?this.bThickness)??
  64. ????????{??
  65. ????????????handled?=?true;??
  66. ????????????return?new?IntPtr((int)HitTest.HTBOTTOM);??
  67. ????????}??
  68. ????????else?//?窗口移动??
  69. ????????{??
  70. ????????????handled?=?true;??
  71. ????????????return?new?IntPtr((int)HitTest.HTCAPTION);??
  72. ????????}??
  73. ????????#endregion??
  74. ????}??
  75. ????return?IntPtr.Zero;??
  76. }??

? ? ?从上面的代码可以看出,工作原理很简单:截取 WM_NCHITTEST 消息,获得鼠标坐标,再在你希望的地方返回不同的消息以模拟鼠标的状态即可。需要注意的是,返回消息之前必须将handled 设为 true。告诉系统你已经处理过该消息,不然无效果。

??? 关于 HitTest 是自定义的枚举类,里面包含了鼠标的各种消息。

  1. 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. } ?
  33. ?HTBORDER 在不具有可变大小边框的窗口的边框上。 
    · HTBOTTOM 在窗口的水平边框的底部。 
    · HTBOTTOMLEFT 在窗口边框的左下角。  
    · HTBOTTOMRIGHT 在窗口边框的右下角。  
    · HTCAPTION 在标题条中。  
    · HTCLIENT 在客户区中。  
    · HTERROR 在屏幕背景或窗口之间的分隔线上(与HTNOWHERE相同,除了Windows的DefWndProc函数产生一个系统响声以指明错误)。  
    · HTGROWBOX 在尺寸框中。  
    · HTHSCROLL 在水平滚动条上。  
    · HTLEFT 在窗口的左边框上。  
    · HTMAXBUTTON 在最大化按钮上。  
    · HTMENU 在菜单区域。  
    · HTMINBUTTON 在最小化按钮上。  
    · HTNOWHERE 在屏幕背景或窗口之间的分隔线上。  
    · HTREDUCE 在最小化按钮上。  
    · HTRIGHT 在窗口的右边框上。  
    · HTSIZE 在尺寸框中。(与HTGROWBOX相同)  
    · HTSYSMENU 在控制菜单或子窗口的关闭按钮上。  
    · HTTOP 在窗口水平边框的上方。  
    · HTTOPLEFT 在窗口边框的左上角。  
    · HTTOPRIGHT 在窗口边框的右上角。  
    · HTTRANSPARENT 在一个被其它窗口覆盖的窗口中。  
    · HTVSCROLL 在垂直滚动条中。  
    · HTZOOM 在最大化按钮上。

WPF无边框捕获消息改变窗口大小

原文:https://www.cnblogs.com/lonelyxmas/p/9824781.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!