C#實(shí)現(xiàn)仿QQ抽屜式窗體的設(shè)計(jì)方法
前言
QQ軟件對于絕大多數(shù)的人來說再熟悉不過了,它以使用方便、界面美觀及功能完善而著稱。
主要通過使用API函數(shù)WindowFromPoint和GetParent實(shí)現(xiàn)仿QQ的抽屜式窗體:
1.WindowFromPoint函數(shù)
該函數(shù)用于獲得包含指定點(diǎn)坐標(biāo)的窗口的句柄。語法格式如下:
[DlIImport("user32.dll")] //需要引入user32.dll動(dòng)態(tài)鏈接庫 public static extern int WindowFromPoint(int xPoint,int yPoint) //獲得包含指定點(diǎn)坐標(biāo)的窗口的句柄 參數(shù)說明 xPoint:被檢測點(diǎn)的橫坐標(biāo)。 yPoint:被檢測點(diǎn)的縱坐標(biāo)。 目返回值:為包含指定點(diǎn)坐標(biāo)的窗口的句柄,若包含指定點(diǎn)坐標(biāo)的窗口不存在,則返回值為null;若該坐標(biāo)對應(yīng)的點(diǎn)在靜態(tài)文本控件之上,則返回值是在該靜態(tài)文本控件下面的窗口的句柄。
2.GetParent函數(shù)
該函數(shù)用于獲取指定句柄的父級(jí)。語法格式如下:
[DllImport("user32.dll",ExactSpelling =true,CharSet =CharSet.Auto)]//需要引入user32.dll動(dòng)態(tài)鏈接庫 public static extern IntPtr GetParent(IntPtr hWnd); //獲取指定句柄的父級(jí) 參數(shù)說明 hWnd:指定窗口的句柄。 返回值:若果函數(shù)執(zhí)行成功,則返回指定窗口句柄的父級(jí);若函數(shù)執(zhí)行失敗,則返回值為null。
3.實(shí)例
本實(shí)例仿照QQ軟件界面的基本操作設(shè)計(jì)了一個(gè)抽屜式的窗體:在該窗體中單擊任意按鈕,程序?qū)@示被單擊按鈕對應(yīng)的列表,同時(shí)隱藏其他兩個(gè)按鈕對應(yīng)的列表;用鼠標(biāo)拖曳該窗體到屏幕的任意邊緣,窗體會(huì)自動(dòng)隱藏到該邊緣內(nèi),當(dāng)鼠標(biāo)劃過隱藏窗體的邊緣時(shí),窗體會(huì)顯示出來;當(dāng)鼠標(biāo)離開窗體時(shí),窗體再次被隱藏。
(1)圖片集合編輯器
本實(shí)例沒有使用資源管理器加載圖片。本實(shí)例設(shè)計(jì)了一個(gè)imageList1控件,項(xiàng)目使用的圖片都要設(shè)計(jì)到imageList1的圖像集合編輯器中。
(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 with 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); button1.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, 262); 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函數(shù) //獲取當(dāng)前鼠標(biāo)下可視化控件的函數(shù) [LibraryImport("user32.dll")] public static partial int WindowFromPoint(int xPoint, int yPoint); //獲取指定句柄的父級(jí)函數(shù) [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 運(yùn)行本程序需要聲明的變量 private IntPtr CurrentHandle; //記錄鼠標(biāo)當(dāng)前狀態(tài)下控件的句柄 private int WindowFlag; //標(biāo)記是否對窗體進(jìn)行拉伸操作 private int intOriHeight; #endregion private void Form1_Load(object sender, EventArgs e) { intOriHeight = Height; DesktopLocation = new Point(794, 0); //為當(dāng)前窗體定位 JudgeWinMouPosition.Enabled = true; //計(jì)時(shí)器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("北風(fēng)", "北風(fēng)", 3); } /// <summary> /// 黑名單 /// </summary> private void Button2_Click(object sender, EventArgs e) { listView1.Dock = DockStyle.None; button3.Dock = DockStyle.Top; //設(shè)置button3按鈕綁定到窗體的上邊緣 button2.Dock = DockStyle.Top; //設(shè)置button2按鈕綁定到窗體的上邊緣 button2.SendToBack(); //保證button2在button3的后面 button1.Dock = DockStyle.Top; button1.SendToBack(); //保證button1在button2的后面 listView1.Dock = DockStyle.Bottom; listView1.Clear(); listView1.Items.Add("冰雨", "冰雨", 5); } /// <summary> /// 判斷當(dāng)前窗體處于哪個(gè)狀態(tài) /// </summary> private void HideWindow_Tick(object sender, EventArgs e) { switch (Convert.ToInt32(WindowFlag.ToString())) { case 1: //當(dāng)窗體處于最上端時(shí) if (Top < 3) //當(dāng)窗體與容器工作區(qū)的上邊緣的距離小于5px時(shí) Top = -(Height - 2); //設(shè)定當(dāng)前窗體距容器工作區(qū)上邊緣的值 break; case 2: //當(dāng)窗體處于最左端時(shí) if (Left < 3)//當(dāng)窗體與容器工作區(qū)的左邊緣的距離小于5px時(shí) Left = -(Width - 2); //設(shè)定當(dāng)前窗體據(jù)容器工作區(qū)左邊緣的值 break; case 3: //當(dāng)窗體處于最右端時(shí) if ((Left + Width) > (GetSystemMetrics(0) - 3)) //當(dāng)窗體與容器工作區(qū)的右邊緣的距離小于5px時(shí) Left = GetSystemMetrics(0) - 2; //設(shè)定當(dāng)前窗體距容器工作區(qū)左邊緣的值 break; case 4: //當(dāng)窗體處于最低端時(shí) if (Bottom > Screen.AllScreens[0].Bounds.Height - 3)//當(dāng)窗體與容器工作區(qū)的下邊緣的距離小于5px時(shí) Top = Screen.AllScreens[0].Bounds.Height - 5; //設(shè)定當(dāng)前窗體距容器工作區(qū)上邊緣之間的距離 break; } } private void JudgeWinMouPosition_Tick(object sender, EventArgs e) { if (Top < 3) //當(dāng)本窗體距屏幕的上邊距小于3px時(shí) { if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y))//當(dāng)鼠標(biāo)在該窗體上時(shí) { WindowFlag = 1; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = false; //設(shè)定計(jì)時(shí)器HideWindow為不可用狀態(tài) Top = 0; //設(shè)定窗體上邊緣與容器工作區(qū)上邊緣之間的距離 } else //當(dāng)鼠標(biāo)沒在窗體上時(shí) { WindowFlag = 1; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = true; //啟動(dòng)計(jì)時(shí)器HideWindow } } //當(dāng)本窗體距屏幕的上邊距大于3px時(shí) else { //當(dāng)本窗體在屏幕的最左端或者最右端、最下端時(shí) if (Left < 3 || (Left + Width) > (GetSystemMetrics(0) - 3) || (Top + Height) > (Screen.AllScreens[0].Bounds.Height - 3)) { if (Left < 3) //當(dāng)窗體處于屏幕左側(cè)時(shí) { if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y)) //當(dāng)鼠標(biāo)在該窗體上時(shí) { Height = Screen.AllScreens[0].Bounds.Height - 40; Top = 3; WindowFlag = 2; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = false;//設(shè)定計(jì)時(shí)器HideWindow為不可用狀態(tài) Left = 0; //設(shè)定窗體的左邊緣與容器工作區(qū)的左邊緣之間的距離 } else //當(dāng)鼠標(biāo)沒在該窗體上時(shí) { WindowFlag = 2; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = true;//設(shè)定計(jì)時(shí)器HideWindow為可用狀態(tài) } } if ((Left + Width) > (GetSystemMetrics(0) - 3)) //當(dāng)窗體處于屏幕的最右側(cè)時(shí) { if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y))//當(dāng)鼠標(biāo)處于窗體上時(shí) { Height = Screen.AllScreens[0].Bounds.Height - 40; Top = 3; WindowFlag = 3; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = false; //設(shè)定計(jì)時(shí)器HideWindow為不可用狀態(tài) Left = GetSystemMetrics(0) - Width; //設(shè)定該窗體與容器工作區(qū)左邊緣之間的距離 } else //當(dāng)鼠標(biāo)離開窗體時(shí) { WindowFlag = 3; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = true; //設(shè)定計(jì)時(shí)器HideWindow為可用狀態(tài) } } //當(dāng)窗體距屏幕最下端的距離小于3px時(shí) if ((Top + Height) > (Screen.AllScreens[0].Bounds.Height - 3)) { if (Handle == MouseNowPosition(Cursor.Position.X, Cursor.Position.Y)) //當(dāng)鼠標(biāo)在該窗體上時(shí) { WindowFlag = 4; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = false;//設(shè)定計(jì)時(shí)器HideWindow為不可用狀態(tài) Top = Screen.AllScreens[0].Bounds.Height - Height;//設(shè)定該窗體與容器工作區(qū)上邊緣之間的距離 } else { if ((Left > Width + 3) && (GetSystemMetrics(0) - Right) > 3) { WindowFlag = 4; //設(shè)定當(dāng)前的窗體狀態(tài) HideWindow.Enabled = true; //設(shè)定計(jì)時(shí)器HideWindow為可用狀態(tài) } } } } } } #region 獲取鼠標(biāo)當(dāng)前狀態(tài)下控件的句柄 /// <summary> /// 獲取鼠標(biāo)當(dāng)前狀態(tài)下控件的句柄 /// </summary> /// <param name="x">當(dāng)前鼠標(biāo)的X坐標(biāo)</param> /// <param name="y">當(dāng)前鼠標(biāo)的Y坐標(biāo)</param> /// <returns></returns> public IntPtr MouseNowPosition(int x, int y) { IntPtr OriginalHandle;//聲明保存原始句柄的變量 OriginalHandle = WindowFromPoint(x, y);//獲取包含鼠標(biāo)原始位置的窗口的句柄 CurrentHandle = OriginalHandle; //設(shè)置當(dāng)前句柄 while (OriginalHandle != 0) //循環(huán)判斷鼠標(biāo)是否移動(dòng) { CurrentHandle = OriginalHandle; //記錄當(dāng)前的句柄 OriginalHandle = GetParent(CurrentHandle);//更新原始句柄 } return CurrentHandle; //返回當(dāng)前的句柄 } #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.生成效果
生成的窗體默認(rèn)停留在窗體頂部,并且隱藏的。鼠標(biāo)滑動(dòng)到其停住的區(qū)域該窗體就會(huì)彈出。此時(shí)可以拖動(dòng)窗體到左、右、下部,松開鼠標(biāo)后窗體會(huì)停駐在左、右、下部。操作窗體上的最大化、關(guān)閉按鈕,可以讓窗體最大化和關(guān)閉。還可以操作窗體的邊框,向左、下、右拖動(dòng)放大縮小窗體;鼠標(biāo)點(diǎn)擊任務(wù)欄的圖標(biāo)可以查找窗體當(dāng)前的??课恢?。
以上就是C#實(shí)現(xiàn)仿QQ抽屜式窗體的設(shè)計(jì)方法的詳細(xì)內(nèi)容,更多關(guān)于C#仿QQ抽屜式窗體的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#實(shí)現(xiàn)讀取ini配置文件的內(nèi)容
INI就是擴(kuò)展名為"INI"的文件,其實(shí)他本身是個(gè)文本文件,可以用記事本打開,本文主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)讀取ini配置文件內(nèi)容的方法,需要的小伙伴可以了解下2023-12-12Unity實(shí)現(xiàn)鼠標(biāo)雙擊與長按的檢測
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)鼠標(biāo)雙擊與長按的檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02