zoukankan      html  css  js  c++  java
  • (十九)c#Winform自定义控件-停靠窗体-HZHControls

    官网

    http://www.hzhcontrols.com

    前提

    入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

    GitHub:https://github.com/kwwwvagaa/NetWinformControl

    码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

    如果觉得写的还行,请点个 star 支持一下吧

    欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

    目录

    https://www.cnblogs.com/bfyx/p/11364884.html

    准备工作

    这是一个可停靠在指定位置或停靠在某个控件旁边的无焦点窗体,市区焦点会关闭

    开始

    添加一个Form,命名为FrmAnchor,实现接口IMessageFilter

    有2个构造函数

     1    #region 构造函数
     2         /// <summary>
     3         /// 功能描述:构造函数
     4         /// 作  者:HZH
     5         /// 创建日期:2019-02-27 11:49:08
     6         /// 任务编号:POS
     7         /// </summary>
     8         /// <param name="parentControl">父控件</param>
     9         /// <param name="childControl">子控件</param>
    10         /// <param name="deviation">偏移</param>
    11         public FrmAnchor(Control parentControl, Control childControl, Point? deviation = null)
    12         {
    13             m_parentControl = parentControl;
    14             InitializeComponent();
    15             this.Size = childControl.Size;
    16             this.HandleCreated += FrmDownBoard_HandleCreated;
    17             this.HandleDestroyed += FrmDownBoard_HandleDestroyed;
    18             this.Controls.Add(childControl);
    19             childControl.Dock = DockStyle.Fill;
    20             Point p = parentControl.Parent.PointToScreen(parentControl.Location);
    21             int intX = 0;
    22             int intY = 0;
    23             if (p.Y + parentControl.Height + childControl.Height > Screen.PrimaryScreen.Bounds.Height)
    24             {
    25                 intY = p.Y - childControl.Height - 1;
    26                 blnDown = false;
    27             }
    28             else
    29             {
    30                 intY = p.Y + parentControl.Height + 1;
    31                 blnDown = true;
    32             }
    33 
    34             if (p.X + childControl.Width > Screen.PrimaryScreen.Bounds.Width)
    35             {
    36                 intX = Screen.PrimaryScreen.Bounds.Width - childControl.Width;
    37 
    38             }
    39             else
    40             {
    41                 intX = p.X;
    42             }
    43             if (deviation.HasValue)
    44             {
    45                 intX += deviation.Value.X;
    46                 intY += deviation.Value.Y;
    47             }
    48             this.Location = new Point(intX, intY);
    49         }
    50 
    51         public FrmAnchor(Control parentControl, Size size, Point? deviation = null)
    52         {
    53             m_parentControl = parentControl;
    54             InitializeComponent();
    55             this.Size = size;
    56             this.HandleCreated += FrmDownBoard_HandleCreated;
    57             this.HandleDestroyed += FrmDownBoard_HandleDestroyed;
    58 
    59             Point p = parentControl.Parent.PointToScreen(parentControl.Location);
    60             int intX = 0;
    61             int intY = 0;
    62             if (p.Y + parentControl.Height + size.Height > Screen.PrimaryScreen.Bounds.Height)
    63             {
    64                 intY = p.Y - size.Height - 1;
    65                 blnDown = false;
    66             }
    67             else
    68             {
    69                 intY = p.Y + parentControl.Height + 1;
    70                 blnDown = true;
    71             }
    72 
    73             if (p.X + size.Width > Screen.PrimaryScreen.Bounds.Width)
    74             {
    75                 intX = Screen.PrimaryScreen.Bounds.Width - size.Width;
    76 
    77             }
    78             else
    79             {
    80                 intX = p.X;
    81             }
    82             if (deviation.HasValue)
    83             {
    84                 intX += deviation.Value.X;
    85                 intY += deviation.Value.Y;
    86             }
    87             this.Location = new Point(intX, intY);
    88         }
    89 
    90         #endregion

    消息筛选器处理一下

    private void FrmDownBoard_HandleDestroyed(object sender, EventArgs e)
            {
                Application.RemoveMessageFilter(this);
            }
    
            private void FrmDownBoard_HandleCreated(object sender, EventArgs e)
            {
                Application.AddMessageFilter(this);
            }
    
     public bool PreFilterMessage(ref Message m)
            {
                if (m.Msg != 0x0201 || this.Visible == false)
                    return false;
                var pt = this.PointToClient(MousePosition);
                this.Visible = this.ClientRectangle.Contains(pt);
                return false;
            }

    无焦点处理

     1   #region 无焦点窗体
     2 
     3         [System.Runtime.InteropServices.DllImport("user32.dll")]
     4         private extern static IntPtr SetActiveWindow(IntPtr handle);
     5         private const int WM_ACTIVATE = 0x006;
     6         private const int WM_ACTIVATEAPP = 0x01C;
     7         private const int WM_NCACTIVATE = 0x086;
     8         private const int WA_INACTIVE = 0;
     9         private const int WM_MOUSEACTIVATE = 0x21;
    10         private const int MA_NOACTIVATE = 3;
    11         protected override void WndProc(ref Message m)
    12         {
    13             if (m.Msg == WM_MOUSEACTIVATE)
    14             {
    15                 m.Result = new IntPtr(MA_NOACTIVATE);
    16                 return;
    17             }
    18             else if (m.Msg == WM_NCACTIVATE)
    19             {
    20                 if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
    21                 {
    22                     if (m.LParam != IntPtr.Zero)
    23                     {
    24                         SetActiveWindow(m.LParam);
    25                     }
    26                     else
    27                     {
    28                         SetActiveWindow(IntPtr.Zero);
    29                     }
    30                 }
    31             }
    32             base.WndProc(ref m);
    33         }
    34 
    35         #endregion
     1    private void timer1_Tick(object sender, EventArgs e)
     2         {
     3             if (this.Owner != null)
     4             {
     5                 Form frm = this.Owner as Form;
     6                 IntPtr _ptr = ControlHelper.GetForegroundWindow();
     7                 if (_ptr != frm.Handle)
     8                 {
     9                     this.Hide();
    10                 }
    11             }
    12         }

    显示和关闭动画

     1 private void FrmAnchor_VisibleChanged(object sender, EventArgs e)
     2         {
     3             timer1.Enabled = this.Visible;
     4             if (Visible)
     5             {
     6                 if (blnDown)
     7                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_POSITIVE);
     8                 else
     9                 {
    10                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_NEGATIVE);
    11                 }
    12             }
    13             else
    14             {
    15                 if (blnDown)
    16                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_NEGATIVE | ControlHelper.AW_HIDE);
    17                 else
    18                 {
    19                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_POSITIVE | ControlHelper.AW_HIDE);
    20 
    21                 }
    22             }
    23         }

    再看一下完整代码

      1 // 版权所有  黄正辉  交流群:568015492   QQ:623128629
      2 // 文件名称:FrmAnchor.cs
      3 // 创建日期:2019-08-15 16:04:24
      4 // 功能描述:FrmAnchor
      5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
      6 
      7 using System;
      8 using System.Collections.Generic;
      9 using System.ComponentModel;
     10 using System.Data;
     11 using System.Drawing;
     12 using System.Linq;
     13 using System.Text;
     14 using System.Windows.Forms;
     15 
     16 namespace HZH_Controls.Forms
     17 {
     18     /// <summary>
     19     /// 功能描述:停靠窗体
     20     /// 作  者:HZH
     21     /// 创建日期:2019-02-27 11:49:03
     22     /// 任务编号:POS
     23     /// </summary>
     24     public partial class FrmAnchor : Form, IMessageFilter
     25     {
     26         Control m_parentControl = null;
     27         private bool blnDown = true;
     28         #region 构造函数
     29         /// <summary>
     30         /// 功能描述:构造函数
     31         /// 作  者:HZH
     32         /// 创建日期:2019-02-27 11:49:08
     33         /// 任务编号:POS
     34         /// </summary>
     35         /// <param name="parentControl">父控件</param>
     36         /// <param name="childControl">子控件</param>
     37         /// <param name="deviation">偏移</param>
     38         public FrmAnchor(Control parentControl, Control childControl, Point? deviation = null)
     39         {
     40             m_parentControl = parentControl;
     41             InitializeComponent();
     42             this.Size = childControl.Size;
     43             this.HandleCreated += FrmDownBoard_HandleCreated;
     44             this.HandleDestroyed += FrmDownBoard_HandleDestroyed;
     45             this.Controls.Add(childControl);
     46             childControl.Dock = DockStyle.Fill;
     47             Point p = parentControl.Parent.PointToScreen(parentControl.Location);
     48             int intX = 0;
     49             int intY = 0;
     50             if (p.Y + parentControl.Height + childControl.Height > Screen.PrimaryScreen.Bounds.Height)
     51             {
     52                 intY = p.Y - childControl.Height - 1;
     53                 blnDown = false;
     54             }
     55             else
     56             {
     57                 intY = p.Y + parentControl.Height + 1;
     58                 blnDown = true;
     59             }
     60 
     61             if (p.X + childControl.Width > Screen.PrimaryScreen.Bounds.Width)
     62             {
     63                 intX = Screen.PrimaryScreen.Bounds.Width - childControl.Width;
     64 
     65             }
     66             else
     67             {
     68                 intX = p.X;
     69             }
     70             if (deviation.HasValue)
     71             {
     72                 intX += deviation.Value.X;
     73                 intY += deviation.Value.Y;
     74             }
     75             this.Location = new Point(intX, intY);
     76         }
     77 
     78         public FrmAnchor(Control parentControl, Size size, Point? deviation = null)
     79         {
     80             m_parentControl = parentControl;
     81             InitializeComponent();
     82             this.Size = size;
     83             this.HandleCreated += FrmDownBoard_HandleCreated;
     84             this.HandleDestroyed += FrmDownBoard_HandleDestroyed;
     85 
     86             Point p = parentControl.Parent.PointToScreen(parentControl.Location);
     87             int intX = 0;
     88             int intY = 0;
     89             if (p.Y + parentControl.Height + size.Height > Screen.PrimaryScreen.Bounds.Height)
     90             {
     91                 intY = p.Y - size.Height - 1;
     92                 blnDown = false;
     93             }
     94             else
     95             {
     96                 intY = p.Y + parentControl.Height + 1;
     97                 blnDown = true;
     98             }
     99 
    100             if (p.X + size.Width > Screen.PrimaryScreen.Bounds.Width)
    101             {
    102                 intX = Screen.PrimaryScreen.Bounds.Width - size.Width;
    103 
    104             }
    105             else
    106             {
    107                 intX = p.X;
    108             }
    109             if (deviation.HasValue)
    110             {
    111                 intX += deviation.Value.X;
    112                 intY += deviation.Value.Y;
    113             }
    114             this.Location = new Point(intX, intY);
    115         }
    116 
    117         #endregion
    118 
    119         private void FrmDownBoard_HandleDestroyed(object sender, EventArgs e)
    120         {
    121             Application.RemoveMessageFilter(this);
    122         }
    123 
    124         private void FrmDownBoard_HandleCreated(object sender, EventArgs e)
    125         {
    126             Application.AddMessageFilter(this);
    127         }
    128 
    129         #region 无焦点窗体
    130 
    131         [System.Runtime.InteropServices.DllImport("user32.dll")]
    132         private extern static IntPtr SetActiveWindow(IntPtr handle);
    133         private const int WM_ACTIVATE = 0x006;
    134         private const int WM_ACTIVATEAPP = 0x01C;
    135         private const int WM_NCACTIVATE = 0x086;
    136         private const int WA_INACTIVE = 0;
    137         private const int WM_MOUSEACTIVATE = 0x21;
    138         private const int MA_NOACTIVATE = 3;
    139         protected override void WndProc(ref Message m)
    140         {
    141             if (m.Msg == WM_MOUSEACTIVATE)
    142             {
    143                 m.Result = new IntPtr(MA_NOACTIVATE);
    144                 return;
    145             }
    146             else if (m.Msg == WM_NCACTIVATE)
    147             {
    148                 if (((int)m.WParam & 0xFFFF) != WA_INACTIVE)
    149                 {
    150                     if (m.LParam != IntPtr.Zero)
    151                     {
    152                         SetActiveWindow(m.LParam);
    153                     }
    154                     else
    155                     {
    156                         SetActiveWindow(IntPtr.Zero);
    157                     }
    158                 }
    159             }
    160             base.WndProc(ref m);
    161         }
    162 
    163         #endregion
    164 
    165         public bool PreFilterMessage(ref Message m)
    166         {
    167             if (m.Msg != 0x0201 || this.Visible == false)
    168                 return false;
    169             var pt = this.PointToClient(MousePosition);
    170             this.Visible = this.ClientRectangle.Contains(pt);
    171             return false;
    172         }
    173 
    174         private void FrmAnchor_Load(object sender, EventArgs e)
    175         {
    176 
    177         }
    178 
    179 
    180         private void FrmAnchor_VisibleChanged(object sender, EventArgs e)
    181         {
    182             timer1.Enabled = this.Visible;
    183             if (Visible)
    184             {
    185                 if (blnDown)
    186                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_POSITIVE);
    187                 else
    188                 {
    189                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_NEGATIVE);
    190                 }
    191             }
    192             else
    193             {
    194                 if (blnDown)
    195                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_NEGATIVE | ControlHelper.AW_HIDE);
    196                 else
    197                 {
    198                     ControlHelper.AnimateWindow(this.Handle, 100, ControlHelper.AW_VER_POSITIVE | ControlHelper.AW_HIDE);
    199 
    200                 }
    201             }
    202         }
    203 
    204         private void timer1_Tick(object sender, EventArgs e)
    205         {
    206             if (this.Owner != null)
    207             {
    208                 Form frm = this.Owner as Form;
    209                 IntPtr _ptr = ControlHelper.GetForegroundWindow();
    210                 if (_ptr != frm.Handle)
    211                 {
    212                     this.Hide();
    213                 }
    214             }
    215         }
    216 
    217     }
    218 }
    View Code
     1 namespace HZH_Controls.Forms
     2 {
     3     partial class FrmAnchor
     4     {
     5         /// <summary>
     6         /// Required designer variable.
     7         /// </summary>
     8         private System.ComponentModel.IContainer components = null;
     9 
    10         /// <summary>
    11         /// Clean up any resources being used.
    12         /// </summary>
    13         /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    14         protected override void Dispose(bool disposing)
    15         {
    16             if (disposing && (components != null))
    17             {
    18                 components.Dispose();
    19             }
    20             base.Dispose(disposing);
    21         }
    22 
    23         #region Windows Form Designer generated code
    24 
    25         /// <summary>
    26         /// Required method for Designer support - do not modify
    27         /// the contents of this method with the code editor.
    28         /// </summary>
    29         private void InitializeComponent()
    30         {
    31             this.components = new System.ComponentModel.Container();
    32             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAnchor));
    33             this.timer1 = new System.Windows.Forms.Timer(this.components);
    34             this.SuspendLayout();
    35             // 
    36             // timer1
    37             // 
    38             this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
    39             // 
    40             // FrmAnchor
    41             // 
    42             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
    43             this.ClientSize = new System.Drawing.Size(45, 48);
    44             this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    45             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
    46             this.Name = "FrmAnchor";
    47             this.ShowIcon = false;
    48             this.ShowInTaskbar = false;
    49             this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
    50             this.Text = "FrmAnchor";
    51             this.TopMost = true;
    52             this.Load += new System.EventHandler(this.FrmAnchor_Load);
    53             this.VisibleChanged += new System.EventHandler(this.FrmAnchor_VisibleChanged);
    54             this.ResumeLayout(false);
    55 
    56         }
    57 
    58         #endregion
    59 
    60         private System.Windows.Forms.Timer timer1;
    61     }
    62 }
    View Code

    用处及效果

    用处:弹出菜单,文本框弹出键盘等

    最后的话

    如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧

  • 相关阅读:
    魔术方法之__call与__callStatic方法
    thinkphp5 实现搜索分页能下一页保留搜索条件
    koa2
    mongodb
    nodejs
    小程序
    Vue学习
    js4
    扎心!来自互联网er的2019年度总结,看完笑着流泪……
    谈谈“奋斗逼!”
  • 原文地址:https://www.cnblogs.com/bfyx/p/11363814.html
Copyright © 2011-2022 走看看