在Timer_Tick事件中使用KeyDown

时间:2018-09-15 20:34:47

标签: c# visual-studio winforms timer

我和我的好友一直在开发此放大镜应用程序,但我们无法使其按期望的方式工作。

我们希望它的工作方式:

  1. 打开应用。
  2. 将鼠标移到要放大的区域。
  3. 打入。
  4. 放大窗口移至鼠标的(偏移)位置,并继续针对该特定位置更新该窗口。
  5. 再次按Enter即可将窗口移至新的光标位置。

现在,一旦我按Enter键,该窗口就会跟随鼠标,因为它进入for循环,并在其中捕获“ Cursor.Position”。我试图将Cursor.Position值保存在“ OnkeyDown”事件中,并在计时器循环内使用它,但由于它“在当前上下文中不存在”而无法使用。

有人可以看到我该怎么做吗?

预先感谢!

/莫顿

/* O-button zooms out
 * I-button zooms in
 * Esc-button exits app
 * Enter moves magnifying window to new location (doesn't work)
*/
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Magnifier
{
    public partial class Form1 : Form
    {
        Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        PictureBox pictureBox1 = new PictureBox();
        int zoom = 3; //zoom level
        public bool NewZoomLocation = false;
        public Form1()
        {


                {
                    InitializeComponent();
                    pictureBox1.Dock = DockStyle.Fill;
                    pictureBox1.BorderStyle = BorderStyle.FixedSingle;
                    Controls.Add(pictureBox1);
                    FormBorderStyle = FormBorderStyle.None;

                    Timer timer = new Timer();
                    timer.Interval = 100;
                    timer.Tick += timer_Tick;
                    timer.Start();
                }
           void timer_Tick(object sender, EventArgs e)
        {     var position = Cursor.Position;
              int xlocation = position.X;
              int ylocation = position.Y;
                {
                    try
                    {
                        var graphics = Graphics.FromImage(printscreen as Image);
                        graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
                        GC.Collect(); // Force the garbage collector (deals with memory leak)

                        if (NewZoomLocation == true)
                        {
                            var lensbmp = new Bitmap(50, 50); //Bitmap for Zoom window
                            var i = 0;
                            var j = 0;
                            for (int row = xlocation - 25; row < xlocation + 25; row++)
                            {
                                j = 0;
                                for (int column = ylocation - 25; column < ylocation + 25; column++)
                                {
                                    lensbmp.SetPixel(i, j, printscreen.GetPixel(row, column));

                                    j++;
                                }
                                i++;
                            }
                            this.pictureBox1.Image = new Bitmap(lensbmp, lensbmp.Width * zoom, lensbmp.Height * zoom);
                            Size = pictureBox1.Image.Size;
                            Left = xlocation - 45 * (zoom); //Horisontal position of final zoom window
                            Top = ylocation + 30; //Vertical position of final zoom window
                            TopMost = true;
                        }
                    }
                    catch //(Exception ex)
                    {
                        //MessageBox.Show(ex.Message);
                    }
                }
           }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyValue == 73) // I-button to zoom in
                zoom++;
            else if (e.KeyValue == 79) // O-button to zoom in
                zoom--;
            else if (e.KeyValue == 27) // Esc-button to exit
            {
                Close();
                Dispose();
            }
            else if (e.KeyValue == 13) // Enter-button to choose zoon area
            {
                NewZoomLocation = true;
            }
            base.OnKeyDown(e);

        }
    }
}

1 个答案:

答案 0 :(得分:1)

我不太确定您想在这里实现什么,但这应该可以使您处于更好的位置。

第一件事。之所以使用GC.Collect是因为您试图堵塞内存泄漏,如果创建了映像,请对其进行处理。

提供一些全局变量

private readonly PictureBox pictureBox1 = new PictureBox();

private Bitmap _lastBmp = new Bitmap(300, 300);

private Point _position;

public bool NewZoomLocation;

private int zoom = 3; //zoom level

构造函数

public Form1()
{
   InitializeComponent();
   pictureBox1.Dock = DockStyle.Fill;
   pictureBox1.BorderStyle = BorderStyle.FixedSingle;
   Controls.Add(pictureBox1);
   FormBorderStyle = FormBorderStyle.None;
   KeyPreview = true;
   Size = _lastBmp.Size;
   TopMost = true;
   var timer = new Timer();
   timer.Interval = 100;
   timer.Tick += timer_Tick;
   timer.Start();
}

清理

protected override void OnClosed(EventArgs e)
{
   base.OnClosed(e);

   _lastBmp.Dispose();
   _lastBmp = null;
}

按键

protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
{
   base.OnPreviewKeyDown(e);
   switch (e.KeyCode)
   {
      case Keys.Enter:
         NewZoomLocation = true;
         _position = Cursor.Position;

         break;
      case Keys.Up:
         zoom++;
         break;
      case Keys.Down:
         zoom--;
         break;
      case Keys.Escape:
         Close();
         break;
   }
}

计时器

private void timer_Tick(object sender, EventArgs e)
{
   if (NewZoomLocation)
   {
      var w = _lastBmp.Size.Width / zoom;
      var h = _lastBmp.Size.Height / zoom;
      var x = _position.X - w / 2;
      var y = _position.Y - h / 2;
      var size = new Size(w, h);    
      using (var screen = new Bitmap(size.Width, size.Height))
      {
         using (var g = Graphics.FromImage(screen))
         {
            g.CopyFromScreen(new Point(x, y), Point.Empty, size);
         }
         // resize
         using (var g = Graphics.FromImage(_lastBmp))
         {
            g.DrawImage(screen, new Rectangle(new Point(), _lastBmp.Size), new Rectangle(0, 0, w, h), GraphicsUnit.Pixel);
         }
      }

      pictureBox1.Image = _lastBmp;
   }
}

还有很多可以做的事,但是这应该可以帮助您入门。不再存在内存泄漏,它仅捕获所需内容的屏幕快照,因此速度更快。

祝你好运