【问题标题】:Move window without border移动无边框窗口
【发布时间】:2011-01-02 04:29:27
【问题描述】:

如何移动没有边框的窗口。应用程序上没有空白空间,可用的只有一个网络浏览器和一个菜单条。我希望用户能够通过拖动菜单条来移动窗口。我该如何编码?我尝试了一些我在网上找到的代码块,但它们都不起作用。

【问题讨论】:

  • 可能是因为应用程序(或用户)无法区分单击MenuStrip 是为了移动应用程序还是打开菜单。窗户有边框是有原因的——重新考虑你的设计。

标签: c# move menustrip borderless


【解决方案1】:

This Code Project 文章应该可以帮助您完成此任务。我自己用过这个没有问题。这是它的要点:

public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;

[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();

private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{     
    if (e.Button == MouseButtons.Left)
    {
        ReleaseCapture();
        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
    }
}

这基本上会“欺骗”窗口管理器,使其认为它正在抓取 winform 的标题栏。

要将其应用于您的项目,只需使用 MenuStrip 中的 MouseDown 事件。

【讨论】:

  • 这真的很棒。您可以在任何 MouseDown 事件中添加方法的内容,例如图片...
  • 这简直太容易了 :) 谢谢!
【解决方案2】:

这是 .Net 方式

    private bool dragging = false;
    private Point dragCursorPoint;
    private Point dragFormPoint;

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        dragging = true;
        dragCursorPoint = Cursor.Position;
        dragFormPoint = this.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (dragging)
        {
            Point dif = Point.Subtract(Cursor.Position, new Size(dragCursorPoint));
            this.Location = Point.Add(dragFormPoint, new Size(dif));
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        dragging = false;
    }

就是这样。

【讨论】:

    【解决方案3】:

    只需将起点放入二维数组中,如下所示:

    public partial class mainForm : Form
    {
        //Global variables for Moving a Borderless Form
        private bool dragging = false;
        private Point startPoint = new Point(0, 0); 
    
    
        public mainForm()
        {
            InitializeComponent();
        }
    
        private void mainForm_MouseDown(object sender, MouseEventArgs e)
        {
            dragging = true;
            startPoint = new Point(e.X, e.Y);
    
        }
    
        private void mainForm_MouseUp(object sender, MouseEventArgs e)
        {
            dragging = false;
        }
    
        private void mainForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (dragging)
            {
                Point p = PointToScreen(e.Location);
                Location = new Point(p.X - this.startPoint.X, p.Y - this.startPoint.Y);
    
            }
    
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以伪造您的菜单条,例如使用带有标签的面板。然后你可以手动处理:当用户点击标签时,会打开一个弹出菜单,当用户拖动标签时,窗口会移动。但我建议不要使用这种变通方法,因为这不是标准的 GUI 行为,您可能会让您的用户感到困惑。

      【讨论】:

      • 请不要这样做。它不仅是一个完全非标准的用户界面,而且仍然不能解决点击的解释问题。请记住,“拖动”发生在 点击发生之后。单击应该打开菜单,还是应该将其解释为开始拖动?时间机器尚未完善。
      • @Cody 释放鼠标按钮时会发生单击。在 Windows 资源管理器的文件夹窗格中查看它是如何工作的:如果您单击一个文件夹,它会在右侧窗格中打开,但如果您拖动一个文件夹,它不会打开,它只是被拖动。
      • 明白。但请理解,您定义的“单击”事件与 Windows 中菜单控件的解释方式不同。只要我在 Windows 中的任何应用程序的任何菜单上按下鼠标按钮,菜单就会下拉。释放鼠标按钮时不会发生这种情况。我认为重要的是要指出,需要特别仔细考虑显着改变预期行为的设计决策。
      【解决方案5】:

      我没试过,但是如果你能处理菜单栏上的“OnMouseDown”和“onMouseUp”事件:

      • 鼠标按下时 - 根据鼠标移动移动窗口
      • 在鼠标向上或鼠标移出时停止跟踪鼠标移动

      【讨论】:

        【解决方案6】:

        如果您使用的是面板,则必须将其添加到

        YourForm.Designer.cs

        this.panel1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseDown);
        

        这个在

        YourForm.cs

         public const int WM_NCLBUTTONDOWN = 0xA1;
                public const int HT_CAPTION = 0x2;
        
                [DllImportAttribute("user32.dll")]
                public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
                [DllImportAttribute("user32.dll")]
                public static extern bool ReleaseCapture();
        
                private void panel1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        ReleaseCapture();
                        SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
                    }
                }
        

        【讨论】:

          【解决方案7】:

          Mbithi Kioko 是在正确的轨道上,但我会这样做。

              bool dragging = false;
              int xOffset = 0;
              int yOffset = 0;
          
              private void Form1_MouseDown(object sender, MouseEventArgs e)
              {
                  dragging = true;
          
                  xOffset = Cursor.Position.X - this.Location.X;
                  yOffset = Cursor.Position.Y - this.Location.Y;
              }
          
              private void Form1_MouseMove(object sender, MouseEventArgs e)
              {
                  if (dragging)
                  {
                      this.Location = new Point(Cursor.Position.X - xOffset, Cursor.Position.Y - yOffset);
                      this.Update();
                  }
              }
          
              private void Form1_MouseUp(object sender, MouseEventArgs e)
              {
                  dragging = false;
              }
          

          【讨论】:

            【解决方案8】:

            我不得不使用System.Runtime.InteropServices.DllImportAttribute - 只是想我会发表评论并让大家知道。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-05-07
              • 1970-01-01
              • 1970-01-01
              • 2022-01-19
              • 2018-04-18
              相关资源
              最近更新 更多