我在运行Windows CE 5.0的.NET CF 2.0应用程序中遇到了一些奇怪的行为。.NET中的计时器/点按并保持手势问题CF
我有一个定时器定期更新控件,该控件还可以从用户(在鼠标下拉处理程序中)接收点击和保持手势。我发现当TAH开始时(但在它退出之前),一个计时器事件可以开始处理,它在执行过程的中途预先执行鼠标放下处理程序。
据我的研究告诉我,这不是正常的行为,我只是误解了定时器/事件?难道SHRecognizeGesture正在调用Application.DoEvents的等价物吗?
无论如何,有没有人有一个“很好”的方式来修复这个例子,以便当应用程序检查TAH时,定时器代理不会“打勾”。
请参阅下面的示例程序来说明此问题(点住列表框下方的空白处以生成日志消息)。
在此先感谢。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace DeviceApplication1
{
public class BugExample : Control
{
[Flags]
internal enum SHRGFLags
{
SHRG_RETURNCMD = 0x00000001,
SHRG_NOTIFYPARENT = 0x00000002,
SHRG_LONGDELAY = 0x00000008,
SHRG_NOANIMATION = 0x00000010,
}
[DllImport("aygshell.dll")]
private extern static int SHRecognizeGesture(ref SHRGINFO shrg);
private struct SHRGINFO
{
public int cbSize;
public IntPtr hwndClient;
public int ptDownx;
public int ptDowny;
public int dwFlags;
}
public bool TapAndHold(int x, int y)
{
SHRGINFO shrgi;
shrgi.cbSize = 20;
shrgi.hwndClient = this.Handle;
shrgi.dwFlags = (int)(SHRGFLags.SHRG_RETURNCMD);
shrgi.ptDownx = x;
shrgi.ptDowny = y;
return (SHRecognizeGesture(ref shrgi) > 0);
}
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
BugExampleForm parent = (BugExampleForm)this.Parent;
//The problem is that the parent tick event will fire whilst TapAndHold is running
//Does TapAndHold perform an equivelant to Application.DoEvents?
parent.AddLog("Tap Hold - Enter");
parent.AddLog(String.Format("Tap Hold - Exit - {0}", TapAndHold(e.X, e.Y)));
}
}
public class BugExampleForm : Form
{
Timer _timer;
BugExample _example;
ListBox _logBox;
public BugExampleForm()
{
_example = new BugExample();
_example.Dock = DockStyle.Fill;
_logBox = new ListBox();
_logBox.Dock = DockStyle.Top;
_timer = new Timer();
_timer.Interval = 1000;
_timer.Enabled = true;
_timer.Tick += new EventHandler(_timer_Tick);
this.SuspendLayout();
this.Text = "Example";
this.Size = new System.Drawing.Size(200, 300);
this.Controls.Add(_example);
this.Controls.Add(_logBox);
this.ResumeLayout();
}
void _timer_Tick(object sender, EventArgs e)
{
AddLog("Tick");
}
public void AddLog(string s)
{
_logBox.Items.Add(s);
_logBox.SelectedIndex = _logBox.Items.Count - 1;
}
}
}
我不能链接图片内嵌,所以here is a link的截图说明
编辑的行为:在我的实际应用中,计时器滴答的更新控制。所以我只能在一个线程内工作。 (我无法真正实现我需要的事件处理程序)。
感谢ctacke和psasik为你的帮助。由于代表不足,我无法赞成,但迄今为止您的回复非常好。我想我将不得不采用设置某种形式的全局可访问布尔的“丑陋”解决方案,该布尔表明控件是否已进入TAH部分。然后在表格的基础上检查这个布尔如果适当。生病让我暂时没有回答,看看我能否得到更多回复。 – 2009-10-30 01:08:56