2012-11-30 1 views
5

का उपयोग कर किसी एप्लिकेशन के बाहर कच्चे माउस क्लिक को कैसे रोकें मैं दो "चूहों" को नियंत्रित करने का प्रयास कर रहा हूं। प्राथमिक माउस (चूहों) का उपयोग सामान्य यूआई नियंत्रण (जिसे मैं अवरुद्ध नहीं करना चाहता) के लिए कर्सर को नियंत्रित करने के लिए उपयोग किया जाता है और एक द्वितीयक "माउस" जिसे केवल उस एप्लिकेशन में इनपुट के रूप में उपयोग किया जाना चाहिए जिसे मैं लिख रहा हूं और अन्यथा अनदेखा कर रहा हूं।सी #

मैं सफलतापूर्वक माउस संदेशों को कैप्चर कर रहा हूं और वांछित के रूप में फ़िल्टरिंग कर रहा हूं। मैं माउस इनपुट को सफलतापूर्वक कैप्चर भी कर सकता हूं, भले ही मेरा ऐप फोकस में न हो (वांछित के रूप में)।

एकमात्र शेष मुद्दा यह है कि मैं माउस को अन्य अनुप्रयोगों के साथ बातचीत करने से नहीं रोक सकता। तो मैं अनिवार्य रूप से माउस पर जासूसी कर सकता हूं, लेकिन पूरी तरह से संदेश का उपभोग नहीं कर सकता।

मैं "विश्वास करता हूं" मैं फ़िल्टर किए गए माउस संदेशों को संसाधित करते समय "बेस.डब्ल्यूप्रोक (रेफ संदेश)" को कॉल करने से रोक रहा हूं, लेकिन सिस्टम अभी भी माउस क्लिक प्राप्त कर रहा है।

क्या सी # (विजुअल स्टूडियो एक्सप्रेस 2010) ऐसा करने में सक्षम है?

किसी भी सहायता के लिए धन्यवाद जो आप दे सकते हैं।

+1

हेक का जवाब सबसे सही लगता है। बेस ओवरराइडिंग। डंडप्रोक केवल विंडोज संदेशों को नियंत्रित करता है * आपका * एप्लिकेशन प्राप्त करता है, लेकिन इसका अन्य अनुप्रयोगों के विंडोज संदेशों को नियंत्रित करने के साथ कुछ लेना देना नहीं है। एक वैश्विक माउस हुक जाने का रास्ता है। यह वास्तव में वास्तव में लोकप्रिय है। – Jason

+0

एक माउस हुक केवल आधे युद्ध है। मुझे वास्तव में दोनों की जरूरत है। हुक का उपयोग अन्य ऐप्स पर क्लिक फॉर्म को रोकने के लिए किया जाता है, लेकिन मुझे कच्चे माउस की आवश्यकता होती है, इसलिए मैं किस वास्तविक डिवाइस पर क्लिक करता था। असली जवाब यह है कि सी # (.net) सही उपकरण नहीं है - दुख की बात है। – ChronoFish

+0

आपको कच्चे माउस की ज़रूरत से क्या मतलब है ताकि आप [जान सकें] किस वास्तविक डिवाइस पर क्लिक किया गया था? माउस क्लिक को हुक करने पर, आप सक्रिय विंडो (GetActiveWindow()) और क्लिक के स्थान को निर्धारित कर सकते हैं, और फिर आप यह निर्धारित कर सकते हैं कि यह क्लिक आपके फॉर्म पर हुआ है या नहीं। – Jason

उत्तर

3

कच्चा इनपुट हो सकता है जो आप खोज रहे हैं। Here एक समान प्रश्न के साथ एक एमएसडीएन चर्चा है जिसमें सी # में mutliple कीबोर्ड को संभालने पर कोडप्रोजेक्ट आलेख से लिंक है।

+0

में कुछ पढ़ने की आवश्यकता नहीं है यह प्राथमिक संदर्भ है जिसने मुझे उतना ही किया है जितना मैंने किया था। यह अन्य अनुप्रयोगों में इनपुट सीमित करने के अलावा "काम करता है"। हालांकि धन्यवाद। – ChronoFish

+0

मुझे नहीं लगता कि यह वैश्विक स्तर पर इनपुट फ़िल्टर करना संभव है, [इस] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms645543 (v = vs.85) .aspx से निर्णय लेना संभव है) लेख। वाक्य जो मुझे ऐसा सोचता है वह है: "ध्यान दें कि माउस और कीबोर्ड भी छिपाए गए हैं, इसलिए उनमें से डेटा दोनों छिपा संदेश WM_INPUT और पारंपरिक संदेशों से हो सकता है। कोई एप्लिकेशन झंडे के उचित चयन से किसी भी विधि का चयन कर सकता है RAWINPUTDEVICE में। " – Bikonja

+0

मैं आपको उत्तर के साथ पुरस्कार दूंगा क्योंकि यह सी # या .net में "संभव नहीं है"। हालांकि यह संभव है - लेकिन आपको एक गैर-नेट डीएलएल के साथ जाना है जिसका मूल रूप से सी/सी ++ – ChronoFish

1

आप वैश्विक माउस हुक का उपयोग कर सकते हैं। मुझे याद नहीं है कि मुझे यह कहां मिला है, लेकिन here नमूना

+0

मैं वैश्विक माउस हुक का उपयोग करने का प्रयास कर रहा हूं - जो शायद मुझे उपयोग करने की ज़रूरत है ... लेकिन इस प्रकार मैं इसे केवल WH_MOUSE के लिए काम करने के लिए प्राप्त कर सकता हूं, जो केवल मेरे ऐप के लिए संदेश कैप्चर करता है, जहां WH_MOUSE_LL है सभी संदेशों को कैप्चर करना चाहिए - लेकिन मुझे कैप्चर शुरू करने के लिए कोड नहीं मिल रहा है (यह त्रुटियां बाहर है)। (ऐसा लगता है कि मैं नो-मैन की भूमि में हूं और सी # के लिए असमर्थित कार्यक्षमता में हूं)। धन्यवाद – ChronoFish

+0

इसके अलावा, मैं रूसी नहीं बोलता या पढ़ता हूं इसलिए फोरम लिंक मेरी मदद नहीं करता है। – ChronoFish

+0

रूसी पढ़ने की कोई आवश्यकता नहीं है, यह अंग्रेजी में टिप्पणियों के साथ माउस हुक नमूना पर एक लिंक है। और यह, कुछ चीजें आप की जरूरत को शामिल उदाहरण के लिए:। 'निजी स्थिरांक पूर्णांक WH_KEYBOARD_LL = 13;' और 'hMouseHook = SetWindowsHookEx ( WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE ( Assembly.GetExecutingAssembly() GetModules() [0]), 0); ' – heq

0

मुझे नहीं लगता कि माउस को C# .Net के माध्यम से क्लिक करना संभव है। हालांकि, आप क्लिप पॉसर के माध्यम से माउस पॉइंटर को एक स्थिति में लॉक करने में सक्षम हो सकते हैं। नीचे दिया गया लिंक आपको इसके साथ मदद कर सकता है।

यदि आप अनिवार्य रूप से एक माउस को इस्तेमाल होने से रोकना चाहते हैं तो क्यों न केवल माउस को अक्षम करें अगर आप डिवाइस मैनेजर पर गए और "अक्षम" पर क्लिक किया। यह here हल के रूप में प्रोग्रामेटिक रूप से किया जा सकता है।

public static class DisableHardware 
{ 
    const uint DIF_PROPERTYCHANGE = 0x12; 
    const uint DICS_ENABLE = 1; 
    const uint DICS_DISABLE = 2; // disable device 
    const uint DICS_FLAG_GLOBAL = 1; // not profile-specific 
    const uint DIGCF_ALLCLASSES = 4; 
    const uint DIGCF_PRESENT = 2; 
    const uint ERROR_INVALID_DATA = 13; 
    const uint ERROR_NO_MORE_ITEMS = 259; 
    const uint ERROR_ELEMENT_NOT_FOUND = 1168; 

    static DEVPROPKEY DEVPKEY_Device_DeviceDesc; 
    static DEVPROPKEY DEVPKEY_Device_HardwareIds; 

    [StructLayout(LayoutKind.Sequential)] 
    struct SP_CLASSINSTALL_HEADER 
    { 
     public UInt32 cbSize; 
     public UInt32 InstallFunction; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct SP_PROPCHANGE_PARAMS 
    { 
     public SP_CLASSINSTALL_HEADER ClassInstallHeader; 
     public UInt32 StateChange; 
     public UInt32 Scope; 
     public UInt32 HwProfile; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct SP_DEVINFO_DATA 
    { 
     public UInt32 cbSize; 
     public Guid classGuid; 
     public UInt32 devInst; 
     public IntPtr reserved;  // CHANGE #1 - was UInt32 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct DEVPROPKEY 
    { 
     public Guid fmtid; 
     public UInt32 pid; 
    } 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern IntPtr SetupDiGetClassDevsW(
     [In] ref Guid ClassGuid, 
     [MarshalAs(UnmanagedType.LPWStr)] 
string Enumerator, 
     IntPtr parent, 
     UInt32 flags); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern bool SetupDiDestroyDeviceInfoList(IntPtr handle); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, 
     UInt32 memberIndex, 
     [Out] out SP_DEVINFO_DATA deviceInfoData); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern bool SetupDiSetClassInstallParams(
     IntPtr deviceInfoSet, 
     [In] ref SP_DEVINFO_DATA deviceInfoData, 
     [In] ref SP_PROPCHANGE_PARAMS classInstallParams, 
     UInt32 ClassInstallParamsSize); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern bool SetupDiChangeState(
     IntPtr deviceInfoSet, 
     [In] ref SP_DEVINFO_DATA deviceInfoData); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern bool SetupDiGetDevicePropertyW(
      IntPtr deviceInfoSet, 
      [In] ref SP_DEVINFO_DATA DeviceInfoData, 
      [In] ref DEVPROPKEY propertyKey, 
      [Out] out UInt32 propertyType, 
      IntPtr propertyBuffer, 
      UInt32 propertyBufferSize, 
      out UInt32 requiredSize, 
      UInt32 flags); 

    [DllImport("setupapi.dll", SetLastError = true)] 
    static extern bool SetupDiGetDeviceRegistryPropertyW(
     IntPtr DeviceInfoSet, 
     [In] ref SP_DEVINFO_DATA DeviceInfoData, 
     UInt32 Property, 
     [Out] out UInt32 PropertyRegDataType, 
     IntPtr PropertyBuffer, 
     UInt32 PropertyBufferSize, 
     [In,Out] ref UInt32 RequiredSize 
    ); 

    static DisableHardware() 
    { 
     DisableHardware.DEVPKEY_Device_DeviceDesc = new DEVPROPKEY(); 
     DEVPKEY_Device_DeviceDesc.fmtid = new Guid(
       0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 
       0xd1, 0x46, 0xa8, 0x50, 0xe0); 
     DEVPKEY_Device_DeviceDesc.pid = 2; 

     DEVPKEY_Device_HardwareIds = new DEVPROPKEY(); 
     DEVPKEY_Device_HardwareIds.fmtid = new Guid(
      0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 
      0xd1, 0x46, 0xa8, 0x50, 0xe0); 
     DEVPKEY_Device_HardwareIds.pid = 3; 
    } 




    public static void DisableDevice(Func<string, bool> filter, bool disable = true) 
    { 
     IntPtr info = IntPtr.Zero; 
     Guid NullGuid = Guid.Empty; 
     try 
     { 
      info = SetupDiGetClassDevsW(
       ref NullGuid, 
       null, 
       IntPtr.Zero, 
       DIGCF_ALLCLASSES); 
      CheckError("SetupDiGetClassDevs"); 

      SP_DEVINFO_DATA devdata = new SP_DEVINFO_DATA(); 
      devdata.cbSize = (UInt32)Marshal.SizeOf(devdata); 

      // Get first device matching device criterion. 
      for (uint i = 0; ; i++) 
      { 
       SetupDiEnumDeviceInfo(info, 
        i, 
        out devdata); 
       // if no items match filter, throw 
       if (Marshal.GetLastWin32Error() == ERROR_NO_MORE_ITEMS) 
        CheckError("No device found matching filter.", 0xcffff); 
       CheckError("SetupDiEnumDeviceInfo"); 

       string devicepath = GetStringPropertyForDevice(info, 
              devdata, 1); // SPDRP_HARDWAREID 

       // Uncomment to print name/path 
       //Console.WriteLine(GetStringPropertyForDevice(info, 
       //       devdata, DEVPKEY_Device_DeviceDesc)); 
       //Console.WriteLine(" {0}", devicepath); 
       if (devicepath != null && filter(devicepath)) break; 

      } 

      SP_CLASSINSTALL_HEADER header = new SP_CLASSINSTALL_HEADER(); 
      header.cbSize = (UInt32)Marshal.SizeOf(header); 
      header.InstallFunction = DIF_PROPERTYCHANGE; 

      SP_PROPCHANGE_PARAMS propchangeparams = new SP_PROPCHANGE_PARAMS(); 
      propchangeparams.ClassInstallHeader = header; 
      propchangeparams.StateChange = disable ? DICS_DISABLE : DICS_ENABLE; 
      propchangeparams.Scope = DICS_FLAG_GLOBAL; 
      propchangeparams.HwProfile = 0; 

      SetupDiSetClassInstallParams(info, 
       ref devdata, 
       ref propchangeparams, 
       (UInt32)Marshal.SizeOf(propchangeparams)); 
      CheckError("SetupDiSetClassInstallParams"); 

      SetupDiChangeState(
       info, 
       ref devdata); 
      CheckError("SetupDiChangeState"); 
     } 
     finally 
     { 
      if (info != IntPtr.Zero) 
       SetupDiDestroyDeviceInfoList(info); 
     } 
    } 
    private static void CheckError(string message, int lasterror = -1) 
    { 

     int code = lasterror == -1 ? Marshal.GetLastWin32Error() : lasterror; 
     if (code != 0) 
      throw new ApplicationException(
       String.Format("Error disabling hardware device (Code {0}): {1}", 
        code, message)); 
    } 

    private static string GetStringPropertyForDevice(IntPtr info, SP_DEVINFO_DATA devdata, 
     uint propId) 
    { 
     uint proptype, outsize; 
     IntPtr buffer = IntPtr.Zero; 
     try 
     { 
      uint buflen = 512; 
      buffer = Marshal.AllocHGlobal((int)buflen); 
      outsize=0; 
      // CHANGE #2 - Use this instead of SetupDiGetDeviceProperty 
      SetupDiGetDeviceRegistryPropertyW(
       info, 
       ref devdata, 
       propId, 
       out proptype, 
       buffer, 
       buflen, 
       ref outsize); 
      byte[] lbuffer = new byte[outsize]; 
      Marshal.Copy(buffer, lbuffer, 0, (int)outsize); 
      int errcode = Marshal.GetLastWin32Error(); 
      if (errcode == ERROR_INVALID_DATA) return null; 
      CheckError("SetupDiGetDeviceProperty", errcode); 
      return Encoding.Unicode.GetString(lbuffer); 
     } 
     finally 
     { 
      if (buffer != IntPtr.Zero) 
       Marshal.FreeHGlobal(buffer); 
     } 
    } 

} 

http://msdn.microsoft.com/en-us/library/windows/desktop/ms648383%28v=vs.85%29.aspx http://www.pinvoke.net/default.aspx/user32/ClipCursor.html

+0

में प्रोग्रामिंग का मतलब है सुझाव के लिए धन्यवाद लेकिन क्लिपिंग कुछ ऐसा है जिसे मैं टालना चाहता हूं। धन्यवाद। – ChronoFish

+0

@ChronoFish मेरे अन्य सुझाव के बारे में क्या है: बस प्रोग्राम को प्रोग्रामिक रूप से अक्षम करें? – FrostyFire

+0

मैं नहीं चाहता कि दूसरा माउस अक्षम हो। मेरे एप्लिकेशन को यह जानने की जरूरत है कि दूसरा माउस "क्लिक किया गया" कब होता है - लेकिन मैं नहीं चाहता कि दूसरे एप्लिकेशन को क्लिक करने पर अन्य एप्लिकेशन जान सकें। – ChronoFish

1

अन्य लोगों को इस ने कहा है के रूप में डॉट नेट में बहुत कम परेशानी पर है:

यहाँ ऊपर के लिंक से नकल कोड है। मैं आपको यह सुनिश्चित करने के लिए अत्यधिक अनुशंसा करता हूं कि आप C++/Win32 पर स्विच करें। मुझे लगता है कि आप लंबे समय तक खुद को सिरदर्द बचाएंगे।

+0

हाँ आप सही हैं। यह वह मार्ग है जहां मैं जा रहा हूं ... लेकिन मेरी राय में, एमएस ने एपीआई का इतना खराब काम किया है कि यह सी ++ में प्रोग्रामिंग करता है। मैं इसे पूरा करने, लात मारने और अंत तक सभी तरह से चिल्लाना होगा। इस दिन और उम्र में रजिस्ट्री से बाहर निकलने के लिए यह छोटा होना चाहिए और इसे नियंत्रण में पोस्ट करना चाहिए - लेकिन आपको "कोउट" पर प्रिंट करने के लिए "एलपीसीटीस्ट्र" प्राप्त करने के लिए हुप्स के माध्यम से कूदना होगा .... – ChronoFish

+0

यदि आप वास्तव में सी ++ से बचना चाहते हैं तो आप वीबी 6 को आजमा सकते हैं। मैंने वीबी 6 और विन 32 पर अपने दांत काट दिया :) जहां तक ​​मुझे याद है कि यह Win32 एपिस के साथ काम करने में काफी प्रभावी है (लेकिन कुछ हद तक लैंगेज के रूप में सीमित है)। दूसरी बड़ी बात यह है कि यह थोड़ी देर के आसपास रहा है, और अभी भी बहुत उपयोग किया जाता है, वहां भी बहुत अच्छे दस्तावेज हैं। –