第一种采用,需注意窗体上的控件是否把窗体覆盖了。。。MouseDown、MouseMove、MouseUp事件应该是鼠标所处位置最顶层的控件的事件
在窗体的类中声明两个变量
private Point mouseOffset; //记录鼠标指针的坐标
private bool isMouseDown = false; //记录鼠标按键是否按下

创建该窗体 MouseDown、MouseMove、MouseUp事件的相应处理程序
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
    int xOffset;
    int yOffset;
    if (e.Button == MouseButtons.Left) 
    {
        xOffset = -e.X ;
        yOffset = -e.Y ;
        mouseOffset = new Point(xOffset, yOffset);
        isMouseDown = true;
    }
}

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

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

第二种调用API 未验证
        using System.Runtime.InteropServices;

[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 Form1_MouseDown(object sender, MouseEventArgs e)
        {
            ReleaseCapture();
            SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
        }

第三种未验证 
        private bool isMouseDown = false;
        private Point FormLocation; //form的location
        private Point mouseOffset; //鼠标的按下位置
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();

[DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
        private const int SC_MOVE = 0xF010;//移动信息
        private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息
        private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息
        private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息
        private const int SC_MAXIMIZE = 0xF030;//最大化信息
        private const int SC_MINIMIZE = 0xF020;//最小化信息

protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_SYSCOMMAND:
                    if (m.WParam == (IntPtr)SC_MAXIMIZE)
                    {
                        m.WParam = (IntPtr)SC_MINIMIZE;
                    }
                    break;
                case WM_NCHITTEST: //如果鼠标移动或单击
                    base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息
                    if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT
                    {
                        m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION
                        return;//直接返回退出方法
                    }
                    break;
            }
            base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理
        }

最后一种,最简单:

protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0201)
{
m.Msg = 0x00A1;//更改消息为非客户区按下鼠标
m.LParam = IntPtr.Zero;
m.WParam = new IntPtr(2);//鼠标放在标题栏内
}
base.WndProc(ref m);
}

总结:这三种都可以实现窗体移动,但是发现光移动,没有重绘了,不知道怎么解决这个问题

C#移动无标题栏窗体的四种代码的更多相关文章

  1. C# 移动无标题栏窗体的几种方法

    第一种,手工移动. 该方法根据鼠标位置实现窗体的移动.网上有很多相关的例子,这里不再多讲. 第二种,调用系统API原理:是当鼠标左键按下时,让系统认为是在标题栏按下的.这里我们用到了winapi里的W ...

  2. 4种方法实现C#无标题栏窗体的移动

    首先C#无标题栏窗体的实现代码 在load时实现 无工具栏+无窗口标题 private void Form1_Load(object sender, EventArgs e) { this.Contr ...

  3. C#之移动无标题栏窗体功能的实现!...

    为实现移动无标题栏窗体的功能,我从网上寻找.整理了以下资料,以备不时之需: 该方法适用于有标题栏和无标题栏窗体,适用于窗体内控件,当然 Form 也不例外, 只须添加 MouseDown.MouseM ...

  4. C#实现无标题栏窗体点击任务栏图标正常最小化或还原的解决方法

    对于无标题栏窗体,也就是FormBorderStyle等于System.Windows.Forms.FormBorderStyle.None的窗体,点击任务栏图标的时候,是不能象标准窗体那样最小化或还 ...

  5. Delphi中动态创建窗体有四种方式

    Delphi中动态创建窗体有四种方式,最好的方式如下: 比如在第一个窗体中调用每二个,主为第一个,第二个设为动态创建 Uses Unit2; //引用单元文件 procedure TForm1.But ...

  6. C# 使用委托实现多线程调用窗体的四种方式

    1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口 ...

  7. C# 使用委托实现多线程调用窗体的四种方式(转)

    1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口 ...

  8. C# 实现无标题栏窗体点击任务栏图标正常最小化或还原的解决方法

    /// <summary> /// 实现窗体的最小化 /// </summary> protected override CreateParams CreateParams { ...

  9. java中的四种代码块

    一.普通代码块 直接在一个方法中出现的{}就称为普通代码块,例子程序如下: public class CodeDemo01{ public static void main(String[] args ...

随机推荐

  1. Spring表达式语言 之 5.4在Bean定义中使用EL(拾伍)

    5.4.1  xml风格的配置 SpEL支持在Bean定义时注入,默认使用"#{SpEL表达式}"表示,其中"#root"根对象默认可以认为是Applicati ...

  2. selenium+python笔记6

    #!/usr/bin/env python # -*- coding: utf-8 -*- """ @desc: 将登陆动作封装成function "" ...

  3. 无法启动T-SQL 调试

    问题详情 解决办法 1.要在服务器本机,不要远程 2.用实例名,不要用.或者local 3.以Windows身份验证的administrator或者sqlserver身份验证的sa登录

  4. XML中的非法字符转化成实体

    问题 如果XML有非法字符比如 "·",或者HTML标签<br/>.XML在解析的过程中就会出错.就无法正常解析,或者把xml反射成实体. 有些字符,像(<)这类 ...

  5. Java 之 I/O 系列 02 ——序列化(一)

    Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 一 序列化概述 序 ...

  6. 简单管理用户SESSION小记(个人观点,欢迎斧正)

    做了几年码农,记录下一般涉及到用户session管理的方法. 问题说明: a.用户如果点击退出时,可以获取用户动作,这样可以销毁session. b.用户直接关闭浏览器或者直接意外关机情况,无法获取用 ...

  7. Java如何将控制台上的结果保存到文件

    无论是二进制数据还是字符数据(文本数据),都可以用文件输出流java.io.FileOutputStream,以字节流的方式保存到指定文件. package test; import java.io. ...

  8. Eclipse如何设置代码提示功能

    Windows→Preference→XML→XML Files→Editor→Content Assist→Auto Activation→Prompt when these characters ...

  9. POJ 3660

    233333... Description: 就是说呢.牛是的实力室友大小之分的.然后呢.告诉你很多pair 表示任意两头牛之间的实力大小.按实力排序之后.问你一共有多少只牛的排名是确定了的. T_T ...

  10. laypage分页功能demo

    demo代码如下: <div id="view1"></div> <div id="page1"></div> ...