C# 移動無標題欄窗體的幾種方法


第一種,手工移動。

該方法根據鼠標位置實現窗體的移動。網上有很多相關的例子,這里不再多講。

第二種,調用系統API
原理:是當鼠標左鍵按下時,讓系統認為是在標題欄按下的。這里我們用到了winapi里的WM_LBUTTONDOWN(客戶區鼠標左鍵按下,值:0x0201)和WM_NCLBUTTONDOWN(非客戶區鼠標左鍵按下,值:0x00A1)及HTCAPTION(鼠標位置在標題欄,值:2,為什么是2,請參照https://msdn.microsoft.com/en-us/library/windows/desktop/ms645618(v=vs.85).aspx)這三個常量。

 

這里是采用 SendMessage這個函數,當鼠標左鍵在客戶區按下的時候,我們用這個函數發出一個鼠標左鍵在標題欄按下的消息來代替。該函數的原型為:

LRESULT SendMessage(      

    HWND hWnd,     UINT Msg,     WPARAM wParam,     LPARAM lParam );
我這們在C#中導入這個API:
        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr hWnd,int msg,int wparam,int lparam);
然后重寫鼠標事件:
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)//按下的是鼠標左鍵
            {
                Capture = false;//釋放鼠標,使能夠手動操作
                SendMessage(Handle, 0x00A1, 2, 0);//拖動窗體
            }
        }
說明:SendMessage(Handle, 0x00A1, 2, 0);
Handle為窗體的屬性,表示當前窗口句柄。0x00A1表示消息ID,這個為非客戶區域鼠標左鍵按下時的消息。2表示
鼠標在標題欄的空白位置。注意,在調用SendMessage之前,我們用Capture釋放鼠標。只要設置成false就可以了。這樣就可以實現在客戶區窗體的拖動了。

第三種,重寫 WndProc

這個方法是用來處理消息的,包括鼠標的各種消息。前一種方法中講到了非客戶區的鼠標消息,但我在msdn里找了半天,沒找到相關的非客戶區的鼠標事件。但WndProc里可以處理。

原理:將鼠標在客戶區按下的消息更改為在非客戶區的標題欄按下。

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x0201://鼠標左鍵按下的消息
                    m.Msg = 0x00A1;//更改消息為非客戶區按下鼠標
                    m.LParam = IntPtr.Zero;//默認值
                    m.WParam = new IntPtr(2);//鼠標放在標題欄內
                    break;
            }
            base.WndProc(ref m);
        }

小結

除了第一種方法外,后兩種都是用了模擬鼠標在標題的動作。這里我是實現了在非標題欄位置移動窗體。
由此我們可以引申開來,我們還可以模擬標題欄圖標、關閉、最大化、最小化等操作。這樣在一些無標題欄窗體中使用是很方便的。大家不仿嘗試一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM