PointerPressed和PointerReleased事件之间不匹配

时间:2013-06-25 20:26:31

标签: c# windows-phone-8 directx monogame

我使用的是Monogame并且有一个问题,如果我快速地将大量手指放在屏幕上然后快速移除它们,最终(经过几次重复)我最终会得到一些“压制”的事件,这些事件从未得到过匹配'发布'活动。

我不认为这个问题与Monogame有关,因为我可以通过使用vs2012创建的小型“Windows Phone和Direct3D”应用程序重现该问题(在我的诺基亚Lumia 920上)。

在C ++方面,我只是在生成的Direct3DInterop类中存储一个向量,用于记录按下的事件和已发布的事件

void Direct3DInterop::OnPointerPressed(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
{
    uint32 pointerID = args->CurrentPoint->PointerId;

    auto i = std::find (_pressed.begin(), _pressed.end(), pointerID);
    if (i == _pressed.end())
        _pressed.push_back(pointerID);
}
void Direct3DInterop::OnPointerReleased(DrawingSurfaceManipulationHost^ sender, PointerEventArgs^ args)
{
    uint32 pointerID = args->CurrentPoint->PointerId;

    _pressed.erase(std::remove(_pressed.begin(), _pressed.end(), pointerID),       _pressed.end());
}

在我的XAML中,我只有一个文本块和一个调度计时器,它定期检查_pressed中的元素数(它应该总是返回0)。

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent" 
  Margin="0,115,0,0">
<DrawingSurface x:Name="DrawingSurface" Margin="0,-113,0,0" Loaded="DrawingSurface_Loaded"/>
<TextBlock x:Name="LostReleasedCount" Text="Lost released count = 0"   HorizontalAlignment="Left" Margin="0,-113,0,0" VerticalAlignment="Top" Height="113"  Width="480"/>

</Grid>

并在文件背后的代码中

private Direct3DInterop m_d3dInterop = null;
private DispatcherTimer _timer;
private int _seconds;

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    // Creates a new instance of a timer.
    _timer = new DispatcherTimer();

    // Tells the _timer to tick every  second.
    _timer.Interval = TimeSpan.FromSeconds(1);


   _timer.Tick += TimerOnTick;
    _timer.Start();
    _seconds = 0;

}

private void TimerOnTick(object sender, EventArgs eventArgs)
{

    Dispatcher.BeginInvoke(() =>
    {
        _seconds++;
        LostReleasedCount.Text = "Lost released count = " + m_d3dInterop.GetPressedCount().ToString();
    });
}

我错过了一些明显的东西吗?您是否始终期望按下的事件和已发布的事件匹配?如果我直接使用XAML和Touch.FrameReported事件,我无法重现这个问题,所以它可能是DirectX的一些问题?

如果没有匹配的按下/释放对,我不确定如何区分真正的问题与仅仅是将手指放在屏幕上而不是移动它的人。

3 个答案:

答案 0 :(得分:0)

来自http://msdn.microsoft.com/library/windows/apps/br208971

  

其他事件而不是PointerReleased可能会在操作结束时触发 - 例如,PointerCanceled或PointerCaptureLost。不要依赖PointerPressed和PointerReleased事件,这些事件总是成对出现。要正常运行,您的应用必须倾听并处理所有可能对Press操作产生结论的事件。您可能无法获得PointerReleased事件的一些原因是:

  • 特定硬件处理触摸操作和按操作的方式的差异
  • 从不同指针
  • 捕获的编程指针
  • 更改显示区域关系的用户操作,例如更改分辨率或显示器设置
  • 输入交互,例如手写笔触摸与之前的触摸操作相同的表面

答案 1 :(得分:0)

可能还有另一个原因。请在此处查看我的回答:How to handle multi touch in windows phone 8 app

可能的原因可能是竞争条件

答案 2 :(得分:0)

在Direct3DBackground类中添加此函数

void Direct3DBackground::SetManipulationHost(Windows::Phone::Input::Interop::
             DrawingSurfaceManipulationHost^ manipulationHost)
{
    manipulationHost->PointerPressed +=
                      ref new TypedEventHandler<
              DrawingSurfaceManipulationHost^, PointerEventArgs^>
              (this, &Direct3DBackground::OnPointerPressed);

    manipulationHost->PointerMoved +=
        ref new TypedEventHandler<DrawingSurfaceManipulationHost^, 
         PointerEventArgs^>(this, &Direct3DBackground::OnPointerMoved);

    manipulationHost->PointerReleased +=
        ref new TypedEventHandler<DrawingSurfaceManipulationHost^, 
         PointerEventArgs^>(this, &Direct3DBackground::OnPointerReleased);
}

和XAML C#代码:

DrawingSurfaceBackground.SetBackgroundManipulationHandler(m_d3dBackGround);