delphi पता लगाएं कि किस प्रक्रिया ने ग्लोबल हॉटकी पंजीकृत की है?(विंडोज एपीआई)




winapi api (8)

जहां तक ​​मैं पता लगाने में सक्षम हूं, विंडोज़ एक एपीआई फ़ंक्शन प्रदान नहीं करता है यह बताने के लिए कि किस एप्लिकेशन ने ग्लोबल हॉटकी पंजीकृत किया है (RegisterHotkey के माध्यम से)। मैं केवल यह पता लगा सकता हूं कि अगर हॉटकी पंजीकृत हो जाती है तो हॉटकी पंजीकृत होती है, लेकिन हॉटकी का "मालिक" कौन नहीं है।

प्रत्यक्ष एपीआई की अनुपस्थिति में, क्या एक चौराहे का रास्ता हो सकता है? विंडोज प्रत्येक पंजीकृत हॉटकी से जुड़े हैंडल को बनाए रखता है - यह थोड़ा सा गड़बड़ है कि इस जानकारी को प्राप्त करने का कोई तरीका नहीं होना चाहिए।

ऐसा कुछ उदाहरण जो संभवतः काम नहीं करेगा: एक पंजीकृत हॉटकी भेजें (अनुकरण करें), फिर हॉटकी संदेश को अवरुद्ध करें Windows इसे पंजीकृत प्रक्रिया में भेज देगा। सबसे पहले, मुझे नहीं लगता कि संदेश को अवरुद्ध करने से गंतव्य विंडो हैंडल प्रकट होगा। दूसरा, भले ही यह संभव था, यह करना एक बुरी बात होगी, क्योंकि हॉटकी भेजना विभिन्न कार्यक्रमों से संभावित रूप से अवांछित गतिविधि के सभी प्रकारों को ट्रिगर करेगा।

यह कुछ भी महत्वपूर्ण नहीं है, लेकिन मैंने ऐसी कार्यक्षमता के लिए लगातार अनुरोध देखे हैं, और मैं उन अनुप्रयोगों का शिकार रहा हूं जो यूआई या दस्तावेज़ों में कहीं भी इसे प्रकट किए बिना हॉटकी पंजीकृत करते हैं।

(डेल्फी में काम करना, और WinAPI में एक प्रशिक्षु से अधिक नहीं, कृपया दयालु रहें।)


एक और धागा वैश्विक एनटी स्तर कीबोर्ड हुक का उल्लेख करता है:

विंडोज़ लॉक करने के लिए हॉटकी (विन + एल) को फिर से असाइन / ओवरराइड करें

हो सकता है कि आप उस प्रक्रिया के हैंडल को प्राप्त कर सकें जिसे हुक कहा जाता है, जिसे आप प्रक्रिया नाम के लिए हल कर सकते हैं

(अस्वीकरण: मेरे पास यह मेरे बुकमार्क में था, वास्तव में कोशिश नहीं की / परीक्षण नहीं किया है)


कुछ शोध के बाद, ऐसा प्रतीत होता है कि आपको आंतरिक संरचना तक पहुंच प्राप्त करने की आवश्यकता होगी जिसे एमएस हॉटकी को स्टोर करने के लिए उपयोग करता है। रेक्टोस में एक साफ कमरा कार्यान्वयन है जो एक आंतरिक सूची को GetHotKey करके और हॉटकी को निकालने के लिए GetHotKey कॉल को लागू करता है GetHotKey कॉल के पैरामीटर से मेल खाता है।

एमएस कार्यान्वयन के लिए ReactOS का कार्यान्वयन कितना करीब है, इस पर निर्भर करता है कि आप संरचना को खोजने के लिए स्मृति में चारों ओर पोक करने में सक्षम हो सकते हैं, लेकिन यह मेरे सिर पर है ...

BOOL FASTCALL
GetHotKey (UINT fsModifiers,
           UINT vk,
           struct _ETHREAD **Thread,
           HWND *hWnd,
           int *id)
{
   PHOT_KEY_ITEM HotKeyItem;

   LIST_FOR_EACH(HotKeyItem, &gHotkeyList, HOT_KEY_ITEM, ListEntry)
   {
      if (HotKeyItem->fsModifiers == fsModifiers &&
            HotKeyItem->vk == vk)
      {
         if (Thread != NULL)
            *Thread = HotKeyItem->Thread;

         if (hWnd != NULL)
            *hWnd = HotKeyItem->hWnd;

         if (id != NULL)
            *id = HotKeyItem->id;

         return TRUE;
      }
   }

   return FALSE;
}

मुझे लगता है कि इस धागे से इस प्रश्न से संबंधित किसी व्यक्ति द्वारा सिसिनरल्स पर पूछा गया था, लेकिन मैंने सोचा कि मैं दोनों को एक साथ रखने के लिए इसे लिंक करूँगा। धागा बहुत दिलचस्प लग रहा है, लेकिन मुझे संदेह है कि कुछ गहरे गोताखोर स्पेलंकिंग को एमएस आंतरिकों तक पहुंच के बिना इसे समझने की आवश्यकता होगी।


यह वास्तव में Windows API के बारे में प्रश्न के उस हिस्से का उत्तर नहीं देता है, लेकिन यह उस प्रश्न के हिस्से का उत्तर देता है जो वैश्विक हॉटकी की सूची और उन अनुप्रयोगों के बारे में है जो "स्वयं" हैं।

http://hkcmdr.anymania.com/ पर मुफ्त हॉटकी एक्सप्लोरर सभी वैश्विक हॉटकी और उनके स्वामित्व वाले अनुप्रयोगों की एक सूची दिखाता है। इसने मुझे यह समझने में मदद की है कि एप्लिकेशन-विशिष्ट शॉर्टकट कुंजी ने कुछ सेकंड के भीतर काम करना बंद कर दिया है और इसे कैसे ठीक किया है (पंजीकृत ग्लोबल हॉटकी को पंजीकृत करने वाले ऐप में पुन: कॉन्फ़िगर करना)।


आपके प्रश्न ने मेरी रूचि पिक्चर की है, इसलिए मैंने कुछ खोदने का काम किया है और, दुर्भाग्यवश मेरे पास आपके लिए उचित जवाब नहीं है, मैंने सोचा कि मैं जो साझा करता हूं वह साझा करता हूं।

मुझे 1 99 8 में लिखे गए कीबोर्ड हुक (डेल्फी में) बनाने का यह उदाहरण मिला, लेकिन कुछ बदलावों के साथ डेल्फी 2007 में संकलित है।

यह एक डीएलएल है जो SetWindowsHookEx को कॉल करता है जो कॉलबैक फ़ंक्शन से गुज़रता है, जो तब कुंजी स्ट्रोक को रोक सकता है: इस मामले में, यह मजेदार के लिए उनके साथ टंकण कर रहा है, बाएं कर्सर को दाएं बदल रहा है, आदि। एक साधारण ऐप फिर डीएलएल और रिपोर्ट को कॉल करता है टीटीमर घटना के आधार पर इसके परिणाम वापस करें। यदि आप रुचि रखते हैं तो मैं डेल्फी 2007 आधारित कोड पोस्ट कर सकता हूं।

यह अच्छी तरह से प्रलेखित और टिप्पणी की गई है और आप संभावित रूप से इसे काम करने के आधार के रूप में उपयोग कर सकते हैं जहां एक महत्वपूर्ण प्रेस चल रही है। यदि आप कुंजी स्ट्रोक भेजे गए एप्लिकेशन के हैंडल प्राप्त कर सकते हैं, तो आप इसे इस तरह से ट्रैक कर सकते हैं। उस हैंडल के साथ आप जो जानकारी आपको आसानी से प्राप्त कर सकते हैं उसे प्राप्त करने में सक्षम होंगे।

अन्य ऐप्स ने अपने शॉर्टकट्स के माध्यम से हॉटकी को निर्धारित करने का प्रयास किया है क्योंकि उनमें शॉर्टकट कुंजी हो सकती है, जो हॉटकी के लिए एक और शब्द है। हालांकि अधिकांश एप्लिकेशन इस संपत्ति को सेट नहीं करते हैं, इसलिए यह अधिक वापस नहीं आ सकता है। यदि आप उस मार्ग में रुचि रखते हैं, तो डेल्फी के पास IShellLink COM इंटरफ़ेस तक पहुंच है जिसका उपयोग आप शॉर्टकट को लोड करने और अपनी हॉटकी प्राप्त करने के लिए कर सकते हैं:

uses ShlObj, ComObj, ShellAPI, ActiveX, CommCtrl;

procedure GetShellLinkHotKey;
var
  LinkFile : WideString;
  SL: IShellLink;
  PF: IPersistFile;

  HotKey : Word;
  HotKeyMod: Byte;
  HotKeyText : string;
begin
  LinkFile := 'C:\Temp\Temp.lnk';

  OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL));

  // The IShellLink implementer must also support the IPersistFile
  // interface. Get an interface pointer to it.
  PF := SL as IPersistFile;

  // Load file into IPersistFile object
  OleCheck(PF.Load(PWideChar(LinkFile), STGM_READ));

  // Resolve the link by calling the Resolve interface function.
  OleCheck(SL.Resolve(0, SLR_ANY_MATCH or SLR_NO_UI));

  // Get hotkey info
  OleCheck(SL.GetHotKey(HotKey));

  // Extract the HotKey and Modifier properties.
  HotKeyText := '';
  HotKeyMod := Hi(HotKey);

  if (HotKeyMod and HOTKEYF_ALT) = HOTKEYF_ALT then
    HotKeyText := 'ALT+';
  if (HotKeyMod and HOTKEYF_CONTROL) = HOTKEYF_CONTROL then
    HotKeyText := HotKeyText + 'CTRL+';
  if (HotKeyMod and HOTKEYF_SHIFT) = HOTKEYF_SHIFT then
    HotKeyText := HotKeyText + 'SHIFT+';
  if (HotKeyMod and HOTKEYF_EXT) = HOTKEYF_EXT then
    HotKeyText := HotKeyText + 'Extended+';

  HotKeyText := HotKeyText + Char(Lo(HotKey));

  if (HotKeyText = '') or (HotKeyText = #0) then
    HotKeyText := 'None';

  ShowMessage('Shortcut Key - ' + HotKeyText);
end;

अगर आपको सफारी बुक्स ऑनलाइन तक पहुंच मिली है, तो स्टीव टेक्सीरा और जेवियर पैचेको द्वारा बोर्लैंड डेल्फी 6 डेवलपर गाइड में शॉर्टकट / शैल लिंक के साथ काम करने के बारे में एक अच्छा अनुभाग है । मेरा उदाहरण ऊपर और इस साइट से एक कुचला हुआ संस्करण है।

उम्मीद है की वो मदद करदे!



मेरे सिर के ऊपर से, आप EnumWindows के साथ सभी विंडो को गिनने का प्रयास कर सकते हैं, फिर कॉलबैक में, प्रत्येक विंडो में WM_GETHOTKEY भेजें।

संपादित करें: इसके विपरीत मैं इसके बारे में गलत था। MSDN में अधिक जानकारी है:

WM_HOTKEY WM_GETHOTKEY और WM_SETHOTKEY हॉट कुंजी से असंबंधित है। WM_HOTKEY संदेश जेनेरिक हॉट कुंजी के लिए भेजा जाता है जबकि WM_SETHOTKEY और WM_GETHOTKEY संदेश विंडो सक्रियण हॉट कुंजी से संबंधित होते हैं।

नोट: Here एक प्रोग्राम है जो आप जिस कार्यक्षमता की तलाश में हैं उसे प्राप्त करने के लिए कह रहे हैं। आप इसे कम करने की कोशिश कर सकते हैं।


विजुअल स्टूडियो टूल स्पाई ++ का उपयोग करने का एक संभावित तरीका है।

इसे आज़माएं:

  1. टूल चलाएं (मेरे लिए, यह C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\spyxx_amd64.exe )
  2. मेनू बार में, जासूस -> लॉग संदेश चुनें ... (या Ctrl + M दबाएं )
  3. अतिरिक्त विंडोज फ्रेम में सिस्टम में सभी विंडोज़ की जांच करें
  4. संदेश टैब पर स्विच करें
  5. सभी बटन साफ़ करें पर क्लिक करें
  6. सूची WM_HOTKEY में WM_HOTKEY का चयन करें, या संदेश समूह में कीबोर्ड जांचें (यदि आप अधिक संभावित शोर के साथ ठीक हैं)
  7. ठीक बटन पर क्लिक करें
  8. प्रश्न में हॉटकी दबाएं (उदाहरण के लिए विन + आर )
  9. संदेश (सभी विंडोज़) विंडो में WM_HOTKEY लाइन का चयन करें, राइट क्लिक करें, और गुण मेनू का चयन करें ... संदर्भ मेनू में
  10. संदेश गुण संवाद में, विंडो हैंडल लिंक पर क्लिक करें (यह संदेश प्राप्त करने वाली विंडो के लिए हैंडल होगा)
  11. विंडो गुण संवाद पर सिंक्रनाइज़ करें बटन पर क्लिक करें। यह विंडो को मुख्य जासूस ++ विंडो ट्रीव्यू में दिखाएगा।
  12. विंडो गुण संवाद पर, प्रक्रिया टैब का चयन करें
  13. प्रक्रिया आईडी लिंक पर क्लिक करें। यह आपको प्रक्रिया दिखाएगा (मेरे विन + आर मामले में: EXPLORER )

मैं कुछ वर्षों तक हार्ड-कोर विंडोज उपयोगकर्ता नहीं रहा हूं (मै मैक पर स्विच किया गया)। लेकिन मैं प्रक्रिया एक्सप्लोरर द्वारा कसम खाता था कि यह पता लगाने के लिए कि कौन सी प्रक्रिया किसी विशेष फ़ाइल का उपयोग कर रही है, जिसे मैं हटाने की कोशिश कर रहा था। शायद यह पता लगाने में मदद करता है कि कौन सी प्रक्रिया गर्म कुंजी का उपयोग करती है?