开发者

C#实现仿QQ抽屉式窗体的设计方法

目录
  • 前言
  • 1.WindowFromPoint函数
  • 2.GetParent函数
  • 3.实例
    • (1)图片集合编辑器
    • (2)Form1.Designer.cs
    • (3)Form1.cs
  • 4.生成效果 

    前言

    QQ软件对于绝大多数的人来说再熟悉不过了,它以使用方便、界面美观及功能完善而著称。

    主要通过使用API函数WindowFromPoint和GetParent实现仿QQ的抽屉式窗体:

    1.WindowFromPoint函数

    该函数用于获得包含指定点坐标的窗口的句柄。语法格式如下:

    [DlIImport("user32.dll")]   //需要引入user32.dll动态链接库
    public static extern int WindowFromPoint(int xPoint,int yPoint) //获得包含指定点坐标的窗口的句柄
    参数说明
    xPoint:被检测点的横坐标。
    yPoint:被检测点的纵坐标。
    目返回值:为包含指定点坐标的窗口的句柄,若包含指定点坐标的窗口不存在,则返回值为null;若该坐标对应的点在静态文本控件之上,则返回值是在该静态文本控件下面的窗口的句柄。

    2.GetParent函数

    该函数用于获取指定句柄的父级。语法格式如下:

    [DllImport("user32.dll",ExactSpelling =true,CharSet =CharSet.Auto)]//需要引入user32.dll动态链接库
    public static extern IntPtr GetParent(IntPtr hWnd);                 //获取指定句柄的父级
     
    参数说明
    hWnd:指定窗口的句柄。
    返回值:若果函数执行成功,则返回指定窗口句柄的父级;若函数执行失败,则返回值为null。

    3.实例

    本实例仿照QQ软件界面的基本操作设计了一个抽屉式的窗体:在该窗体中单击任意按钮,程序将显示被单击按钮对应的列表,同时隐藏其他两个按钮对应的列表;用鼠标拖曳该窗体到屏幕的任意边缘,窗体会自动隐藏到该边缘内,当鼠标划过隐藏窗体的边缘时,窗体会显示出来;当鼠标离开窗体时,窗体再次被隐藏。

    (1)图片集合编辑器

    本实例没有使用资源管理器加载图片。本实例设计了一个imageList1控件,项目使用的图片都要设计到imageList1的图像集合编辑器中。

    C#实现仿QQ抽屉式窗体的设计方法

    (2)Form1.Designer.cs

    namespace _190
    {
        partial class Form1
        {
        编程    /// <summary>
            ///  Required designer variable.
            /// </summary>
            private System.ComponentModel.IContainer components = null;
     
            /// <summary>
            ///  Clean up any resources being used.
            /// </summary>
            /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
     
            #region Windows Form Designer generated code
     
            /// <summary>
            ///  Required method for Designer support - do not modify
            ///  the contents of this method wipythonth the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                components = new System.ComponentModel.Container();
                System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
                button1 = new Button();
                button2 = new Button();
                button3 = new Button();
                listView1 = new ListView();
                imageList1 = new ImageList(components);
                JudgeWinMouPosition = new System.Windows.Forms.Timer(components);
                HideWindow = new System.Windows.Forms.Timer(components);
                SuspendLayout();
                // 
                // button1
                // 
                button1.Dock = DockStyle.Top;
                button1.Location = new Point(0, 0);
                but编程客栈ton1.Name = "button1";
                button1.Size = new Size(153, 23);
                button1.TabIndex = 0;
                button1.Text = "我的好友";
                button1.UseVisualStyleBackColor = true;
                button1.Click += Button1_Click;
                // 
                // button2
                // 
                button2.Dock = DockStyle.Bottom;
                button2.Location = new Point(0, 262http://www.devze.com);
                button2.Name = "button2";
                button2.Size = new Size(153, 23);
                button2.TabIndex = 1;
                button2.Text = "黑名单";
                button2.UseVisualStyleBackColor = true;
                button2.Click += Button2_Click;
                // 
                // button3
                // 
                button3.Dock = DockStyle.Bottom;
                button3.Location = new Point(0, 239);
                button3.Name = "button3";
                button3.Size = new Size(153, 23);
                button3.TabIndex = 2;
                button3.Text = "陌生人";
                button3.UseVisualStyleBackColor = true;
                button3.Click += Button3_Click;
                // 
                // listView1
                // 
                listView1.Dock = DockStyle.Fill;
                listView1.Location = new Point(0, 23);
                listView1.Name = "listView1";
                listView1.Size = new Size(153, 216);
                listView1.TabIndex = 3;
                listView1.UseCompatibleStateImageBehavior = false;
                // 
                // imageList1
                // 
                imageList1.ColorDepth = ColorDepth.Depth32Bit;
                imageList1.ImageStream = (ImageListStreamer)resources.GetObject("imageList1.ImageStream");
                imageList1.TransparentColor = Color.Transparent;
                imageList1.Images.SetKeyName(0, "01.jpg");
                imageList1.Images.SetKeyName(1, "02.png");
                imageList1.Images.SetKeyName(2, "03.jpg");
                imageList1.Images.SetKeyName(3, "04.jpg");
                imageList1.Images.SetKeyName(4, "05.png");
                imageList1.Images.SetKeyName(5, "06.jpg");
                // 
                // JudgeWinMouPosition
                // 
                JudgeWinMouPosition.Tick += JudgeWinMouPosition_Tick;
                // 
                // HideWindow
                // 
                HideWindow.Tick += HideWindow_Tick;
                // 
                // Form1
                // 
                AutoScaleDimensions = new SizeF(7F, 17F);
                AutoScaleMode = AutoScaleMode.Font;
                BackgroundImageLayout = ImageLayout.Stretch;
                ClientSize = new Size(153, 285);
                Controls.Add(listView1);
                Controls.Add(button3);
                Controls.Add(button2);
                Controls.Add(button1);
                Name = "Form1";
                StartPosition = FormStartPosition.CenterScreen;
                Text = "仿QQ抽屉式窗体";
                Load += Form1_Load;
                LocationChanged += Form1_LocationChanged;
                Resize += Form1_Resize;
                ResumeLayout(false);
            }
     
            #endregion
     
            private Button button1;
            private Button button2;
            private Button button3;
            private ListView listView1;
            private ImageList imageList1;
            private System.Windows.Forms.Timer JudgeWinMouPosition;
            private System.Windows.Forms.Timer HideWindow;
        }
    }编程

    (3)Form1.cs

    // 仿QQ抽屉式窗体
    using System.Runtime.InteropServices;
     
    namespace _190
    {
        public partial class Form1 : Form
        {
            #region 声明本程序中用到的API函数
            //获取当前鼠标下可视化控件的函数
            [LibraryImport("user32.dll")]
            public static partial int WindowFromPoint(int xPoint, int yPoint);
            //获取指定句柄的父级函数
            [LibraryImport("user32.dll")]
            public static partial IntPtr GetParent(IntPtr hWnd);
            //获取屏幕的大小
            [LibraryImport("user32.dll", EntryPoint = "GetSystemMetrics")]
            private static partial int GetSystemMetrics(int mVal);
            #endregion
     
            public Form1()
            {
                InitializeComponent();
            }
     
            #region 运行本程序需要声明的变量
            private IntPtr CurrentHandle;   //记录鼠标当前状态下控件的句柄
            private int WindowFlag;         //标记是否对窗体进行拉伸操作 
            private int intOriHeight;
            #endregion
     
            private void Form1_Load(object sender, EventArgs e)
            {
                intOriHeight = Height;
                DesktopLocation = new Point(794, 0);   //为当前窗体定位
                JudgeWinMouPosition.Enabled = true;    //计时器JudgeWinMouPosition开始工作
                listView1.Clear();
                listView1.LargeImageList = imageList1;
                listView1.Items.Add("小猪", "小猪", 0);
                listView1.Items.Add("小狗", "小狗", 1);
                listView1.Items.Add("娇娇", "娇娇", 2);
            }
     
            public int OriHeight
            {
                get { return intOriHeight; }
            }
     
            /// <summary>
            /// 我的好友
            /// </summary>
            private void Button1_Click(object sender, EventArgs e)
            {
                listView1.Dock = DockStyle.None;
                button1.Dock = DockStyle.Top;
                button2.Dock = DockStyle.Bottom;
                button3.Dock = DockStyle.Bottom;
                button3.SendToBack();
                listView1.BringToFront();
                listView1.Dock = DockStyle.Bottom;
                listView1.Clear();
                listView1.Items.Add("小猪", "小猪", 0);
                listView1.Items.Add("小狗", "小狗", 1);
                listView1.Items.Add("娇娇", "娇娇", 2);
            }
            /// <summary>
            /// 陌生人
            /// </summary>
            private void Button3_Click(object sender, EventArgs e)
            {
                listView1.Dock = DockStyle.None;
                button2.Dock = DockStyle.Top;
                button1.Dock = DockStyle.Top;
                button1.SendToBack();
                button3.Dock = DockStyle.Bottom;
                listView1.Dock = DockStyle.Bottom;
                listView1.Clear();
                listView1.Items.Add("北风", "北风", 3);
            }
            /// <summary>
            /// 黑名单
            /// </summary>
            private void Button2_Click(object sender, EventArgs e)
            {
                listView1.Dock = DockStyle.None;
     
                button3.Dock = DockStyle.Top;   //设置button3按钮绑定到窗体的上边缘
     
                button2.Dock = DockStyle.Top;   //设置button2按钮绑定到窗体的上边缘
                button2.SendToBack();           //保证button2在button3的后面
     
                button1.Dock = DockStyle.Top;
                button1.SendToBack();           //保证button1在button2的后面
     
     
                listView1.Dock = DockStyle.Bottom;
                listView1.Clear();
                listView1.Items.Add("冰雨", "冰雨", 5);
            }
            /// <summary>
            /// 判断当前窗体处于哪个状态
            /// </summary>
            private void HideWindow_Tick(object sender, EventArgs e)
            {
                switch (Convert.ToInt32(WindowFlag.ToString())) 
                {
                    case 1:          //当窗体处于最上端时   
                        if (Top < 3) //当窗体与容器工作区的上边缘的距离小于5px时
                            Top = -(Height - 2);  //设定当前窗体距容器工作区上边缘的值
                        break;
                    case 2:          //当窗体处于最左端时
                        if (Left < 3)//当窗体与容器工作区的左边缘的距离小于5px时
                            Left = -(Width - 2); //设定当前窗体据容器工作区左边缘的值
                        break;
                    case 3:          //当窗体处于最右端时
                        if ((Left + Width) > (GetSystemMetrics(0) - 3))     //当窗体与容器工作区的右边缘的距离小于5px时
                            Left = GetSystemMetrics(0) - 2;                 //设定当前窗体距容器工作区左边缘的值
                        break;
                    case 4:          //当窗体处于最低端时
                        if (Bottom > Screen.AllScreens[0].Bounds.Height - 3)//当窗体与容器工作区的下边缘的距离小于5px时
                            Top = Screen.AllScreens[0].Bounds.Height - 5;   //设定当前窗体距容器工作区上边缘之间的距离
                        break;
                }
            }
     
            private void JudgeWinMouPosition_Tick(object sender, EventArgs e)
            {
                if (Top < 3)         //当本窗体距屏幕的上边距小于3px时
                {
                    if (Handle == MouseNowposition(Cursor.Position.X, Cursor.Position.Y))//当鼠标在该窗体上时
                    {
                        WindowFlag = 1;             //设定当前的窗体状态
                        HideWindow.Enabled = false; //设定计时器HideWindow为不可用状态
                        Top = 0;                    //设定窗体上边缘与容器工作区上边缘之间的距离
                    }
                    else                            //当鼠标没在窗体上时
                    {
                        WindowFlag = 1;             //设定当前的窗体状态
                        HideWindow.Enabled = true;  //启动计时器HideWindow
                    }
                }                                   //当本窗体距屏幕的上边距大于3px时
                else
                {
                    //当本窗体在屏幕的最左端或者最右端、最下端时
                    if (Left < 3 || (Left + Width) > (GetSystemMetrics(0) - 3) || (Top + Height) > (Screen.AllScreens[0].Bounds.Height - 3))
                    {
                        if (Left < 3)              //当窗体处于屏幕左侧时
                        {
                            if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y))    //当鼠标在该窗体上时
                            {
                                Height = Screen.AllScreens[0].Bounds.Height - 40;
                                Top = 3;
                                WindowFlag = 2;    //设定当前的窗体状态
                                HideWindow.Enabled = false;//设定计时器HideWindow为不可用状态
                                Left = 0;          //设定窗体的左边缘与容器工作区的左边缘之间的距离
                            }
                            else                   //当鼠标没在该窗体上时
                            {
                                WindowFlag = 2;    //设定当前的窗体状态
                                HideWindow.Enabled = true;//设定计时器HideWindow为可用状态
                            }
                        }
                        if ((Left + Width) > (GetSystemMetrics(0) - 3)) //当窗体处于屏幕的最右侧时
                        {
                            if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y))//当鼠标处于窗体上时
                            {
                                Height = Screen.AllScreens[0].Bounds.Height - 40;
                                Top = 3;
                                WindowFlag = 3;       //设定当前的窗体状态
                                HideWindow.Enabled = false; //设定计时器HideWindow为不可用状态
                                Left = GetSystemMetrics(0) - Width;      //设定该窗体与容器工作区左边缘之间的距离
                            }
                            else                      //当鼠标离开窗体时
                            {
                                WindowFlag = 3;       //设定当前的窗体状态
                                HideWindow.Enabled = true;  //设定计时器HideWindow为可用状态
                            }
                        }
                        //当窗体距屏幕最下端的距离小于3px时
                        if ((Top + Height) > (Screen.AllScreens[0].Bounds.Height - 3))
                        {
                            if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y)) //当鼠标在该窗体上时
                            {
                                WindowFlag = 4;           //设定当前的窗体状态
                                HideWindow.Enabled = false;//设定计时器HideWindow为不可用状态
                                Top = Screen.AllScreens[0].Bounds.Height - Height;//设定该窗体与容器工作区上边缘之间的距离
                            }
                            else
                            {
                                if ((Left > Width + 3) && (GetSystemMetrics(0) - Right) > 3)
                                {
                                    WindowFlag = 4;           //设定当前的窗体状态
                                    HideWindow.Enabled = true; //设定计时器HideWindow为可用状态
                                }
                            }
                        }
                    }
                }
            }
     
     
            #region 获取鼠标当前状态下控件的句柄
            /// <summary>
            /// 获取鼠标当前状态下控件的句柄
            /// </summary>
            /// <param name="x">当前鼠标的X坐标</param>
            /// <param name="y">当前鼠标的Y坐标</param>
            /// <returns></returns>
            public IntPtr MouseNowPosition(int x, int y)
            {
                IntPtr OriginalHandle;//声明保存原始句柄的变量
                OriginalHandle = WindowFromPoint(x, y);//获取包含鼠标原始位置的窗口的句柄
                CurrentHandle = OriginalHandle;        //设置当前句柄
                while (OriginalHandle != 0)            //循环判断鼠标是否移动
                {
                    CurrentHandle = OriginalHandle;    //记录当前的句柄
                    OriginalHandle = GetParent(CurrentHandle);//更新原始句柄
                }
                return CurrentHandle;                  //返回当前的句柄
            }
            #endregion
     
     
            private void Form1_LocationChanged(object sender, EventArgs e)
            {
                if (Left > 3 && Right < (GetSystemMetrics(0) - 3))
                {
                    if (Height == Screen.AllScreens[0].Bounds.Height - 40)
                    {
                        Height = OriHeight;
                    }
                }
            }
     
            private void Form1_Resize(object sender, EventArgs e)
            {
                listView1.Height = Height - button3.Height * 3 - 30;
            }
        }
    }

    4.生成效果 

    生成的窗体默认停留在窗体顶部,并且隐藏的。鼠标滑动到其停住的区域该窗体就会弹出。此时可以拖动窗体到左、右、下部,松开鼠标后窗体会停驻在左、右、下部。操作窗体上的最大化、关闭按钮,可以让窗体最大化和关闭。还可以操作窗体的边框,向左、下、右拖动放大缩小窗体;鼠标点击任务栏的图标可以查找窗体当前的停靠位置。

    C#实现仿QQ抽屉式窗体的设计方法

    C#实现仿QQ抽屉式窗体的设计方法

    C#实现仿QQ抽屉式窗体的设计方法

    以上就是C#实现仿QQ抽屉式窗体的设计方法的详细内容,更多关于C#仿QQ抽屉式窗体的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜