如何使窗口窗体在长时间单击 C# 时移动



>我在 C# 中有一个 Windows 窗体,即使没有"X"顶栏,它看起来也是一个孤独的按钮。我把它做成只是一个按钮,我希望当我长时间触摸按钮时,我将能够在屏幕上移动它。

当我触摸窗口表单背景时,我成功地做到了这一点,我可以移动它,但我希望它在触摸按钮时发生。

在互联网上查看后,我编写了这段代码,但我不知道在 moveApp() mehtod 上写什么。

这是我的代码:

namespace Print_My_Screen
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();       
       }
       private void PrintScreen()
       {
         Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
         Graphics graphics = Graphics.FromImage(printscreen as Image);
         graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
         string subPath = @"C:PrintMyScreen";
         bool exists = System.IO.Directory.Exists(subPath);
         if (!exists)
            System.IO.Directory.CreateDirectory(subPath);
         printscreen.Save(@"C:PrintMyScreenprintscreen.png", ImageFormat.Png);
         printIt();
         MessageBox.Show("Your screen has been printed successfully","",MessageBoxButtons.OK,MessageBoxIcon.Information);
      }
      private void button1_Click(object sender, EventArgs e)
      {
         PrintScreen();
      }
      private void printIt()
      {
        PrintDocument pd = new PrintDocument();
        // pd.PrintPage += PrintPage;
        pd.PrintPage += (sender, args) =>
        {
            System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:PrintMyScreenprintscreen.png");
            img.RotateFlip(RotateFlipType.Rotate90FlipXY);
            args.Graphics.DrawImage(img, args.MarginBounds);
        };
        pd.Print();
      }
      private void PrintPage(object o, PrintPageEventArgs e)
      {
        System.Drawing.Image img = System.Drawing.Image.FromFile(@"C:PrintMyScreenprintscreen.png");
        Point loc = new Point(100, 100);
        e.Graphics.DrawImage(img, loc);
        img.Dispose();
      }
      protected override void WndProc(ref Message m)
      {
        switch (m.Msg)
        {
            case 0x84:
                base.WndProc(ref m);
                if ((int)m.Result == 0x1)
                    m.Result = (IntPtr)0x2;
                return;
        }
        base.WndProc(ref m);
      }
      private void moveApp()
      {
      }
      public void Repeater(Button btn, int interval)
      {
        var timer = new Timer { Interval = interval };
        timer.Tick += (sender, e) => moveApp();
        btn.MouseDown += (sender, e) => timer.Start();
        btn.MouseUp += (sender, e) => timer.Stop();
        btn.Disposed += (sender, e) =>
        {
            timer.Stop();
            timer.Dispose();
        };
      }
   }
}

你没有错过很多。

为了移动表单,您需要向窗口发送一条消息,指出左按钮位于表单标题上。这可以通过以下方法实现:

    public const int WM_NCLBUTTONDOWN = 0xA1;
    public const int HT_CAPTION = 0x2;
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool ReleaseCapture();

然后在您的moveapp中使用它:

  private void moveApp()
  {
        ReleaseCapture();
        SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
  }

还有一件事,由于您正在使用 Repeater中的Windows.Forms.Timer ,您将每 interval 毫秒输入一次moveapp。您必须Stop它才能输入一次。
因此,Repeater现在看起来像这样:

  public void Repeater(Button btn, int interval)
  {
    var timer = new Timer { Interval = interval };
    timer.Tick += (sender, e) =>  {timer.Stop();moveApp();}
    btn.MouseDown += (sender, e) => timer.Start();
    btn.MouseUp += (sender, e) => timer.Stop();
    btn.Disposed += (sender, e) =>
    {
        timer.Stop();
        timer.Dispose();
    };
  }

不要忘记在构造函数中调用中继器...我没看到你这样做。

最新更新