Я столкнулся с некоторым странным поведением в моем приложении .NET CF 2.0, работающем в Windows CE 5.0.
У меня есть таймер, периодически обновляющий элемент управления, который также может получать жесты касания и удержания от пользователя (в обработчике нажатия мыши). Я обнаружил, что когда 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;
}
}
}
Я не могу связать изображения встроенными, поэтому вот ссылка на скриншот, иллюстрирующий поведение
Редактировать: В моем реальном приложении отметка времени обновляет элемент управления. Так что я ограничен работой в одном потоке. (Я не могу действительно выполнить то, что мне нужно, с помощью обработчиков событий).