Make Borderless Form Moveable

Borderless Form Moveable on CSharp

Nghĩ hoài không biết đặt tiêu đề tiếng Việt cho bài viết như thế nào cho dễ hiểu nên tôi để nguyên là tiếng Anh.

Đúng như tên tiêu đề, chúng ta sẽ tạo 1 Windows Form trên C# ở dạng không có Border, tức là giống như giao diện MetroUI phẳng và có thể di chuyển cửa sổ đó dễ dàng như có Border vậy.

Hiển thị tốt trên Windows XP, Windows 7 mà không cần dùng thư viện hỗ trợ nào khác.

Có thể một vài bạn sẽ không hiểu Border là gì, Border trong Windows Form là phần viền bao ngoài cửa sổ ứng dụng, chứa tiêu đề và các nút đóng - phóng to - thu nhỏ cửa sổ.

Windows Form Border

Tôi sẽ demo 1 ví dụ hoàn chỉnh.

Bước 1. Tạo Form không có Border

Các bạn cứ tạo fom như bình thường, phần Properties có chỉnh sửa một chút:

Tạo Form

Chúng ta được 1 form không có border như hình trên.

Bước 2. Tạo 1 vùng để có thể di chuyển cửa sổ

Tạo vùng này thì tôi dùng đối tượng Panel, muốn vùng có thể di chuyển cửa sổ như thế nào thì bạn vẽ ra như vậy.

Ở đây tôi để vùng đó ở trên cùng của cửa sổ cho quen thuộc.

Tạo Panel

Phần này sẽ nhận biết hành động MouseDown để xử lý việc di chuyển cửa sổ.

Nếu bạn muốn di chuyển cửa sổ ở bất kỳ vị trí nào thì không cần tạo Panel mà dùng ngay đối tượng Form.

Bước 3. Tạo Button trong suốt

Tất nhiên khi tạo 1 form thì phải có nút phóng to hoặc thu nhỏ hoặc nút đóng cửa sổ hoặc gì đó mà các bạn muốn. :D

Ở đây tôi làm nút đóng và ẩn cửa sổ.

Tạo button trong suốt

Vậy là xong phần thiết kế giao diện, tiếp theo là phần mã nguồn.

Cần add thêm thư viện System.Runtime.InteropServices vào đầu chương trình.

Đưa đoạn mã này vào thân chương trình, đoạn mã này có nhiệm vụ xử lý sự kiện MouseDown với đối tượng, ở đây là đối tượng Panel.

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private void panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}

Toàn bộ mã nguồn của Demo:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//Handle panel
using System.Runtime.InteropServices;
//Open link
using System.Diagnostics;

namespace Test_CSharp
{
    public partial class Form1 : Form
    {
        //=========Panel Moveable======================
        public const int WM_NCLBUTTONDOWN = 0xA1;
        public const int HT_CAPTION = 0x2;

        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();

        private void panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }
        //==============================================

        public Form1()
        {
            InitializeComponent();
            //Add Event Handler
            this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
        }

        private void btnMinimizeForm_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void btnCloseForm_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void linkText_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            /*
            string url;
            if (e.Link.LinkData != null)
                url = e.Link.LinkData.ToString();
            else
                url = linkText.Text.Substring(e.Link.Start, e.Link.Length);

            if (!url.Contains("://"))
                url = "http://" + url;

            ProcessStartInfo si = new ProcessStartInfo(url);
            Process.Start(si);
            linkText.LinkVisited = true;
            */
        }
    }
}

Chương trình sau khi biên dịch:

Kết quả

Enjoy!