移动无标题(边框)窗体

来源:互联网 发布:mysql的截取函数怎么用 编辑:程序博客网 时间:2024/06/08 06:10
 

移动无标题窗体很麻烦很麻烦,要不断重画窗体。这样有可能造成窗体刷新慢的问题,同时也会消耗很多系统资源。首先介绍一下常规的方法:

//在窗体的类中声明两个变量

private Point mouseOffset; //记录鼠标指针的坐标
private bool isMouseDown = false; //记录鼠标按键是否按下

//创建该窗体 MouseDown事件的相应处理程序,注示部分为坐标的补偿

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;
    }
}

//创建该窗体的 MouseMove事件的相应处理程序

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;
    }
}

//创建该窗体的MouseUp事件的相应处理程序

private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
    // 修改鼠标状态isMouseDown的值
    // 确保只有鼠标左键按下并移动时,才移动窗体
    if (e.Button == MouseButtons.Left) 
    {
        isMouseDown = false;
    }
}

今天无意间发现了一个很简单的代码,这个方法调用了系统API
在Program.cs中存在如下代码:

        [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;

这里作一些说明:user32.dll文件的作用是Windows用户界面相关应用程序接口,用于包括Windows处理,基本用户界面等特性,如创建窗口和发送消息。它可以帮助我在实现界面的一些操作。ReleaseCapture()的作用是从当前线程中的窗口释放鼠标捕获,并恢复通常的鼠标输入处理。捕获鼠标的窗口接收所有的鼠标输入(无论光标的位置在哪里),除非点击鼠标键时,光标热点在另一个线程的窗口中。如果函数调用成功,返回非零值;如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetlastError函数。很明显,它可以帮助我们得到鼠标的坐标。SendMessage()将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。
然后在想要实现这样功能的窗体上打入如下代码:

private void frmInputPsd_MouseDown(object sender, MouseEventArgs e)
         {
            //如果鼠标指针在标题栏范围内并且按下了鼠标左键,则触发移动标题栏方法
            if (e.Button == MouseButtons.Left && e.Y <= 25)
             {
                Program.ReleaseCapture();
                Program.SendMessage(this.Handle, Program.WM_SYSCOMMAND, Program.SC_MOVE + Program.HTCAPTION, 0);
            }
        }

这种方法实现无标题的窗体移动代码更少,结构也更清晰!

原创粉丝点击