OpenTK使触摸按钮提升点击事件的方式与鼠标不同

时间:2014-10-30 14:22:45

标签: wpf opengl event-handling interop touchscreen

我想做什么:我目前正在WPF应用程序中托管OpenTK glControl(通过WindowsFormsHost)。该应用程序有许多按钮,但我们将专注于暂停和播放按钮。我使用VBO,这就是我为GL.DrawArrays(PrimitiveType.LineStrip, 0, frameCount );制作动画的方式。它绘制了从0到framecount的顶点范围,所以当我点击播放时,它只是开始递增framecount,它开始动画。只使用鼠标,一切都很完美。

问题:我的应用程序也需要使用触摸屏(FWIW,当我说触摸时,WPF将其视为手写笔,而不是触摸)。当应用程序没有动画时,触摸会像它应该的那样工作,我不会处理触摸事件,因此触摸按钮只会引发Click事件。如果我们没有动画,我就不会有任何问题。因此,当我使用我的鼠标Click播放按钮时,UI仍然响应我的鼠标(点击工作,徘徊改变颜色,等等),但接触似乎在一段时间内被忽略。我必须触摸一个按钮3到5次才能完成它应该做的事情(比如暂停)。让我们回过头来,现在我们还没有动画,这次,如果我触摸播放按钮来举起Click事件,它将开始制作动画,但我的触摸现在有同样的问题,必须触摸多个提升Click事件的时间,最重要的是,UI现在不响应鼠标(WindowsFormsHost仍然正确地响应鼠标事件)。单击按钮或将鼠标悬停在按钮上并没有做任何事情。直到我再次暂停动画,UI才开始再次响应鼠标。

我尝试了什么(我认为)我知道:当UI停止响应鼠标输入并且触摸输入被弄乱时,如果我使用MOUSE或TOUCH点击我的任何地方应用程序,它按预期工作。这让我相信它不是触摸屏驱动程序问题或任何东西。我还使用Snoop来查看正在引发(或不发生)的事件,以便看到手写笔和鼠标被捕获和释放以及焦点是什么。我找不到一个没有发布的实例。如果有人愿意,我可以发布Snoop结果,显示鼠标和触摸点击之间的差异。我尝试将预览鼠标放在MainWindow上,但在TOUCHING播放后,没有鼠标点击引发此事件,触摸播放按钮后第一次触摸会触发此事件。我也尝试隐藏WindowsFormsHost,鼠标和触摸点击所有工作就像他们应该减去glControl。因为我隐藏了WindowsFormsHost,所以paint事件永远不会被触发,这让我相信paint函数可能存在问题。我知道这个错误WPF Touch Bug,但我并不认为这是我的问题。有些东西告诉我互操作是给我带来问题的,但我不确定。

我的代码:

    private void playFwdFunc()
    {
        //disable undrawing and enable drawing
        undraw = false;
        draw = true;

        //unpause animation
        paused = false;
        //enable/disable appropriate buttons
        pauseBtn.IsEnabled = true;
        stepBackBtn.IsEnabled = false;
        stepFwdBtn.IsEnabled = false;
        clearStart.IsEnabled = true;
        clearCurrent.IsEnabled = true;
        //refresh control
        glControl1.Invalidate();
    }


    private void playFwdClick(object sender, RoutedEventArgs e)
    {
        playFwdFunc();

    }

在我的glPaint活动中:

  if (frameCount < vertices.Length && !paused)
            {
                //draw more vertices
                if (draw)
                {
                    if (0 < (int)(vertices.Length / (25000 / speedTrack.Value)))
                        frameCount += (int)(vertices.Length / (25000 / speedTrack.Value));
                    else
                        frameCount++;
                }


                //draw less vertices
                else if (undraw)
                {
                    if (0 < (int)(vertices.Length / (25000 / speedTrack.Value)))
                        frameCount -= (int)(vertices.Length / (25000 / speedTrack.Value));
                    else
                        frameCount--;
                }


                //make sure we dont have a negative framecount (null pointer)
                if (frameCount < 0)
                {
                    paused = true;
                    frameCount = 0;
                 //   manageCodeBox();

                }
                //make sure we dont exceed # of vertices (null pointer)
                else if (frameCount > vertices.Length)
                {
                    frameCount = vertices.Length;
                    paused = true;
                 //   manageCodeBox();
                }

            }

我的问题:为什么点击鼠标按钮会让UI做出与触摸按钮不同的反应,即使他们举起同样的事件?任何意见都表示赞赏。

1 个答案:

答案 0 :(得分:0)

所以我找到了造成这种行为的原因,在我的绘画功能中,我不断提出一个有glControl1.Invalidate()的事件。

我最好的猜测:我唯一真正的猜测是,某些事件,如触控线程上发生的触摸,在调用glControl1.Invalidate()时如何进入与UI线程的实时锁定。我认为这就是为什么一些接触被接受,但UI线程永远不会到达鼠标事件监听器。正如我所说:最好的猜测。

我的解决方法:我最初拨打DispatcherTimer来致电glControl1.Invalidate()。鼠标事件运行正常,但由于触摸被提升为鼠标点击,除非我处理触摸事件(我不想对我的UI上的每个按钮执行),否则会有延迟。到目前为止,我的下一个解决方案似乎正在发挥作用。

在我的windows构造函数中:CompositionTarget.Rendering += invalidateProcessor;

功能:

private void invalidateProcessor(object sender, EventArgs e)
    {
        Dispatcher.BeginInvoke(new Action(() => { if (!paused) glControl1.Invalidate(); }), DispatcherPriority.Background);
    }

我选择了DispatcherPriority.Background,因为较高优先级会再次导致触摸延迟。