1

誰かが何かをタップして保持したことを感知するアプリケーションを作成しようとしています。Windowsフォームを使用しています。マウスダウンを使用してみましたが、常に起動しているようには見えません。これもマルチタッチアプリになります。ボタンを 2 つ用意します。ユーザーは 1 つのボタンをタップ アンド ホールドし、もう 1 つのボタンを押すことができます。または ボタンを 1 つ押すだけです。Windowsフォームアプリがそれをどのように処理できるかさえわかりません。

すべての例は、xaml を使用する Windows タッチ アプリで見られます。これは本当にタップアンドホールドをキャプチャする唯一の方法ですか??

ここでは基本的にオンスクリーン キーボードを作成していますが、Windows フォームがなければそれは不可能だと思います。ここで間違っている場合は修正してください。

これに関するヘルプやガイダンスは大歓迎です。ありがとう。

4

2 に答える 2

2

プログラムが Windows 8 で実行されている場合は、WM_POINTER API を使用して必要な入力を取得できます。メッセージをキャプチャするには、WndProc をオーバーライドします。機能させるには P/Invoke を実行する必要がありますが、それほど難しくはありません。開始するための不完全なコードを次に示します。追跡するポインターの種類ごとに、up、down、および update イベントのケースを追加する必要があります。マルチタッチを処理するためのポインター ID を追跡します。長押しを処理するには、WM_POINTERDOWN から WM_POINTERUP までの時間を自分で追跡し、それに応じて行動する必要があります。お役に立てれば。

public const int WM_POINTERDOWN = 0x0246;
public const int WM_POINTERUP = 0x0247;
public const int WM_POINTERUPDATE = 0x0245;

public enum POINTER_INPUT_TYPE : int
{
    PT_POINTER = 0x00000001,
    PT_TOUCH   = 0x00000002,
    PT_PEN     = 0x00000003,
    PT_MOUSE   = 0x00000004
}

public static uint GET_POINTERID_WPARAM(uint wParam) { return wParam & 0xFFFF; }

[DllImport("User32.dll")]
public static extern bool GetPointerType(uint pPointerID, out POINTER_INPUT_TYPE pPointerType);

protected override void WndProc(ref Message m)
{
    bool handled = false;
    uint pointerID;
    POINTER_INPUT_TYPE pointerType;
    switch(m.Message)
    {
        case WM_POINTERDOWN:
             pointerID = User32.GET_POINTERID_WPARAM((uint)m.WParam);
             if (User32.GetPointerType(pointerID, out pointerType))
             {
                 switch (pointerType)
                 {
                     case POINTER_INPUT_TYPE.PT_PEN:
                         // Stylus Down
                         handled = true;
                         break;
                     case POINTER_INPUT_TYPE.PT_TOUCH:
                         // Touch down
                         handled = true;
                         break;
                 }
             }
             break;
    }

    if (handled)
        m.Result = (IntPtr)1;

    base.WndProc(ref m);
}
于 2013-03-25T21:46:59.097 に答える
0

この質問はしばらく前から出回っており、単純なアプローチが役立つ可能性があります。MouseDown イベントと Click イベント (MouseUp の前に発生) の間の時間を測定することで、「タップ アンド ホールド」(またはクリック アンド ホールド) をシミュレートできます。時間が特定の値よりも大きい場合は、Click をキャンセルし、(おそらく) 独自の TapAndHold イベントを発生させます。誰でもこのアプローチを試すために使用できるテスト コントロールを作成しました。テスト アプリに UserControl を追加して (私は TestTapAndHold と呼びます)、次のコードを貼り付けます。

public partial class TestTapAndHold : UserControl
{
    private string showText = "Tap Me";
    private DateTime mouseDown;
    private const int holdTime = 500;
    public TestTapAndHold()
    {
        InitializeComponent();
        this.Paint += drawText;
    }
    public delegate void OnTapAndHold(EventArgs e);
    public event OnTapAndHold TapAndHold;
    private void drawText(object sender, PaintEventArgs e)
    {
        using (var drawBrush = new SolidBrush(Color.Black))
        {
            e.Graphics.DrawString(showText, Font, drawBrush, new Point(5,3));
        }
    }
    protected override void OnClick(EventArgs e)
    {
        if (DateTime.Now.Subtract(mouseDown).Milliseconds >= holdTime)
        {
            showText = "Tap Hold";
            TapAndHold?.Invoke(e);
        } else
        {
            base.OnClick(e);
            showText = "Tapped";
        }
        Invalidate();
    }
    private void TestTapAndHold_MouseDown(object sender, MouseEventArgs e)
    {
        mouseDown = DateTime.Now;
    }
}

アプリをビルドし、テスト コントロールの 1 つをフォームにポップします。次に、次のようにフォームにイベント ハンドラーを追加できます。

    private void testTapAndHold1_TapAndHold(EventArgs e)
    {
        MessageBox.Show("You tapped and Held");
    }

この一般的なアプローチにより、Microsoft Surface 4 で実行されている Windows フォーム アプリに「タップ アンド ホールド」機能を追加することができました。

于 2016-04-27T14:22:51.833 に答える