2009-09-03 36 views

Trả lời

1

Giải pháp 1

Đang đăng ký cho mỗi và mọi sự kiện trên tất cả các điều khiển trong một hình thức chắc chắn là đơn giản nhất cách tiếp cận nhất để lấy, vì bạn chỉ cần sử dụng mã do Ramesh.

Tuy nhiên, một kỹ thuật khác liên quan đến việc ghi đè phương thức xử lý thông báo cửa sổ mặc định ("WndProc") trên điều khiển chính - trong trường hợp này, biểu mẫu chứa tất cả các điều khiển. Điều này có tác dụng phụ mà bạn sẽ không thể phát hiện khi con trỏ chuột di chuyển qua các điều khiển chứa bên trong một điều khiển chính khác.

Ví dụ: bạn sẽ không thể phát hiện khi con trỏ chuột trên TextBox được chứa bên trong một TabControl. Điều này là do TabControl sẽ tiếp tục xử lý tất cả các sự kiện chuột.

Giải pháp 2

Các giải pháp sau đây sẽ khắc phục được tất cả các vấn đề trong việc cố gắng để phát hiện mà điều khiển con trỏ chuột đã qua sử dụng một kỹ thuật gọi là cửa sổ móc.

Hooks về cơ bản cho phép chúng tôi bẫy sự kiện chuột và bàn phím ngay cả trước khi chúng được gửi đến cửa sổ bằng tiêu điểm.

Dưới đây là một ví dụ:

public enum HookType : int 
    { 
    WH_JOURNALRECORD = 0, 
    WH_JOURNALPLAYBACK = 1, 
    WH_KEYBOARD = 2, 
    WH_GETMESSAGE = 3, 
    WH_CALLWNDPROC = 4, 
    WH_CBT = 5, 
    WH_SYSMSGFILTER = 6, 
    WH_MOUSE = 7, 
    WH_HARDWARE = 8, 
    WH_DEBUG = 9, 
    WH_SHELL = 10, 
    WH_FOREGROUNDIDLE = 11, 
    WH_CALLWNDPROCRET = 12, 
    WH_KEYBOARD_LL = 13, 
    WH_MOUSE_LL = 14 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
    public int X; 
    public int Y; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct MouseHookStruct 
    { 
    public POINT pt; 
    public int hwnd; 
    public int hitTestCode; 
    public int dwExtraInfo; 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern int SetWindowsHookEx(HookType hook, HookProc callback, IntPtr hInstance, uint dwThreadId); 

    [DllImport("user32.dll", SetLastError= true)] 
    static extern int CallNextHookEx(int hook, int code, IntPtr wParam, IntPtr lParam); 

    [DllImport("kernel32.dll")] 
    static extern int GetLastError(); 

    [DllImport("kernel32.dll")] 
    static extern int GetCurrentThreadId(); 

    public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); 
    private static int hHook; 

    public Form1() 
    { 
    InitializeComponent(); 

    hHook = SetWindowsHookEx(HookType.WH_MOUSE, MouseHookProc, IntPtr.Zero, (uint)GetCurrentThreadId()); 
    if (hHook == 0) 
    MessageBox.Show("GetLastError: " + GetLastError()); 
    } 

    private int MouseHookProc(int code, IntPtr wParam, IntPtr lParam) 
    { 
    //Marshall the data from the callback. 
    MouseHookStruct mouseInfo = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct)); 

    if (code < 0) 
    { 
    return CallNextHookEx(hHook, code, wParam, lParam); 
    } 
    else 
    { 
    //Create a string variable that shows the current mouse coordinates. 
    String strCaption = "x = " + mouseInfo.pt.X.ToString("d") + 
    " y = " + mouseInfo.pt.Y.ToString("d"); 

    //You must get the active form because it is a static function. 
    Form tempForm = Form.ActiveForm; 

    Control c = Control.FromHandle((IntPtr)mouseInfo.hwnd); 
    if (c != null) 
    label1.Text = c.Name; 
    else 
    label1.Text = "Control not found"; 

    //Set the caption of the form. 
    tempForm.Text = strCaption; 

    return CallNextHookEx(hHook, code, wParam, lParam); 
    } 
    } 
1

Conttrols khác trong biểu mẫu không thể nghe trình xử lý sự kiện chuột của biểu mẫu. Bởi vì mỗi điều khiển đều có trình nghe sự kiện chuột của riêng nó.

Nhưng Bạn có thể đăng ký mỗi sự kiện điều khiển chuột để các sự kiện dạng chuột

this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown);  
this.label1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown); 
this.ListBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MDown); 

cách này bạn có thể có điều khiển duy nhất cho tất cả các sự kiện điều khiển chuột.

2

Tôi thấy điều này là giải pháp tốt nhất cho mục đích của tôi.

Tạo một lớp mới có nguồn gốc từ IMessageFilter:

public class GlobalMouseHandler : IMessageFilter 
{ 

    private const int WM_LBUTTONDOWN = 0x201; 

    public bool PreFilterMessage(ref Message m) 
    { 
     if (m.Msg == WM_LBUTTONDOWN) 
     { 
      // do something 
      ((YourMainForm)Form.ActiveForm).YourMainForm_Click(null, null); 
     } 
     return false; 
    } 
} 

Sau đó, trong hình thức chính của bạn thêm này để đăng ký bộ lọc thông điệp:

GlobalMouseHandler globalClick = new GlobalMouseHandler(); 
Application.AddMessageFilter(globalClick); 

Và thêm chức năng này để làm bất cứ điều gì bạn có, trong biểu mẫu của bạn:

public void YourMainForm_Click(object sender, EventArgs e) 
{ 
    // do anything here... 
} 
Các vấn đề liên quan