C#模擬實現(xiàn)QQ窗體功能
案例簡述
通過C#使用類似QQ窗體的功能,當(dāng)窗體放置到屏幕的邊緣,可以將窗體隱藏,當(dāng)鼠標(biāo)再次放置到屏幕邊緣時,窗體可再次顯示。
預(yù)備知識導(dǎo)圖
功能結(jié)構(gòu)
由于本案例主要通過窗體和鼠標(biāo)位置句柄的比對,以及判斷窗體在屏幕的位置,進(jìn)行窗體的移動和隱藏。窗體的隱藏通過時間控件循環(huán)。涉及的功能如下
- 獲取當(dāng)前鼠標(biāo)位置的句柄
- 獲取當(dāng)前窗體的句柄
- 比對鼠標(biāo)位置所在控件的句柄和窗體句柄,進(jìn)行窗體的移動
- 判斷當(dāng)前窗體所在屏幕的位置以及比對鼠標(biāo)位置和窗體的句柄是否一致,進(jìn)行隱藏
關(guān)鍵代碼
//利用C#中Cursor.Position屬性和Point結(jié)構(gòu) Point CPoint;//定義鼠標(biāo)的坐標(biāo) CPoint = new Point(Cursor.Position.X,Cursr.Position.Y); /* int a,b; a= CPoint.X;//鼠標(biāo)坐標(biāo)的X值 b= CPoint.Y;//鼠標(biāo)坐標(biāo)的Y值 */ //在創(chuàng)建獲取鼠標(biāo)下可視化控件句柄方法前,需要調(diào)用windows系統(tǒng)api函數(shù)user32.dll。 #region API聲明 //獲取當(dāng)前鼠標(biāo)下可視化控件的句柄 [DllImport("user32.dll")] public static extern int WindowFromPoint(int xPoint, int yPoint); //獲取指定句柄的父級句柄 [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] public static extern IntPtr GetParent(IntPtr hWnd); //獲取屏幕的大小 [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")] private static extern int GetSystemMetrics(int mVal); #endregion #region 獲取當(dāng)前鼠標(biāo)下可視化控件的句柄 /// <summary> /// 獲取當(dāng)前鼠標(biāo)下可視化控件的句柄 /// </summary> /// <param x="int">當(dāng)前鼠標(biāo)的X坐標(biāo)</param> /// <param y="int">當(dāng)前鼠標(biāo)的Y坐標(biāo)</param> public IntPtr FormNameAt(int x, int y) { IntPtr Tem_hWnd;//設(shè)置存儲句柄的變量 Tem_Handle = (IntPtr)(WindowFromPoint(x, y));//獲取當(dāng)前鼠標(biāo)下可視化控件的句柄 Tem_hWnd = Tem_Handle;//記錄原始句柄 while (Tem_hWnd != ((IntPtr)0))//遍歷該句柄的父級句柄 { Tem_Handle = Tem_hWnd;//記錄當(dāng)前句柄 Tem_hWnd = GetParent(Tem_hWnd);//獲取父級句柄 } return Tem_Handle;//返回最底層的父級句柄 } #endregion
知識點分析
C#基礎(chǔ)知識
IntPtr:表示一個帶符號整數(shù),其中位寬度與指針相同。即用來表示指針或句柄、它是一個平臺特定類型,另外關(guān)于IntPtr(0)作用等同于IntPtr.Zero,在MSDN的介紹如下
此字段的值不等效于 null。 使用此字段可以有效地確定 的 IntPtr 實例是否已設(shè)置為非零值。
例如,假設(shè)變量 ip 是 的 IntPtr實例。 可以通過將它與構(gòu)造函數(shù)返回的值進(jìn)行比較來確定它是否已設(shè)置,例如:“ if ip != new IntPtr(0)… ”。 但是,調(diào)用構(gòu)造函數(shù)來獲取未初始化的指針效率低下。 最好對“” if ip != IntPtr.Zero… 或“”“ if !IntPtr.Zero.Equals(ip)… 進(jìn)行編碼。
Point:常用的方法為保存鼠標(biāo)的坐標(biāo),MSDN介紹如下:
提供有序的 x 坐標(biāo)和 y 坐標(biāo)整數(shù)對,該坐標(biāo)對在二維平面中定義一個點。
DIIImport:命名空間為System.Runtime.InteropServices,作用是提供非托管DLL導(dǎo)出的函數(shù)的必要調(diào)用信息,比如windows系統(tǒng)的API函數(shù)。在調(diào)用時,需要提供包含入口點的dll名稱。如[DllImport(“user32.dll”)]。用 DllImport 屬性修飾的方法必須具有 extern 修飾符
另外對于DIIImport有五個命名參數(shù),詳細(xì)描述如下:
命名參數(shù)名稱 | 描述 | 說明 |
---|---|---|
CallingConvention | 參數(shù)指示入口點的調(diào)用約定。如果未指CallingConvention,則使用默認(rèn)值 | CallingConvention.Winapi |
CharSet | 用在入口點中的字符集。如果未指定 CharSet,則使用默認(rèn)值 | CharSet.Auto |
EntryPoint | 給出 dll 中入口點的名稱。如果未指定 EntryPoint,則使用方法本身的名稱 | |
ExactSpelling | 指示 EntryPoint 是否必須與指示的入口點的拼寫完全匹配。如果未指定 ExactSpelling,則使用默認(rèn)值 false | |
PreserveSig | 方法的簽名應(yīng)當(dāng)被保留還是被轉(zhuǎn)換。當(dāng)簽名被轉(zhuǎn)換時,它被轉(zhuǎn)換為一個具有 HRESULT返回值和該返回值的一個名為 retval 的附加輸出參數(shù)的簽名。如果未指定 PreserveSig,則使用默認(rèn)值 true。 | |
SetLastError | 方法是否保留 Win32"上一錯誤"。如果未指定 SetLastError,則使用默認(rèn)值 false。 |
Screen:表示單個系統(tǒng)上的一個或多個顯示設(shè)備。本案例用到的地方為獲取屏幕邊界
this.Height=Screen.AllScreens[0].Bounds.Height;其他常用的方法是將軟件中的多個窗體,在主屏幕運行,但是把各個窗體(坐標(biāo))移動到各個擴(kuò)展屏幕位置。
Windows系統(tǒng)知識
句柄:以下摘自百度百科
用來標(biāo)識對象或者項目的標(biāo)識符,可以用來描述窗體、文件等,值得注意的是句柄不能是常量
Windows之所以要設(shè)立句柄,根本上源于內(nèi)存管理機(jī)制的問題,即虛擬地址。簡而言之?dāng)?shù)據(jù)的地址需要變動,變動以后就需要有人來記錄、管理變動,因此系統(tǒng)用句柄來記載數(shù)據(jù)地址的變更。在程序設(shè)計中,句柄是一種特殊的智能指針,當(dāng)一個應(yīng)用程序要引用其他系統(tǒng)(如數(shù)據(jù)庫、操作系統(tǒng))所管理的內(nèi)存塊或?qū)ο髸r,就要使用句柄
在本案例中主要用于記錄當(dāng)前鼠標(biāo)位置和窗體的標(biāo)簽。
**user32.dll:**以下摘自百度百科
user32.dll是Windows用戶界面相關(guān)應(yīng)用程序接口,用于包括Windows處理,基本用戶界面等特性,如創(chuàng)建窗口和發(fā)送消息。
在C#程序開發(fā)中,在基于windows系統(tǒng)開發(fā)運行時,需要調(diào)用windows系統(tǒng)相關(guān)應(yīng)用程序,所以需要user32.dll接口內(nèi)的方法實現(xiàn)相關(guān)功能,對應(yīng)的也包括kernel32.dll。user32.dll接口的方法過多,這里不一一介紹。
控件和組件
**事件e:**本文暫不討論事件的原理機(jī)制,只討論控件觸發(fā)的事件。其實在進(jìn)行控件的事件觸發(fā)時,會有兩個參數(shù)
(object sender, EventArgs e)
sender是事件源,表示觸發(fā)事件的那個組件,比如說你按下按鈕,那么sender就是按鈕
EventArgs是事件參數(shù),比如說你用鼠標(biāo)點擊窗體,那么EventArgs是會包含點擊的位置等等,它用來輔助你處理事件。
到此這篇關(guān)于C#模擬實現(xiàn)QQ窗體功能的文章就介紹到這了,更多相關(guān)C# QQ窗體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過容器擴(kuò)展屬性IExtenderProvider實現(xiàn)WinForm通用數(shù)據(jù)驗證組件
這篇文章介紹了通過容器擴(kuò)展屬性IExtenderProvider實現(xiàn)WinForm通用數(shù)據(jù)驗證組件的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12學(xué)習(xí)Winform分組類控件(Panel、groupBox、TabControl)
這篇文章主要和大家一起學(xué)習(xí)Winform分組類控件,包括容器控件(Panel),分組框控件(groupBox)和選項卡控件(TabControl)等控件,感興趣的小伙伴們可以參考一下2016-05-05c#利用Excel直接讀取數(shù)據(jù)到DataGridView
這個例子的功能是c#讀取excel文件,大家可以參考使用2013-11-11