所謂“可拖動窗體”就是無需拖動標題欄就可以拖動的窗體,這在一個沒有標題欄的窗體上是一種非常有用的技術。關於這一方面的技巧,網上已經有很多介紹,但都不是很詳盡,有些實現也不夠簡潔。最主要的,這些介紹大多是大片大片的源代碼,很少講解;初學者學期來恐怕要費些力氣(我在學習這個技巧的時候就很痛苦)。在這裡,我對這個技巧進行了一個詳細的講解,相信各位初學者朋友可以學會如何制作可拖動窗體。
(注:本文期望的讀者是那些有一定用C#開發Windows程序基礎但暫時還不會制作可拖動窗體的朋友。)
首先,我們來復習一下一個Windows窗體的組成。請看這張圖:
--------------------------------------------------------------------------------
圖1 Windows窗體構成
--------------------------------------------------------------------------------
這是一個形式化的標准Windows窗體。首先,窗體的頂部是一個標題欄,其余的部分是窗體的主體,包圍在窗體主體外圍的是一個邊框,邊框內不就是我們放置控件或繪制圖形的用戶區。
圖中還標明了各種窗體構造元素的尺寸的獲得方法。對於用戶區,System.Windows.Forms.Form提供了實例屬性ClIEntSize,相信大家已經很熟悉了。而要想活棋一般性的窗體構造元素(如標題欄、邊框等)的尺寸,我們可以使用.NET類庫中提供的一個類:System.Windows.Forms.SystemInformation,這個類提供了一些靜態屬性如表示標題欄高度的CaptionHeight。有關SystemInformation類的信息可以在.NET SDK文檔目錄“.NET Framework SDK -> 參考 -> 類庫 -> System.Windows.Forms -> SystemInformation 類”處找到(注:這裡的超鏈接只在您安裝了.Net Framework 1.1簡體中文版並且安裝了配套文檔時才有效)。這是一個很有用的類,希望大家能夠記住它(可能您早就知道了,可我是才知道的-_-汗~~)。
接下來,我們來看看如何在在用戶區拖動鼠標時移動窗體。請看下面這張圖:
--------------------------------------------------------------------------------
圖2 窗體的移動
--------------------------------------------------------------------------------
我們來觀察鼠標在窗體內的位置和窗體的移動,很容易可以發現:在窗體被拖動的過程中,鼠標在窗體內的相對位置是始終不變的!那麼,我們只要檢測到鼠標在屏幕中的移動並修改窗體的位置就可以達到拖動窗體的目的!
我們知道,在鼠標消息/事件處理中,只能得到鼠標相對於窗體的位置。那麼,如何知道鼠標在屏幕中的位置呢?這裡又要提到一個類:System.Windows.Forms.Control類。也許你會很吃驚:這不是所有控件的基類麼?呵呵~是這樣di。不過,盡管是這樣,Control類卻沒有像其他廣泛使用的基類那樣被聲明為抽象類,而且它提供了一個靜態屬性:MousePosition,通過這個屬性可以得到鼠標相對於屏幕的位置。有關Control類的信息可以在.NET Framework文檔目錄“.NET Framework SDK -> 參考 -> 類庫 -> System.Windows.Forms -> Control 類”處找到(注:這裡的超鏈接只在您安裝了.Net Framework 1.1簡體中文版並且安裝了配套文檔時才有效)。
知道了如何獲取這些信息之後,制作移動窗體實際上就成了一個很簡單的問題了。基本過程是這樣的:首先,在鼠標(左鍵或一個你喜歡的鍵)按下時,記錄鼠標位置;由於在移動的過程中,鼠標的屏幕坐標發生變化但窗體相對坐標不變,我們可以推算出窗體位置的變化為(假設mousePosition具有System.Drawing.Point類型,表示鼠標在窗體中的相對坐標):
// 示例代碼1
Form.Top = Control.MousePosition.Y - mousePosition.Y;
Form.Left = Control.MousePosition.X - mousePosition.X;
這樣還不行,因為我們的mousePosition表示的是鼠標在窗體用戶區內的相對坐標,但在移動窗體的時候還要考慮窗體標題欄和邊框的尺寸。