閱讀323 返回首頁    go 阿裏雲 go 技術社區[雲棲]


C# 係統應用之無標題窗體移動的兩種方法

在做項目界麵設計中,常常為了美觀需要設置窗體屬性"FormBorderStyle"(窗體邊框和標題欄外觀)為None無標題窗口.此時隱藏標題的窗口怎樣實現移動呢?我根據自己的項目從自己完成的兩種方法進行講解.

一.MouseDown\MouseMove事件方法實現

第一種方法我采用常用的根據MouseDown、MouseMove、MouseUp、MouseLeave事件中鼠標移動的距離,窗體坐標也跟著移動的方法.具體代碼如下:

bool formMove = false;       //是否開始移動
int currentXPosition = 0;    //當前鼠標X坐標
int currentYPosition = 0;    //當前鼠標Y坐標
        
//函數:鼠標按下
private void WelcomeWindow_MouseDown(object sender, MouseEventArgs e)
{
    formMove = true;                       //鼠標按下開始移動
    currentXPosition = MousePosition.X;    //鼠標的X坐標為當前窗體左上角X坐標
    currentYPosition = MousePosition.Y;    //鼠標的Y坐標為當前窗體的左上角Y坐標
}
//函數:鼠標移動
private void WelcomeWindow_MouseMove(object sender, MouseEventArgs e)
{
    if (formMove)
    {
        //鼠標xy坐標確定窗體XY坐標 鼠標移動XY距離
        this.Left += MousePosition.X - currentXPosition;
        this.Top += MousePosition.Y - currentYPosition;
        //鼠標當前位置賦值
        currentXPosition = MousePosition.X;
        currentYPosition = MousePosition.Y;
    }
}
//函數:鼠標鬆開
private void WelcomeWindow_MouseUp(object sender, MouseEventArgs e)
{
    formMove = false;     //停止移動
}
//函數:鼠標離開
private void WelcomeWindow_MouseLeave(object sender, EventArgs e)
{
    //初始狀態
    currentXPosition = 0;
    currentYPosition = 0;
    formMove = false;
}

同時有的設置變量Point formPoint通過Offset和Location變換位置亦類似.但是第一種方法可能由於每次獲取鼠標坐標,移動時如果鼠標不在窗口位置會產生窗體總是向屏幕外移動的現象,因此推薦第二種調用API函數的方法.

二.調用API函數實現

第二種方法是采用API函數ReleaseCapture和SendMessage來實現的,ReleaseCapture函數從當前線程中窗口釋放鼠標捕獲,SendMessage函數的作用是調用一個窗口的窗口函數,將一條消息命令發給那個窗口.
SendMessage(
IntPtr hwnd,   //要接收消息的那個窗口的句柄
int wMsg,       //消息的標識符
int wParam,   //具體取決於發送的消息
int lParam      //具體取決於發送的消息
)

其中調用API函數需要引用命名空間System.Runtime.InteropServices.代碼中WM_SYSCOMMAND常量代表要向窗口發送消息,SC_MOVE常代表要向窗口發送移動的消息.代碼如下:

#region 鼠標移動操作
//該函數從當前線程中窗口釋放鼠標捕獲
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
        
//發送消息移動窗體
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
public const int WM_SYSCOMMAND = 0x0112;    //向窗口發送消息
public const int SC_MOVE = 0xF010;          //向窗口發送移動的消息
public const int HTCAPTION = 0x0002;

//鼠標位於窗體(底部位置)按下移動操作
private void EMSecure_MouseDown(object sender, MouseEventArgs e)
{
    ReleaseCapture();
    SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
#endregion

其中,EMSecure是對話框Form,當鼠標點擊到圖片或控件Panel時不會響應移動,所以對需要移動的控件也響應該API函數即可.如我的程序界麵Panel1位於窗體頂部,故也響應該移動事件,即panel1_MouseDown(object sender, MouseEventArgs e).運行結果如下圖所示,紅色部分可以實現移動(頂部為Panel控件):

提示如果是WPF可以響應Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){this.DragMove();}實現窗體移動.最後希望該文章對大家有所幫助,如果有錯誤或不足之處,請海涵.
(By:Eastmount 2014-3-7 夜2點 原創:
https://blog.csdn.net/eastmount)

最後更新:2017-04-03 12:55:32

  上一篇:go 經典動態規劃基礎題-三角形最大和問題
  下一篇:go android隱藏底部虛擬鍵Navigation Bar實現全屏