3

コントロールを持つ Windows フォーム アプリケーションがあります。コントロールは、ペイントするキャンバスを含むグラフ パネルで構成されています。私がやりたいことは、キャンバスの右端とキャンバスに描かれた最後のアイテムとの間に特定の距離があるように、パネルをプログラムでマウスドラッグすることです。私は2つのアプローチを試みました。どちらも、パネルを思い通りにドラッグするという意味で機能しますが、希望する動きの精度を得ることができないようです。私はマウス シミュレーターをコーディングし、2 つのアプローチを試みました。

アプローチ 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 を使用してみました。キャンバスは本来あるべき positionShift 量と等しくありません。いつもオフのようです。私はこれに長い間取り組んできましたが、今は途方に暮れています。ここで何が起こっているのかわかりません。シミュレートされたマウス ドラッグによってキャンバス ドラッグの精度を向上させるにはどうすればよいですか?

4

1 に答える 1

0

まず、SendInput API では AbsoluteValue フラグが許可されているため、これらの値を計算する必要はないと思いますが、これは問題になる可能性がありますが、おそらくそうではありません。

これにマウスドラッグ操作を使用している理由については興味がありますが。あなたがしたいのは、描画ごとに指定された量だけキャンバスを再配置することだけのようです。この場合、キャンバス自体に明示的に設定しないでください。また、純粋な WinForms または WPF を使用しているかどうかも不明です。私がかなり確信しているキャンバスである不明確なビットは、WPF対応のウィンドウでのみ使用できます。

そうは言っても、キャンバスを含むオブジェクトに応じて、状況に応じて適切にマージンを設定するだけです。使用しているデータがわからないため、それについてはあまり言えません。しかし、これは比較的単純なアイデアなので、それが機能するかどうかを教えてください。少なくとも、ピクセルに完全に近い位置合わせが得られるはずです.

WinForms、あなたが話していた「キャンバス」オブジェクトに対して上記を実行するか、オブジェクトの絶対座標を使用して移動します。

あなたが取り組んでいたもののサンプルを大まかに提供していただければ、あなたが何を意味しているのかをよりよく理解できるかもしれません.

于 2012-11-06T10:14:34.000 に答える