2009-09-03 13 views

Odpowiedz

1

Rozwiązanie 1

Zapisywanie się każda impreza na każdej kontroli w formie jest z pewnością najbardziej Najprostszym podejście do podjęcia, ponieważ wystarczy użyć kodu podanego przez Ramesh.

Jednak inna technika polega na przesłonięciu domyślnej metody przetwarzania komunikatów systemu Windows ("WndProc") w formancie nadrzędnym - w tym przypadku w formularzu zawierającym wszystkie formanty. Ma to efekt uboczny, którego nie można wykryć, gdy kursor myszy przesunie się nad kontrolkami zawartymi w innym elemencie nadrzędnym.

Na przykład nie można wykryć, kiedy kursor myszy znajduje się nad TextBox, który jest zawarty wewnątrz TabControl. Dzieje się tak, ponieważ TabControl będzie kontynuować przetwarzanie wszystkich zdarzeń myszy.

Rozwiązanie 2

Poniżej rozwiązanie pozwoli przezwyciężyć wszystkie problemy próbując wykryć, które kontrolować kursor myszy znajduje się nad zastosowaniem techniki znanej jako okien haki.

Haczyki zasadniczo umożliwiają uwięzienie zdarzeń myszy i klawiatury nawet przed ich wysłaniem do okna z fokusem.

Oto próbka:

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

Inne kontrakty w formularzu nie mogą nasłuchiwać obsługi zdarzeń myszy w formularzu. Ponieważ każdy kontroler ma własne listy obserwatorów zdarzeń myszy.

ale można zapisać się każdy zdarzeń Kontrola zdarzeń myszy do formy myszy

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); 

ten sposób można mieć jeden obsługi dla wszystkich zdarzeń steruje myszką.

2

I okazało się, że najlepszym rozwiązaniem dla moich celów.

Utwórz nową klasę pochodną od 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; 
    } 
} 

Następnie w formularzu głównym dodać do zarejestrowania filtr wiadomość:

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

i dodać tę funkcję, aby robić, co trzeba, w twojej formie:

public void YourMainForm_Click(object sender, EventArgs e) 
{ 
    // do anything here... 
} 
Powiązane problemy