• C#鼠标拖拽无边框浮动窗体的方法:窗体控制


    目录

    (1)ReleaseCapture函数

    (2)SendMessage函数

    (3)实例

    1.Resources.Designer.cs

    2.Form1.Designer.cs

    3.Form1.cs


            一般情况下,在标题栏中按住鼠标左键不放即可实现拖动操作。

            当做浮动窗体时,如果包含窗体边框,那么界面给使用者的感觉将很不友好,因此浮动窗体没有边框,但对于这种没有边框的窗体,该如何进行拖放操作呢?

            主要用Windows的两个API函数,即ReleaseCapture和SendMessage来实现:

    (1)ReleaseCapture函数

            该函数用来释放被当前线程中某个窗口捕获的光标。语法格式如下:

    1. [DllImport("user32.dll")]
    2. public static extern bool ReleaseCapture();

    (2)SendMessage函数

            该函数用来向指定的窗体发送Windows消息。语法格式如下:

    1. [DllImport("user32.dll")]
    2. public static extern bool SendMessage(IntPtr hwdn,int wMsg,int mParam,int lParam);

    (3)实例

             本实例鼠标落于窗体上,在UP之前,随意拖拽窗体到任意位置。

    1.Resources.Designer.cs

    1. //------------------------------------------------------------------------------
    2. //
    3. // 此代码由工具生成。
    4. // 运行时版本:4.0.30319.42000
    5. //
    6. // 对此文件的更改可能会导致不正确的行为,并且如果
    7. // 重新生成代码,这些更改将会丢失。
    8. //
    9. //------------------------------------------------------------------------------
    10. namespace _198.Properties {
    11. using System;
    12. ///
    13. /// 一个强类型的资源类,用于查找本地化的字符串等。
    14. ///
    15. // 此类是由 StronglyTypedResourceBuilder
    16. // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
    17. // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
    18. // (以 /str 作为命令选项),或重新生成 VS 项目。
    19. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
    20. [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    21. [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    22. internal class Resources {
    23. private static global::System.Resources.ResourceManager resourceMan;
    24. private static global::System.Globalization.CultureInfo resourceCulture;
    25. [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
    26. internal Resources() {
    27. }
    28. ///
    29. /// 返回此类使用的缓存的 ResourceManager 实例。
    30. ///
    31. [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
    32. internal static global::System.Resources.ResourceManager ResourceManager {
    33. get {
    34. if (object.ReferenceEquals(resourceMan, null)) {
    35. global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("_198.Properties.Resources", typeof(Resources).Assembly);
    36. resourceMan = temp;
    37. }
    38. return resourceMan;
    39. }
    40. }
    41. ///
    42. /// 重写当前线程的 CurrentUICulture 属性,对
    43. /// 使用此强类型资源类的所有资源查找执行重写。
    44. ///
    45. [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
    46. internal static global::System.Globalization.CultureInfo Culture {
    47. get {
    48. return resourceCulture;
    49. }
    50. set {
    51. resourceCulture = value;
    52. }
    53. }
    54. ///
    55. /// 查找 System.Drawing.Bitmap 类型的本地化资源。
    56. ///
    57. internal static System.Drawing.Bitmap _04 {
    58. get {
    59. object obj = ResourceManager.GetObject("_04", resourceCulture);
    60. return ((System.Drawing.Bitmap)(obj));
    61. }
    62. }
    63. }
    64. }

    2.Form1.Designer.cs

    1. namespace _198
    2. {
    3. partial class Form1
    4. {
    5. ///
    6. /// Required designer variable.
    7. ///
    8. private System.ComponentModel.IContainer components = null;
    9. ///
    10. /// Clean up any resources being used.
    11. ///
    12. /// true if managed resources should be disposed; otherwise, false.
    13. protected override void Dispose(bool disposing)
    14. {
    15. if (disposing && (components != null))
    16. {
    17. components.Dispose();
    18. }
    19. base.Dispose(disposing);
    20. }
    21. #region Windows Form Designer generated code
    22. ///
    23. /// Required method for Designer support - do not modify
    24. /// the contents of this method with the code editor.
    25. ///
    26. private void InitializeComponent()
    27. {
    28. SuspendLayout();
    29. //
    30. // Form1
    31. //
    32. AutoScaleDimensions = new SizeF(7F, 17F);
    33. AutoScaleMode = AutoScaleMode.Font;
    34. BackgroundImage = Properties.Resources._04;
    35. BackgroundImageLayout = ImageLayout.Stretch;
    36. ClientSize = new Size(311, 218);
    37. FormBorderStyle = FormBorderStyle.None;
    38. Name = "Form1";
    39. Text = "Form1";
    40. MouseDown += Form1_MouseDown;
    41. ResumeLayout(false);
    42. }
    43. #endregion
    44. }
    45. }

    3.Form1.cs

             实例中,使用的API函数 [DllImport("user32.dll")]会提示CA1401和SYSLIB1054的错误消息提示,不要理睬,否则生成的窗体不能实现拖拽。按道理讲,按照提示修改更新为最新的API函数,P/INVOKE应该是能正常工作的,可是我没有心情去调试它了,感兴趣的网友见到后,可以深入研究并攻克它,趟有结果,还请回复。我用的框架是.NET8.0。

    1. // 拖拽无边框浮动窗体
    2. using System.Runtime.InteropServices;
    3. namespace _198
    4. {
    5. public partial class Form1 : Form
    6. {
    7. #region 本程序中用到的API函数
    8. [DllImport("user32.dll")]
    9. public static extern bool ReleaseCapture();//用来释放被当前线程中某个窗口捕获的光标
    10. [DllImport("user32.dll")]
    11. public static extern bool SendMessage(IntPtr hwdn, int wMsg, int mParam, int lParam);//向指定的窗体发送Windows消息
    12. #endregion
    13. #region 本程序中需要声明的变量
    14. public const int WM_SYSCOMMAND = 0x0112; //该变量表示将向Windows发送的消息类型
    15. public const int SC_MOVE = 0xF010; //该变量表示发送消息的附加消息
    16. public const int HTCAPTION = 0x0002; //该变量表示发送消息的附加消息
    17. #endregion
    18. public Form1()
    19. {
    20. InitializeComponent();
    21. }
    22. ///
    23. /// 鼠标落在窗体上,随意拖拽
    24. ///
    25. private void Form1_MouseDown(object sender, MouseEventArgs e)
    26. {
    27. ReleaseCapture(); //用来释放被当前线程中某个窗口捕获的光标
    28. SendMessage(Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); //向Windows发送拖动窗体的消息
    29. }
    30. }
    31. }

  • 相关阅读:
    多线程之线程安全集合类
    实践总结 3 种前端部署后页面检测版本的方法
    郑州大学编译原理实验四LR(0)分析算法JAVA
    pandas连接oracle数据库并拉取表中数据到dataframe中、筛选当前时间(sysdate)到一分钟之前的所有数据(筛选一分钟之内的数据)
    【Shell 脚本速成】02、Shell 变量详解
    套接字的多种可选项
    Mac热门软件推荐Paste mac 中文激活版 剪切板工具
    Matplotlib傻瓜指南
    LeetCode每日一题(2109. Adding Spaces to a String)
    让你随时随地访问金蝶云星空企业版v8.0,内网穿透轻松实现远程办公!
  • 原文地址:https://blog.csdn.net/wenchm/article/details/138194672