以编程方式模拟鼠标拖动

时间:2012-11-05 17:53:05

标签: c# winforms mouse

我有一个带控件的Windows窗体应用程序。该控件由一个带有画布的图表面板组成。我想要做的是以编程方式鼠标拖动面板,以便我在画布的右边缘和画布上绘制的最后一个项目之间有一个特定的距离。我尝试了两种方法。两者都工作在面板按需要拖动但我似乎无法获得我想要的运动精度。我编写了一个鼠标模拟器并尝试了两种方法。

方法1:

 if(this.ChartControl.ChartPanel.CanFocus)
 {
      // ... Focus the chart panel to be adjusted.
      this.ChartControl.ChartPanel.Focus();

      // ... Move cursor to lastBarScreenCoordinates on the chart panel to be adjusted.
      Cursor.Position = new Point(lastBarScreenCoordinates.X, lastBarScreenCoordinates.Y);

      MouseSimulator.SetMouseDragThresholds();

      // ... Move chart panel to required position.
      MouseSimulator.LeftMouseButtonDown(lastBarScreenCoordinates.X, lastBarScreenCoordinates.Y);
      MouseSimulator.MouseMove(lastBarScreenCoordinates.X-positionShift,
           lastBarScreenCoordinates.Y);
      MouseSimulator.LeftMouseButtonUp(lastBarScreenCoordinates.X-positionShift,
           lastBarScreenCoordinates.Y);

      MouseSimulator.ResetMouseDragThresholds(_cx_default, _cy_default);

      // ... Redraw the chart panel.
      this.ChartControl.ChartPanel.Refresh();

      // ... Reset cursor to its starting position.
      Cursor.Position = new Point(startingCursorX, startingCursorY);
 }

方法2:

 if(this.ChartControl.ChartPanel.CanFocus)
 {
      // ... Focus the chart panel to be adjusted.
      this.ChartControl.ChartPanel.Focus();

      // ... Move cursor to lastBarScreenCoordinates on the chart panel to be adjusted.
      Cursor.Position = new Point(lastBarScreenCoordinates.X, lastBarScreenCoordinates.Y);

      MouseSimulator.SetMouseDragThresholds();

      // ... Move chart panel to required position.
      MouseSimulator.LeftMouseButtonDown(lastBarScreenCoordinates.X, lastBarScreenCoordinates.Y);
      Cursor.Position = new Point(lastBarScreenCoordinates.X-positionShift,
           lastBarScreenCoordinates.Y);
      WindowsCommunication.SendMessage(this.ChartControl.Handle, 0x200, IntPtr.Zero,IntPtr.Zero);
      MouseSimulator.LeftMouseButtonUp(lastBarScreenCoordinates.X-positionShift,
           lastBarScreenCoordinates.Y);

      MouseSimulator.ResetMouseDragThresholds(_cx_default, _cy_default);

      // ... Redraw the chart panel.
      this.ChartControl.ChartPanel.Refresh();

      // ... Reset cursor to its starting position.
      Cursor.Position = new Point(startingCursorX, startingCursorY);
 }

我使用SendInput模拟鼠标点击。这是鼠标左键代码示例...

 public static void LeftMouseButtonDown(int x, int y)
 {
      INPUT mouseInput = new INPUT();
      mouseInput.type = SendInputEventType.InputMouse;
      mouseInput.mkhi.mi.dx = CalculateAbsoluteCoordinateX(x);
      mouseInput.mkhi.mi.dy = CalculateAbsoluteCoordinateY(y);
      mouseInput.mkhi.mi.mouseData = 0;
      mouseInput.mkhi.mi.time = 0;
      mouseInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
      SendInput(1, ref mouseInput, Marshal.SizeOf(new INPUT()));
 }

我计算了鼠标的标准化绝对坐标,如下所示......

 private static int CalculateAbsoluteCoordinateX(int x)
 {
      return ((x * 65536) + GetSystemMetrics(SystemMetric.SM_CXSCREEN) - 1) /
           GetSystemMetrics(SystemMetric.SM_CXSCREEN);
 }

所以这里是精度问题。如果我使用方法1(鼠标移动),绘制的最后一个项目和画布右边缘之间的测量距离与我在positionShift中设置的距离不同,并且光标位置差异不等于positionShift。我最初认为这是由于指针弹道问题,所以我尝试使用方法2.方法2确实给我精确的指针定位但我仍然有困难,面板移动但最后一个条画和右边缘之间的距离画布不等于positionShift的数量。它似乎总是关闭。我已经在这方面工作了很长时间,我的智慧结束了。我不确定这里发生了什么。如何通过模拟鼠标拖动来提高画布拖动的精度?

1 个答案:

答案 0 :(得分:0)

你可以做的就是这个,首先我相信SendInput API允许一个AbsoluteValue标志,所以不需要计算那些可能是问题的值,但很可能不是。

虽然我很好奇你为什么要使用Mouse Drag opperation。看起来你想要做的就是在每次绘制时按照指定的数量重新定位画布。如果是这种情况,为什么不在显卡本身明确设置它。还不清楚你是使用纯WinForms还是WPF。不清楚的是Canvas,我相当肯定只能用于启用WPF的窗口。

话虽如此 WPF修复, 根据包含画布的对象,只需根据情况设置其边距,因为我不知道您正在使用的数据我不能多说这些。但这是一个相对简单的想法,所以让我知道如果有效,它应该给你,至少也是一个像素完美对齐。

的WinForms, 只需对上面讨论的“Canvas”对象执行上述操作,或者使用对象的绝对坐标来移动它。

如果您能提供一份您正在研究的样本,那么我们可以更好地了解您的意思。