• 转:悬挂窗口


    所谓悬挂窗口,就是类似QQ聊天工具的一个功能,当窗口放到桌面的上边界时自动收缩成一个小条隐藏起来;而一旦鼠标再次接触到上述边界的时候,窗口又会自动展开。

    实现方法有两类,一是窗口内实现悬挂,在窗口内创建一个小的Panel,正常时不可见,在悬挂是显示,
    悬挂时设置窗口标题栏不显示和窗口高度为该Panel高度;二是单独窗口悬挂,创建新的窗口作为悬挂时的显示条,同时隐藏掉主窗口。

    一、窗口内实现悬挂
    在LocationChanged事件内判断是否到桌面上边界,通过定时器判断当前鼠标位置(System.Windows.Forms.Control.MousePosition)是否离开窗口区域,或者进入窗口区域。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Demo
    {
        /// <summary>
        /// 方法一:窗口内实现悬挂
        /// </summary>
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                pnlHangBar.Visible = false;
                m_NomalHeight = Height;
                m_IsHange = false;
                timer1.Enabled = true;
                timer1.Interval = 200;
                timer1.Tick += new EventHandler(timer1_Tick);
            }
    
            /// <summary>
            /// 窗体正常高度
            /// </summary>
            int m_NomalHeight = 0;
            /// <summary>
            /// 窗体是否处于悬挂状态
            /// </summary>
            bool m_IsHange = false;
    
            /// <summary>
            /// 窗体被激活时触发
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Activated(object sender, EventArgs e)
            {
                Text = "Activated:" +MousePosition.ToString();
            }
            /// <summary>
            /// 窗体被停用时触发
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Deactivate(object sender, EventArgs e)
            {
                Text = "Deactivate:" + MousePosition.ToString();
            }
    
            /// <summary>
            /// 悬挂
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnHang_Click(object sender, EventArgs e)
            {
                if (this.FormBorderStyle == FormBorderStyle.None)
                {
                    this.FormBorderStyle = FormBorderStyle.Sizable;
                    pnlHangBar.Visible = false;
                }
                else
                {
                    this.FormBorderStyle = FormBorderStyle.None;
                    pnlHangBar.Visible = true;
                    this.Height = pnlHangBar.Height;
                    m_IsHange = true;
                }
            }
    
            /// <summary>
            /// 窗体位置改变时触发,判断是否应该悬挂窗体
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_LocationChanged(object sender, EventArgs e)
            {
                if (Location.Y <= 0)
                {
                    Top = 0;
                    m_IsHange = true;
                }
                else
                {
                    m_IsHange = false;
                }
    
                Text = "LocationChanged:" + MousePosition.ToString();
            }
    
            /// <summary>
            /// 显示或悬挂窗体
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void timer1_Tick(object sender, EventArgs e)
            {
                // 鼠标在屏幕的位置
                lblMousePosition.Text = MousePosition.ToString();
                lblMousePosition2.Text = "鼠标在屏幕的位置:" + MousePosition.ToString();
                // 鼠标在窗体客户端内的位置
                Point pClient = this.PointToClient(MousePosition);
                lblClientPosition.Text = "鼠标在窗体客户端内的位置:" + pClient.ToString();
                // 窗体悬挂
                if (pClient.X < 0 || pClient.X > Width || pClient.Y > Height)  //在窗体客户区域之外时
                {
                    if (m_IsHange)
                    {
                        this.FormBorderStyle = FormBorderStyle.None;
                        pnlHangBar.Visible = true;
                        this.Height = pnlHangBar.Height;
                    }
                }
                else //在窗体客户区域之内
                {
                    if (m_IsHange)
                    {
                        this.FormBorderStyle = FormBorderStyle.Sizable;
                        pnlHangBar.Visible = false;
                        this.Height = m_NomalHeight;
                    }
                }
            }
    
            private void Form1_Resize(object sender, EventArgs e)
            {
                if(!m_IsHange)
                    m_NomalHeight = this.Height;
            }
        }
    }

                              

    二、单独窗口悬挂

    本来不想考虑第二种方式的,但是后来发现需要悬挂的窗口设置高度居然无效,是一个从DevComponents.DotNetBar.Office2007RibbonForm继承的窗口类。

     实现思路基本一样,只是需要注意的是判断当前鼠标的位置需要分不同的窗口转换坐标,还有其他细节见代码。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Demo
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
                timer1.Enabled = true;
                timer1.Interval = 500;
            }
    
            /// <summary>
            /// 窗体是否处于悬挂状态
            /// </summary>
            bool m_IsHange = false;
            /// <summary>
            /// 悬挂标志窗口
            /// </summary>
            FrmHideFlagForm m_HideFlagForm = new FrmHideFlagForm();
    
            /// <summary>
            /// 窗体位置改变时触发,判断是否应该悬挂窗体
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form2_LocationChanged(object sender, EventArgs e)
            {
                if (Location.Y < 0)
                {
                    Top = 0;
                    m_IsHange = true;
                }
                else
                {
                    m_IsHange = false;
                }
                SetHideFlagFormPos(); 
            }
    
            /// <summary> 
            /// 设置标志窗体的位置和大小 
            /// </summary> 
            private void SetHideFlagFormPos()
            {
                m_HideFlagForm.Left = this.Left;
                m_HideFlagForm.Top = this.Top;
                m_HideFlagForm.Width = this.Width;
                m_HideFlagForm.Height = 10;
            }
    
            /// <summary> 
            /// 显示或悬挂窗体
            /// </summary> 
            /// <param name="sender"></param> 
            /// <param name="e"></param> 
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (System.Windows.Forms.Control.MouseButtons == MouseButtons.Left)
                    return;  //在鼠标左键为按下时,认为窗口处在拖动状态,暂停鼠标位置的判断 
                ShowHideForm();
            }
            /// <summary> 
            /// 悬挂或者展开窗体 
            /// </summary> 
            private void ShowHideForm()
            {
                Point pMousePosition = new Point(System.Windows.Forms.Control.MousePosition.X,
                    System.Windows.Forms.Control.MousePosition.Y);
                Point pClientPosition = new Point();
                int iHight = 0;
                if (this.Visible)
                {
                    pClientPosition = PointToClient(pMousePosition);
                    iHight = Height;
                }
                else
                {
                    pClientPosition = m_HideFlagForm.PointToClient(pMousePosition);
                    iHight = m_HideFlagForm.Height;
                }
    
                if (pClientPosition.X < 0 || pClientPosition.X > Width || pClientPosition.Y > iHight)  //在窗体客户区域之外时 
                {
                    if (m_IsHange && FormBorderStyle != FormBorderStyle.None)
                    {
                        FormBorderStyle = FormBorderStyle.None;
                        this.Hide();
                        m_HideFlagForm.Show();
                        SetHideFlagFormPos();
                    }
                }
                else //在窗体客户区域之内 
                {
                    if (m_IsHange && FormBorderStyle != FormBorderStyle.Sizable)
                    {
                        FormBorderStyle = FormBorderStyle.Sizable;
                        m_HideFlagForm.Hide();
                        this.Show();
                    }
                }
            }
    
            /// <summary> 
            /// 窗口大小改变事件 
            /// </summary> 
            /// <param name="sender"></param> 
            /// <param name="e"></param> 
            private void Form2_Resize(object sender, EventArgs e)
            {
                m_HideFlagForm.Left = Left;
                m_HideFlagForm.Width = Width;
            }
        }
    }

              

    参考自:http://www.cnblogs.com/haiyabtx/archive/2012/09/21/2697202.html

  • 相关阅读:
    统计候选人
    九宫格输入法
    前端同学面试准备
    1、单元格内换行诀窍、合并单元格、身份证、日期乱码
    读写锁
    混合锁、互斥锁
    原子操作、自旋锁
    pipeline httpmodule
    vm +cenos7+gitlab 02
    vm +cenos7+gitlab 01
  • 原文地址:https://www.cnblogs.com/lusunqing/p/3450853.html
Copyright © 2020-2023  润新知