我正在尝试编写一个应用程序来感知某人何时点击并持有某些内容。我正在使用Windows窗体。我尝试使用鼠标,但它似乎并没有一直开火。这也将是一个多点触控应用程序。我将有两个按钮,用户可以点击并按住一个按钮,同时按下另一个按钮。或者只需按一个按钮。我甚至不确定Windows窗体应用程序如何处理它。
所有看到windows touch应用程序的例子都使用xaml。这真的是捕捉点击并保持的唯一方法吗?
我实际上是在这里制作一个屏幕键盘,我认为没有Windows窗体是不可能的。如果我在这里错了,请纠正我。
非常感谢任何帮助或指导。感谢。
答案 0 :(得分: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);
}
答案 1 :(得分: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;
}
}
构建应用程序,然后将其中一个测试控件弹出到表单上。然后,您可以向表单添加事件处理程序,如:
private void testTapAndHold1_TapAndHold(EventArgs e)
{
MessageBox.Show("You tapped and Held");
}
这种一般方法使我能够添加"点按并保持"在Microsoft Surface 4上运行的Windows窗体应用程序的功能