Thursday, October 16, 2008

Sử dụng IMessageFilter để khóa các sự kiện

 

Khi bạn cần thực hiện các process cần nhiều thời gian, ví dụ như việc gọi đến một service trên Internet, thì ngoài việc hiển thị progress bar, bạn cần khóa không cho người sử dụng thao tác trên màn hình, gồm các sự kiện liên quan đến con chuột và bàn phím. Ví dụ sau đây sẽ sử dụng khả năng lọc các message mà Windows gửi đến ứng dụng để thực hiện yêu cầu trên.

Đầu tiên, bạn cần cài đặt các phương thức được đưa ra trong Interface IMessageFilter.

/// <summary>
/// Lớp cài đătn Interface để lọc các message mà Windows sẽ gửi đến ứng dụng
/// </summary>
public class FilterMessageSample : IMessageFilter
{
    public const int WM_MOUSEFIRST = 0x0200,//Message bắt đầu có sự kiện chuột
                     WM_MOUSELAST = 0x020A,//Message kết thúc có sự kiện chuột
                     WM_KEYFIRST = 0x0100,//Message bắt đầu có sư kiện phím
                     WM_KEYLAST = 0x0108;//Message kết thúc có sự kiện phím
 
    /// <summary>
    /// Cài đặt phương thức lọc message của IMessageFilter
    /// </summary>
    /// <param name="m"></param>
    /// <returns></returns>
    public bool PreFilterMessage(ref Message m)
    {
        //Nếu các message nằm trong khoảng message có chứa sự kiện
        //bàn phím hoặc chuột
        if (m.Msg >= WM_MOUSEFIRST || m.Msg <= WM_MOUSELAST 
            || m.Msg >= WM_KEYFIRST || m.Msg <= WM_KEYLAST)
        {
            return true;//Không gửi message đến ứng dụng
        }
 
        return false;
    }
}

Cuối cùng, khi bạn muốn khóa ứng dụng hay hủy bỏ khóa, bạn hãy cài đặt đoạn code sau:

//Tạo một instance thực hiện filter các sự kiện bàn phím và chuột
FilterMessageSample filterMessageSample = new FilterMessageSample();
...
//Khi bạn thực hiện khóa các sự kiện với ứng dụng
Application.AddMessageFilter(filterMessageSample);
...
//Và khi bạn muốn ứng dụng trở lại hoạt động bình thường
Application.RemoveMessageFilter(filterMessageSample);

Ngoài ví dụ đơn giản trên, bạn còn có thể sử dụng khả năng của IMessageFilter để bắt toàn bộ các message trước khi nó được gửi đến chương trình.