7

MouseMoveプログラムにいくつかのイベントを添付しましMouseClickたが、次はこれらのいずれかです。

  1. 「グローバルな」マウスの動きを取得して、フォームの外でもマウスの位置を読み取ることができるようにします。
  2. そもそもマウスがフォームから離れないようにします。

私のプロジェクトはゲームなので、他のほとんどのゲームのようにマウスがフォームから離れないようにするのは素晴らしいことです (alt + tab fe でフォーカスを切り替えると、マウスを移動できます)。グローバルなマウスの動きを求める質問は、私のニーズにはかなり厄介です。

マウスがフォームの枠外に出ないようにする簡単な方法はありますか? または、実際には境界線を超えないようにするために、マウスをクライアント領域内にとどめておきます。


ゲームに関する追加情報:

このゲームは、5 秒から 30 秒の短いサバイバル ゲームです (30 秒後には生き続けるのが難しくなります)、マウスで弾丸をかわす必要があります。System.Windows.Forms.Panelマウスをフォームの外に移動すると、プレーヤー (マウスに取り付けられている) が動きを止めて、すぐに弾丸が当たってしまうと、本当に面倒です。これが、マウスがその領域を離れないようにすることが良い理由です。

4

5 に答える 5

5

遅い答えですが、役に立つかもしれません。フォームMouseLeaveMouseMoveイベントをサブスクライブして、次のように処理できます。

    private int X = 0;
    private int Y = 0;

    private void Form1_MouseLeave(object sender, EventArgs e)
    {
        Cursor.Position = new Point(X, Y);
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (Cursor.Position.X < this.Bounds.X + 50 )
            X = Cursor.Position.X + 20;
        else
            X = Cursor.Position.X - 20;

        if (Cursor.Position.Y < this.Bounds.Y + 50)
            Y = Cursor.Position.Y + 20;
        else
            Y = Cursor.Position.Y - 20;           
    }

上記により、マウスカーソルがフォームの境界を離れることはありません。ゲームが終了したら、必ずイベントの登録を解除してください。

編集 :

Hans Passants の回答は、私の回答よりも理にかなっています。使用Cursor.ClipするMouseEnter:

private void Form1_MouseEnter(object sender, EventArgs e)
    {
        Cursor.Clip = this.Bounds;
    }

エラー/クラッシュが発生した場合は、カーソルを解放できます(キャッチできると確信しています):

Cursor.Clip = Rectangle.Empty;
于 2013-02-22T18:11:26.377 に答える
4

たとえば、ユーザーが [スタート] メニューを操作するのを妨げるマウスをトラップすることはできません。最も近いのは、Cursor.Clip プロパティを割り当てることです。ただし、ユーザーが Ctrl+Esc を押すなどして簡単に無効にできます。これに関する通知はありません。

最善の方法は、フォームの Deactivated イベントをサブスクライブすることです。これにより、ユーザーが別のプログラムに切り替えたことを確実に伝えることができます。Activated イベントは、ユーザーがいつ戻ったかを示します。もちろん、ゲーム スコアがゲーム オブジェクトを動かし続けることに依存している場合、ユーザーが実際にこれを行う理由はほとんどありません。そのため、たとえば Escape キーを使用してゲームを一時停止する簡単な方法をユーザーに提供することを忘れないでください。

于 2013-02-22T17:33:29.263 に答える
2

あなたの問題の正確な解決策はわかりませんが、まったく別の考えがあります。あなたのゲームがどのように機能するかはわかりませんが、あなたが私に言ったことに基づいて、それを一歩難しくしてみませんか: ゲーム領域に境界線を追加します。たとえば、4 ピクセル幅の長方形で、触れることはできません。それらに触れると、死亡し、マウスが解放されます。

于 2013-02-22T17:21:37.170 に答える
1

Cursorクラスを使用できます。例えば:

int X = Cursor.Position.X;
int Y = Cursor.Position.Y;

ユーザーがフォームの外にマウスを移動できないようにするための最善のアプローチは、画面上のフォームの座標を把握してMouseMoveイベントを添付し、マウスがフォームの長方形の内側にあるかどうかを確認することです。 。

画面上のフォームの位置を知るには、この質問を見てください。

于 2013-02-22T17:03:33.567 に答える
0

2 つの理由から、グローバル マウス移動コントロールはお勧めしません。

  • これは悪い設計です。オペレーティング システムの境界を尊重する必要があります。この種の動作が必要な場合は、アプリケーションを全画面表示にします。この種の操作を実行する必要がある唯一のアプリケーションは、OS 全体をロックダウンする「キオスク」モードのアプリケーションです (オペレーターの悪用を防ぐため)。

  • グローバル キー フックは煩雑で、動作が保証されておらず、オペレーティング システムの重要な部分 (すべてのコントロール) に影響を与えるため危険です。コードにバグがあると、マシンの再起動が必要になる場合があります。

とは言っても、最後に確認したとき (少し前に Vista で) SetWindowsHookExは引き続き動作します (ただし、IIRC は公式にサポートされていません)。これは管理されていない呼び出しなので、pinvoke する必要がありますが、それを使用すると、メッセージの転送を拒否できます。アプリケーションの境界の外にマウスを移動します。OSがカーソルコントロールに勝てるかどうかは100%わかりませんが(以前はデスクトップボックスでキーボードをブロックしただけでした)、おそらくそれが最善の方法です.

于 2013-02-22T17:42:29.207 に答える