共用方式為


HOW TO:建立非矩形 Windows Form

以往,建立非矩形的表單是一項既耗時又需要高度勞力的程序,其中牽涉到 API 呼叫和龐大的程式設計工作。 然而現在的情況已經有所改變。

注意事項注意事項

這個程序需要硬體處理大量的圖形,因此,電腦會因記憶體和圖形卡而有不同的執行效能。 當應用程式包含自訂繪圖時,一定要在各種視訊卡上進行測試,以確保在為使用者部署前,具有令人滿意的效能。

建立非矩形表單的程序包含兩個項目:建立具有形狀的表單,以及為某些程式設計的邏輯編碼,讓表單可以移動和關閉。 第二個步驟是必要的,因為包含自訂形狀的表單沒有標題列,而且其中沒有繼承的功能,例如將表單在螢幕上四處移動和關閉的能力。 因此,必須撰寫複寫這些功能的程式碼。 如需建立非矩形表單和非矩形控制項的詳細資訊,請參閱 HOW TO:建立具圖案的 Windows Form

非矩形表單的建立包含三個步驟:

  • 建立做為表單介面 (Surface) 的點陣圖 (實際上,您將從矩形「切出」想要的表單形狀)。

  • 建立 Windows 應用程式專案,設定它的屬性以消除標題列,然後使用點陣圖做為表單的背景。

  • 輸入重新建立標題列提供功能 (例如移動和關閉表單) 的程式碼。

注意事項注意事項

根據您目前使用的設定或版本,您所看到的對話方塊與功能表指令可能會與 [說明] 中描述的不同。 若要變更設定,請從 [工具] 功能表中選取 [匯入和匯出設定]。 如需詳細資訊,請參閱 使用設定

若要建立具有形狀的表單

  1. 以某一色彩建立非矩形的點陣圖,而背景使用另一個色彩以有所區別。 使用您慣用的任何繪圖程式。 繪製的形狀最終會成為您的表單,因此請確認將圖形畫得夠大以便使用。

    注意事項注意事項

    選擇容易記得的背景彩色,例如藍色,因為稍後這將會是重要的資訊。

  2. 在 Visual Studio 中建立新的 [Windows 應用程式] 專案。 如需詳細資訊,請參閱 HOW TO:建立新的 Windows Form 應用程式專案

  3. 在 [屬性] 視窗中:

    • FormBorderStyle 屬性設定成 None

      這個屬性會從表單移除標題列 (它也會移除標題列提供的功能,包括關閉表單和移動表單的能例。 但是這個缺點會在下列的程式碼中解決)。

    • 將表單的 BackgroundImage 屬性設定成先前建立的點陣圖檔。 不需要將檔案加入至專案系統;當您將檔案指定為背景影像時,就會自動完成這個動作。

      這個屬性將點陣圖影像設定成表單的背景 (當與下列指定的 TransparencyKey 屬性串聯使用時,這個屬性會定義表單的形狀)。

    • TransparencyKey 屬性設定成點陣圖檔的背景色彩。

      這個屬性會告知應用程式您要檢視表單的哪些部分。

      注意事項注意事項

      不管 TransparencyKey 屬性的設定為何,色彩深度設成大於 24 位元的顯示器可能會有顯示問題,表單的特定部分無法成為透明的。 若要避免這個問題,請確定顯示器在 [顯示] 控制台中的色彩深度設定小於 24 位元。 在開發具有這種透明效果的應用程式時,請記住您要讓使用者知道這個問題。

若要撰寫關閉表單的程式碼

  1. 在表單中加入一個 Button 控制項。 如需詳細資訊,請參閱 HOW TO:將控制項加入至 Windows Form

  2. 加入程式碼,讓使用者能夠叫用其 Close 方法以關閉表單。

    下列範例說明如何加入按一下即可關閉表單的按鈕。

    Private Sub Button1_Click(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles Button1.Click
       Me.Close()
    End Sub
    
    private void button1_Click(object sender, System.EventArgs e)
    {
       this.Close();
    }
    
    C# 注意事項C# 注意事項

    請務必加入程式碼以啟用事件處理常式。 使用下列範例的程式碼,此程式碼看起來像是這樣:

    this.Button1.Click += new System.EventHandler(this.button1_Click);
    

若要撰寫移動表單的程式碼 (選擇性)

  1. 建立拖曳就可移動表單的程序。 輸入與下列類似的程式碼,以建立新的 Point 物件。 在計算如何移動表單時,這會做為變數。 isMouseDown 欄位是用於追蹤使用者是否按住滑鼠按鍵。 表單應該只在按住滑鼠時移動。

    Private mouseOffset As Point
    Private isMouseDown As Boolean = False
    
    private Point mouseOffset;
    private bool isMouseDown = false;
    
  2. 為表單的 MouseDown 事件建立事件處理常式。 在處理常式中加入程式碼,讓使用者按一下表單任何一處,即可拖曳它。 如需建立事件處理常式的詳細資訊,請參閱 HOW TO:使用設計工具建立事件處理常式

    輸入與下列類似的程式碼,根據滑鼠指標的目前位置,將座標指定給 mouseOffset 變數。 在下列的程式碼中,請注意位移 (Offset) 位置是使用關於框線大小 (FrameBorderSize.Width) 和標題列高度 (CaptionHeight) 的系統資訊進行計算的。 測試位移時必須將這些情況納入考量,因為有些測量是使用工作區,而有些則是使用螢幕座標進行的。 因此,位移等於框線寬度加上標題高度,再加上表單工作區的位移。

    Private Sub Form1_MouseDown(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles MyBase.MouseDown
        Dim xOffset As Integer
        Dim yOffset As Integer
    
        If e.Button = MouseButtons.Left Then
            xOffset = -e.X - SystemInformation.FrameBorderSize.Width
            yOffset = -e.Y - SystemInformation.CaptionHeight - _
                    SystemInformation.FrameBorderSize.Height
            mouseOffset = New Point(xOffset, yOffset)
            isMouseDown = True
        End If
    End Sub
    
    private void Form1_MouseDown(object sender, 
        System.Windows.Forms.MouseEventArgs e)
    {
        int xOffset;
        int yOffset;
    
        if (e.Button == MouseButtons.Left) 
        {
            xOffset = -e.X - SystemInformation.FrameBorderSize.Width;
            yOffset = -e.Y - SystemInformation.CaptionHeight - 
                SystemInformation.FrameBorderSize.Height;
            mouseOffset = new Point(xOffset, yOffset);
            isMouseDown = true;
        }    
    }
    
    C# 注意事項C# 注意事項

    請務必加入程式碼以啟用事件處理常式。 使用下列範例的程式碼,此程式碼看起來像是這樣:

    this.MouseDown += new
       System.Windows.Forms.MouseEventHandler
       (this.Form1_MouseDown);
    
  3. 為表單的 MouseMove 事件建立事件處理常式。

    輸入與下列類似的程式碼。 當按下滑鼠左鍵並拖曳滑鼠時,表單的 Location 屬性會設定成新的位置。

    Private Sub Form1_MouseMove(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles MyBase.MouseMove
        If isMouseDown Then
            Dim mousePos As Point = Control.MousePosition
            mousePos.Offset(mouseOffset.X, mouseOffset.Y)
            Location = mousePos
        End If
    End Sub
    
    private void Form1_MouseMove(object sender, 
        System.Windows.Forms.MouseEventArgs e)
    {
        if (isMouseDown) 
        {
            Point mousePos = Control.MousePosition;
            mousePos.Offset(mouseOffset.X, mouseOffset.Y);
            Location = mousePos;
        }
    }
    
    C# 注意事項C# 注意事項

    請務必加入程式碼以啟用事件處理常式。 使用下列範例的程式碼,此程式碼看起來像是這樣:

    this.MouseMove += new
       System.Windows.Forms.MouseEventHandler
       (this.Form1_MouseMove);
    
  4. 為表單的 MouseUp 事件建立事件處理常式。 輸入與下列類似的程式碼。

    Private Sub Form1_MouseUp(ByVal sender As Object, _
        ByVal e As MouseEventArgs) Handles MyBase.MouseUp
        ' Changes the isMouseDown field so that the form does
        ' not move unless the user is pressing the left mouse button.
        If e.Button = MouseButtons.Left Then
            isMouseDown = False
        End If
    End Sub
    
    private void Form1_MouseUp(object sender, 
        System.Windows.Forms.MouseEventArgs e)
    {
        // Changes the isMouseDown field so that the form does
        // not move unless the user is pressing the left mouse button.
        if (e.Button == MouseButtons.Left) 
        {
            isMouseDown = false;
        }
    }
    
    C# 注意事項C# 注意事項

    請務必加入程式碼以啟用事件處理常式。 使用下列範例的程式碼,此程式碼看起來像是這樣:

    this.MouseUp += new
       System.Windows.Forms.MouseEventHandler
       (this.Form1_MouseUp);
    

請參閱

工作

HOW TO:建立具圖案的 Windows Form

HOW TO:建立透明的 Windows Form

參考

Windows Form 概觀