65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 .NET Compact Framework 中抑制输入事件

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2012 年 2 月 10 日

CPOL

1分钟阅读

viewsIcon

18159

在加载时抑制按键和鼠标事件

简介 我最近在开发 Windows Mobile 6.5 应用程序时,在使用 .NET Compact CE 处理输入事件时遇到一个问题。 由于很难在互联网上找到解决方案,我认为分享我的经验是个好主意,以便其他遇到相同问题开发人员可以减少这方面的麻烦。 情况 我的问题如下。 我的窗体应用程序调用 Web 服务来检查用户输入的凭据并加载一些数据以显示。 在执行过程中,我显示等待光标。
Cursor.Current = Cursors.WaitCursor
我认为这足以让最终用户知道他必须等待一段时间,直到有结果。 但麻烦在我发现一位急于测试我的应用程序的同事后开始了。 问题 虽然执行过程(检查凭据、加载数据)可能需要超过 5 秒,我的急于求成的同事在约 2 秒后开始产生鼠标点击。 这导致在 Web 服务执行完成后显示的屏幕上产生点击事件。 当然,这不是我想要的! 毕竟,设置等待光标只是设置等待光标,不多也不少。 因此,我尝试禁用窗体、显示加载屏幕等,但这些都不足以抑制鼠标和按键事件。 实际上发生的情况是,操作系统会缓冲用户输入,并在新窗体激活后**触发**这些输入。 因此,我们必须在这个地方处理问题。 解决方案 我创建了一个名为 InputEvents 的密封类,可以在窗体的激活事件中调用,以抑制在窗体实际激活之前发生的所有未处理输入事件。
public sealed class InputEvents
{
  internal struct MSG
  {
    public IntPtr hwnd;
    public int Msg;
    public IntPtr wParam;
    public IntPtr lParam;
    public int time;
    public int pt_x;
    public int pt_y;
  }

  [DllImport("coredll.dll", EntryPoint = "PeekMessage", SetLastError = true)]
  private static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);

  [DllImport("coredll.dll", EntryPoint = "GetMessageW", SetLastError = true)]
  private static extern bool GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);

  [DllImport("coredll.dll", EntryPoint = "TranslateMessage", SetLastError = true)]
  private static extern bool TranslateMessage(out MSG lpMsg);

  [DllImport("coredll.dll", EntryPoint = "DispatchMessage", SetLastError = true)]
  private static extern bool DispatchMessage(ref MSG lpMsg);
  
  private const int WM_KEYFIRST = 256;
  private const int WM_KEYLAST = 264;
  private const int WM_MOUSEFIRST = 512;
  private const int WM_MOUSELAST = 521;
  private const int PM_NOREMOVE = 0;
  private const int PM_REMOVE = 1;

  public static bool SuppressKeyMouseEvents()
  {
    MSG lpMsg;
    // check for messages
    while (PeekMessage(out lpMsg, IntPtr.Zero, 0, 0, PM_NOREMOVE))
    {
      // there is, so get the top one
      if (GetMessage(out lpMsg, IntPtr.Zero, 0, 0))
      {
        if (!((WM_MOUSEFIRST <= lpMsg.Msg && lpMsg.Msg <= WM_MOUSELAST) || (WM_KEYFIRST <= lpMsg.Msg && lpMsg.Msg <= WM_KEYLAST)))
        {
          TranslateMessage(out lpMsg);
	  DispatchMessage(ref lpMsg);
        }
      }
    }
    return true;
  }
}
更多信息请参见 http://msdn.microsoft.com/en-us/library/ms907610.aspx[^].
© . All rights reserved.