2010-10-13 35 views
6

Tôi có một bảng điều khiển trong Biểu mẫu của tôi với trình xử lý sự kiện nhấp chuột. Tôi cũng có một số điều khiển khác bên trong bảng điều khiển (nhãn, bảng khác, vv). Tôi muốn sự kiện nhấp chuột đăng ký nếu bạn nhấp vào bất kỳ đâu trong bảng điều khiển. Sự kiện nhấp chuột hoạt động miễn là tôi không nhấp vào bất kỳ điều khiển nào trong bảng điều khiển nhưng tôi muốn kích hoạt sự kiện bất kể bạn nhấp vào bên trong bảng điều khiển ở đâu. Điều này có thể xảy ra nếu không thêm cùng một sự kiện nhấp chuột vào tất cả các điều khiển bên trong bảng điều khiển không?Xử lý sự kiện nhấp ở bất kỳ đâu trong bảng điều khiển trong C#

+0

Đây có phải là WPF .....? –

+1

Không, chỉ cần một cửa sổ thông thường hình thức ứng dụng –

Trả lời

1

tôi cần các chức năng chính xác cùng một ngày hôm nay, vì vậy đây là thử nghiệm và hoạt động:

1: Tạo một subclasser mà có thể cướp mouseclick của bạn:

internal class MessageSnatcher : NativeWindow 
{ 
    public event EventHandler LeftMouseClickOccured = delegate{}; 

    private const int WM_LBUTTONDOWN = 0x201; 
    private const int WM_PARENTNOTIFY = 0x210; 

    private readonly Control _control; 

    public MessageSnatcher(Control control) 
    { 
     if (control.Handle != IntPtr.Zero) 
      AssignHandle(control.Handle); 
     else 
      control.HandleCreated += OnHandleCreated; 

     control.HandleDestroyed += OnHandleDestroyed; 
     _control = control; 
    } 

    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_PARENTNOTIFY) 
     { 
      if (m.WParam.ToInt64() == WM_LBUTTONDOWN) 
       LeftMouseClickOccured(this, EventArgs.Empty); 
     } 

     base.WndProc(ref m); 
    } 

    private void OnHandleCreated(object sender, EventArgs e) 
    { 
     AssignHandle(_control.Handle); 
    } 

    private void OnHandleDestroyed(object sender, EventArgs e) 
    { 
     ReleaseHandle(); 
    } 
} 

2: khởi tạo các snatcher để móc vào WndProc bảng điều khiển:

private MessageSnatcher _snatcher; 

    public Form1() 
    { 
     InitializeComponent(); 

     _snatcher = new MessageSnatcher(this.panel1); 
    } 

3: The Message snatcher sẽ nhận được WM_PARENTNOTIFY nếu bạn click vào một chi ld kiểm soát.

5

Về mặt kỹ thuật, có thể là mặc dù là rất xấu xí. Bạn cần phải nắm bắt thông báo trước nó được gửi đến điều khiển đã được nhấp. Mà bạn có thể làm với IMessageFilter, bạn có thể đánh hơi một thông điệp đầu vào đã được loại bỏ khỏi hàng đợi tin nhắn trước khi nó được gửi đi. Như thế này:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

class MyPanel : Panel, IMessageFilter { 
    public MyPanel() { 
     Application.AddMessageFilter(this); 
    } 
    protected override void Dispose(bool disposing) { 
     if (disposing) Application.RemoveMessageFilter(this); 
     base.Dispose(disposing); 
    } 
    public bool PreFilterMessage(ref Message m) { 
     if (m.HWnd == this.Handle) { 
      if (m.Msg == 0x201) { // Trap WM_LBUTTONDOWN 
       Point pos = new Point(m.LParam.ToInt32()); 
       // Do something with this, return true if the control shouldn't see it 
       //... 
       // return true 
      } 
     } 
     return false; 
    } 
} 
+0

+1 Tôi cũng đã làm điều này và đồng ý nó sẽ làm việc độc đáo. Cảnh báo duy nhất của tôi là nó về cơ bản gắn vào máy bơm ứng dụng sự kiện tin nhắn, do đó hãy chắc chắn rằng bất cứ điều gì bạn làm trong "Làm điều gì đó với điều này ..." bit, làm cho nó nhanh chóng và hiệu quả. –

+1

Meh, nó đã được lọc cho bảng điều khiển và thông báo. Mã này chạy theo thời gian của con người. –

0

Bit muộn cho bữa tiệc, Nhưng điều tôi làm là lập bản đồ tất cả sự kiện nhấp của tất cả các điều khiển bên trong sự kiện nhấp vào bảng điều khiển. Tôi biết cách tiếp cận khó chịu của nó. nhưng hey !!

Các vấn đề liên quan