FrmAnchor.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // ***********************************************************************
  2. // Assembly : HZH_Controls
  3. // Created : 08-08-2019
  4. //
  5. // ***********************************************************************
  6. // <copyright file="FrmAnchor.cs">
  7. // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
  8. // </copyright>
  9. //
  10. // Blog: https://www.cnblogs.com/bfyx
  11. // GitHub:https://github.com/kwwwvagaa/NetWinformControl
  12. // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
  13. //
  14. // If you use this code, please keep this note.
  15. // ***********************************************************************
  16. using System;
  17. using System.Collections.Generic;
  18. using System.ComponentModel;
  19. using System.Data;
  20. using System.Drawing;
  21. using System.Linq;
  22. using System.Text;
  23. using System.Windows.Forms;
  24. namespace HZH_Controls.Forms
  25. {
  26. /// <summary>
  27. /// 功能描述:停靠窗体
  28. /// 作  者:HZH
  29. /// 创建日期:2019-02-27 11:49:03
  30. /// 任务编号:POS
  31. /// </summary>
  32. /// <seealso cref="System.Windows.Forms.Form" />
  33. /// <seealso cref="System.Windows.Forms.IMessageFilter" />
  34. public partial class FrmAnchor : Form, IMessageFilter
  35. {
  36. /// <summary>
  37. /// The m parent control
  38. /// </summary>
  39. Control m_parentControl = null;
  40. /// <summary>
  41. /// The BLN down
  42. /// </summary>
  43. private bool blnDown = true;
  44. /// <summary>
  45. /// The m size
  46. /// </summary>
  47. Size m_size;
  48. /// <summary>
  49. /// The m deviation
  50. /// </summary>
  51. Point? m_deviation;
  52. /// <summary>
  53. /// The m is not focus
  54. /// </summary>
  55. bool m_isNotFocus = true;
  56. #region 构造函数
  57. /// <summary>
  58. /// 功能描述:构造函数
  59. /// 作  者:HZH
  60. /// 创建日期:2019-02-27 11:49:08
  61. /// 任务编号:POS
  62. /// </summary>
  63. /// <param name="parentControl">父控件</param>
  64. /// <param name="childControl">子控件</param>
  65. /// <param name="deviation">偏移</param>
  66. /// <param name="isNotFocus">是否无焦点窗体</param>
  67. public FrmAnchor(Control parentControl, Control childControl, Point? deviation = null,bool isNotFocus=true)
  68. {
  69. m_isNotFocus = isNotFocus;
  70. m_parentControl = parentControl;
  71. InitializeComponent();
  72. this.Size = childControl.Size;
  73. this.HandleCreated += FrmDownBoard_HandleCreated;
  74. this.HandleDestroyed += FrmDownBoard_HandleDestroyed;
  75. this.Controls.Add(childControl);
  76. childControl.Dock = DockStyle.Fill;
  77. m_size = childControl.Size;
  78. m_deviation = deviation;
  79. if (parentControl.FindForm() != null)
  80. {
  81. Form frmP = parentControl.FindForm();
  82. if (!frmP.IsDisposed)
  83. {
  84. frmP.LocationChanged += frmP_LocationChanged;
  85. }
  86. }
  87. parentControl.LocationChanged += frmP_LocationChanged;
  88. }
  89. /// <summary>
  90. /// Initializes a new instance of the <see cref="FrmAnchor" /> class.
  91. /// </summary>
  92. /// <param name="parentControl">The parent control.</param>
  93. /// <param name="size">The size.</param>
  94. /// <param name="deviation">The deviation.</param>
  95. /// <param name="isNotFocus">if set to <c>true</c> [is not focus].</param>
  96. public FrmAnchor(Control parentControl, Size size, Point? deviation = null, bool isNotFocus = true)
  97. {
  98. m_isNotFocus = isNotFocus;
  99. m_parentControl = parentControl;
  100. InitializeComponent();
  101. this.Size = size;
  102. this.HandleCreated += FrmDownBoard_HandleCreated;
  103. this.HandleDestroyed += FrmDownBoard_HandleDestroyed;
  104. m_size = size;
  105. m_deviation = deviation;
  106. }
  107. /// <summary>
  108. /// Handles the LocationChanged event of the frmP control.
  109. /// </summary>
  110. /// <param name="sender">The source of the event.</param>
  111. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  112. void frmP_LocationChanged(object sender, EventArgs e)
  113. {
  114. this.Hide();
  115. }
  116. #endregion
  117. /// <summary>
  118. /// Handles the HandleDestroyed event of the FrmDownBoard control.
  119. /// </summary>
  120. /// <param name="sender">The source of the event.</param>
  121. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  122. private void FrmDownBoard_HandleDestroyed(object sender, EventArgs e)
  123. {
  124. Application.RemoveMessageFilter(this);
  125. }
  126. /// <summary>
  127. /// Handles the HandleCreated event of the FrmDownBoard control.
  128. /// </summary>
  129. /// <param name="sender">The source of the event.</param>
  130. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  131. private void FrmDownBoard_HandleCreated(object sender, EventArgs e)
  132. {
  133. Application.AddMessageFilter(this);
  134. }
  135. #region 无焦点窗体
  136. /// <summary>
  137. /// Sets the active window.
  138. /// </summary>
  139. /// <param name="handle">The handle.</param>
  140. /// <returns>IntPtr.</returns>
  141. [System.Runtime.InteropServices.DllImport("user32.dll")]
  142. private extern static IntPtr SetActiveWindow(IntPtr handle);
  143. /// <summary>
  144. /// The wm activate
  145. /// </summary>
  146. private const int WM_ACTIVATE = 0x006;
  147. /// <summary>
  148. /// The wm activateapp
  149. /// </summary>
  150. private const int WM_ACTIVATEAPP = 0x01C;
  151. /// <summary>
  152. /// The wm ncactivate
  153. /// </summary>
  154. private const int WM_NCACTIVATE = 0x086;
  155. /// <summary>
  156. /// The wa inactive
  157. /// </summary>
  158. private const int WA_INACTIVE = 0;
  159. /// <summary>
  160. /// The wm mouseactivate
  161. /// </summary>
  162. private const int WM_MOUSEACTIVATE = 0x21;
  163. /// <summary>
  164. /// The ma noactivate
  165. /// </summary>
  166. private const int MA_NOACTIVATE = 3;
  167. /// <summary>
  168. /// WNDs the proc.
  169. /// </summary>
  170. /// <param name="m">要处理的 Windows <see cref="T:System.Windows.Forms.Message" />。</param>
  171. protected override void WndProc(ref Message m)
  172. {
  173. if (m_isNotFocus)
  174. {
  175. if (m.Msg == WM_MOUSEACTIVATE)
  176. {
  177. m.Result = new IntPtr(MA_NOACTIVATE);
  178. return;
  179. }
  180. else if (m.Msg == WM_NCACTIVATE)
  181. {
  182. if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
  183. {
  184. if (m.LParam != IntPtr.Zero)
  185. {
  186. SetActiveWindow(m.LParam);
  187. }
  188. else
  189. {
  190. SetActiveWindow(IntPtr.Zero);
  191. }
  192. }
  193. }
  194. }
  195. base.WndProc(ref m);
  196. }
  197. #endregion
  198. /// <summary>
  199. /// 在调度消息之前将其筛选出来。
  200. /// </summary>
  201. /// <param name="m">要调度的消息。无法修改此消息。</param>
  202. /// <returns>如果筛选消息并禁止消息被调度,则为 true;如果允许消息继续到达下一个筛选器或控件,则为 false。</returns>
  203. public bool PreFilterMessage(ref Message m)
  204. {
  205. if (m.Msg != 0x0201 || this.Visible == false)
  206. return false;
  207. var pt = this.PointToClient(MousePosition);
  208. this.Visible = this.ClientRectangle.Contains(pt);
  209. return false;
  210. }
  211. /// <summary>
  212. /// Handles the Load event of the FrmAnchor control.
  213. /// </summary>
  214. /// <param name="sender">The source of the event.</param>
  215. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  216. private void FrmAnchor_Load(object sender, EventArgs e)
  217. {
  218. }
  219. /// <summary>
  220. /// Handles the VisibleChanged event of the FrmAnchor control.
  221. /// </summary>
  222. /// <param name="sender">The source of the event.</param>
  223. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  224. private void FrmAnchor_VisibleChanged(object sender, EventArgs e)
  225. {
  226. timer1.Enabled = this.Visible;
  227. if (this.Visible)
  228. {
  229. Point p = m_parentControl.Parent.PointToScreen(m_parentControl.Location);
  230. int intX = 0;
  231. int intY = 0;
  232. if (p.Y + m_parentControl.Height + m_size.Height > Screen.PrimaryScreen.Bounds.Height)
  233. {
  234. intY = p.Y - m_size.Height - 1;
  235. blnDown = false;
  236. }
  237. else
  238. {
  239. intY = p.Y + m_parentControl.Height + 1;
  240. blnDown = true;
  241. }
  242. if (p.X + m_size.Width > Screen.PrimaryScreen.Bounds.Width)
  243. {
  244. intX = Screen.PrimaryScreen.Bounds.Width - m_size.Width;
  245. }
  246. else
  247. {
  248. intX = p.X;
  249. }
  250. if (m_deviation.HasValue)
  251. {
  252. intX += m_deviation.Value.X;
  253. intY += m_deviation.Value.Y;
  254. }
  255. this.Location = new Point(intX, intY);
  256. }
  257. }
  258. /// <summary>
  259. /// Handles the Tick event of the timer1 control.
  260. /// </summary>
  261. /// <param name="sender">The source of the event.</param>
  262. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  263. private void timer1_Tick(object sender, EventArgs e)
  264. {
  265. if (this.Owner != null)
  266. {
  267. Form frm = this.Owner as Form;
  268. IntPtr _ptr = ControlHelper.GetForegroundWindow();
  269. if (_ptr != frm.Handle && _ptr!=this.Handle)
  270. {
  271. this.Hide();
  272. }
  273. }
  274. }
  275. }
  276. }