2009-09-03 18 views
6

में सभी नियंत्रणों की माउस घटनाओं की सदस्यता लेना मैं प्रत्येक रूप में मैन्युअल रूप से सदस्यता लेने के बिना, किसी भी रूप में सभी नियंत्रणों की "माउस डाउन" घटनाओं को आसानी से कैसे पकड़ सकता हूं? (सी #) "कीप्रेव्यू" सुविधा की तरह कुछ, लेकिन माउस घटनाओं के लिए।फॉर्म

उत्तर

1

समाधान 1

एक रूप के भीतर हर नियंत्रण पर प्रत्येक और हर घटना की सदस्यता लेना निश्चित रूप से, लेने के लिए सबसे सरल दृष्टिकोण है, क्योंकि तुम सिर्फ रमेश द्वारा दिए गए कोड का उपयोग करें।

हालांकि, एक और तकनीक में मूल नियंत्रण पर डिफ़ॉल्ट विंडोज़ संदेश प्रसंस्करण विधि ("WndProc") को ओवरराइड करना शामिल है - इस मामले में, वह फ़ॉर्म जिसमें सभी नियंत्रण शामिल हैं। इसका एक दुष्प्रभाव है कि जब आप माउस कर्सर किसी अन्य अभिभावक नियंत्रण में निहित नियंत्रणों पर चलता है तो आप यह पता लगाने में सक्षम नहीं होंगे।

उदाहरण के लिए, जब आप माउस कर्सर TextBox पर TabControl के अंदर स्थित है, तो आप यह पता लगाने में सक्षम नहीं होंगे। ऐसा इसलिए है क्योंकि TabControl सभी माउस घटनाओं को संसाधित करना जारी रखेगा।

समाधान 2

निम्नलिखित समाधान जो को नियंत्रित माउस कर्सर एक तकनीक खिड़कियों के रूप में जाना का उपयोग कर खत्म हो गया है हुक का पता लगाने के प्रयास में सभी मुद्दों पर काबू पाने जाएगा।

हुक अनिवार्य रूप से हमें फोकस के साथ खिड़की पर भेजे जाने से पहले माउस और कीबोर्ड ईवेंट को फंसाने की अनुमति देता है।

यहां एक नमूना है:

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 फॉर्म के माउस ईवेंट हैंडलर को नहीं सुन सकते हैं। क्योंकि प्रत्येक नियंत्रण को अपने माउस इवेंट श्रोता मिलते हैं।

लेकिन आप रूपों माउस घटनाओं

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

इस तरह से करने के लिए प्रत्येक नियंत्रण माउस घटनाओं सदस्यता ले सकते हैं आप सभी नियंत्रण माउस की घटनाओं के लिए एक हैंडलर हो सकता है।

2

मैं यह मेरी प्रयोजनों के लिए सबसे अच्छा समाधान हो पाया।

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

फिर अपने मुख्य रूप में इस ऐड संदेश फिल्टर रजिस्टर करने के लिए:

एक नया वर्ग IMessageFilter से प्राप्त बनाएं

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

और जो कुछ भी आप की क्या ज़रूरत है करने के लिए इस समारोह जोड़ने के लिए, आपके फॉर्म में:

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