Hangi işlemin küresel bir kısayol tuşu kaydettiğini öğrenin? (Windows API)


114

Bulabildiğim kadarıyla Windows, hangi uygulamanın küresel bir kısayol tuşu kaydettiğini (RegisterHotkey aracılığıyla) söylemek için bir API işlevi sunmuyor. Sadece RegisterHotkey false döndürürse bir kısayol tuşunun kaydedildiğini, ancak kısayol tuşuna kimin "sahip olduğunu" öğrenemiyorum.

Doğrudan bir API yokluğunda, dolambaçlı bir yol olabilir mi? Windows, kayıtlı her kısayol tuşuyla ilişkili tutamacı korur - bu bilgiye ulaşmanın hiçbir yolu olmaması biraz çıldırtıcıdır.

Muhtemelen çalışmayacak bir şeye örnek: kayıtlı bir kısayol tuşu gönderin (simüle edin), ardından Windows'un onu kaydettiren işleme göndereceği kısayol tuşu mesajını yakalayın. İlk olarak, mesajı yakalamanın hedef pencere tutamacını ortaya çıkaracağını düşünmüyorum. İkincisi, mümkün olsa bile, kısayol tuşları göndermek çeşitli programlardan her tür potansiyel olarak istenmeyen etkinliği tetikleyeceği için yapılması kötü bir şey olurdu.

Kritik bir şey değil, ancak bu tür işlevsellik için sık sık istekler gördüm ve kendim, kullanıcı arayüzünde veya belgelerde herhangi bir yerde ifşa etmeden kısayol tuşlarını kaydeden uygulamaların kurbanı oldum.

(Delphi'de çalışıyor ve WinAPI'de bir çıraktan fazlası değil, lütfen nazik olun.)

Yanıtlar:


20

Sorunuz ilgimi çekti, bu yüzden biraz araştırma yaptım ve maalesef sizin için uygun bir cevabım yokken, sahip olduğum şeyi paylaşacağımı düşündüm.

Bu klavye kancası (Delphi'de) oluşturma örneğini 1998'de buldum, ancak Delphi 2007'de birkaç ince ayar ile derlenebilir.

Bu SetWindowsHookEx, bir geri arama işlevinden geçen bir çağrıya sahip bir DLL'dir ve daha sonra tuş vuruşlarını kesebilir: Bu durumda, eğlenmek için onlarla uğraşıyor, sol imleci sağa çeviriyor vb. Daha sonra basit bir uygulama, DLL'yi çağırır ve geri rapor verir. TTimer olayına dayalı sonuçları. Eğer ilgilenirseniz, Delphi 2007 tabanlı kodu gönderebilirim.

İyi belgelenmiş ve yorumlanmıştır ve potansiyel olarak bir tuşa basmanın nereye gittiğini bulmanın temeli olarak kullanabilirsiniz. Tuş vuruşlarını gönderen uygulamanın tanıtıcısını bulabilirseniz, o şekilde geriye doğru takip edebilirsiniz. Bu tutamaç ile ihtiyacınız olan bilgileri oldukça kolay bir şekilde elde edebilirsiniz.

Diğer uygulamalar, kısayol tuşu için başka bir terim olan bir Kısayol tuşu içerebildiklerinden, Kısayollarından geçerek kısayol tuşlarını belirlemeye çalıştı. Ancak çoğu uygulama bu özelliği ayarlama eğiliminde değildir, bu nedenle çok fazla geri dönmeyebilir. Bu rotayla ilgileniyorsanız, Delphi, IShellLinkbir kısayol yüklemek ve kısayol tuşunu almak için kullanabileceğiniz COM arayüzüne erişebilir :

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;

Safari Books Online'a erişiminiz varsa, Steve Teixeira ve Xavier Pacheco tarafından yazılan Borland Delphi 6 Geliştirici Kılavuzunda kısayollarla / kabuk bağlantılarıyla çalışma hakkında iyi bir bölüm var . Yukarıdaki örneğim oradan ve bu siteden kesilmiş bir versiyondur .

Umarım yardımcı olur!


59

Olası bir yol, Visual Studio aracı Spy ++ kullanmaktır .

Bunu bir deneyin:

  1. Aracı çalıştırın (benim için, şu anda C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\spyxx_amd64.exe)
  2. Menü çubuğunda, Casus -> Mesajları günlüğe kaydet ... öğesini seçin (veya Ctrl+ tuşuna basın M)
  3. Kontrol Sistemine Tüm Windows'u içinde Ek Windows çerçevesi
  4. Mesajlar sekmesine geçin
  5. Tümünü Temizle düğmesini tıklayın
  6. Seç WM_HOTKEYliste kutusunda, veya çek Klavye içinde İleti Grupları (eğer daha fazla potansiyel gürültü ediyoruz OK)
  7. Click OK tuşuna
  8. Söz konusu kısayol tuşuna basın ( örneğin Win+ R)
  9. Mesajlar (Tüm Pencereler) penceresindeki WM_HOTKEYsatırı seçin , sağ tıklayın ve içerik menüsünde Özellikler ... öğesini seçin.
  10. Gelen Mesaj Özellikleri iletişim kutusunda, tıklayın Pencere Kolu linki (Bu iletiyi pencere için tanıtıcı olacaktır)
  11. Pencere Özellikleri iletişim kutusundaki Senkronize Et düğmesini tıklayın . Bu, pencereyi ana Spy ++ pencere ağaç görünümünde gösterecektir.
  12. On Pencere Özellikleri iletişim kutusunda, seçmek Süreç sekmesini
  13. Click İşlem Kimliği linki. Bu (Benim içinde size süreci gösterir Win+ Rdurumda: EXPLORER)

6
Mükemmel cevap! Spy ++ 'nın 64 bit sürümünün yalnızca 64 bit uygulamalar için mesajları yakaladığını unutmayın. nedenle , kısayol tuşuna bastıktan sonra İleti günlüğündeWM_HOTKEY mesajı görmezseniz, Spy ++' nın 32 bit sürümünü çalıştırmanız gerekebilir. .
David Ferenczy Rogožan

ÇOK TEŞEKKÜR EDERİM!!! Bunu bulana kadar temelde bazı kısayolları kullanmaktan vazgeçtim.
thewindev

3
8. adımda kısayol tuşu sormaz, mesaj penceresi herhangi bir kısayol tuşuna bastıktan sonra boş kalmaya devam eder. Github.com/westoncampbell/SpyPlusPlus (Windows 10'da) adresinden 32 ve 64 bitlik sürümler kullanıldı .
CoolMind

9

Biraz araştırmadan sonra, MS'in kısayol tuşlarını depolamak için kullandığı dahili yapıya erişmeniz gerektiği anlaşılıyor. ReactOS, GetHotKeydahili bir listeyi yineleyerek ve parametrelerle eşleşen kısayol tuşunu çağrıya çıkararak çağrıyı gerçekleştiren bir temiz oda uygulamasına sahiptir .

ReactOS'un uygulamasının MS uygulamasına ne kadar yakın olduğuna bağlı olarak, yapıyı bulmak için hafızada dolaşabilirsiniz, ama bu benim kafamın üzerinde ...

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

Sanırım sysinternals bu parçacığı bu soruya ilişkin birileri tarafından istendi, ama ben iki buluşmanızı tutmak için yine ona bağlantı düşündüm. İş parçacığı çok ilgi çekici görünüyor, ancak MS iç bileşenlerine erişim olmadan bunu anlamak için derinlemesine inceleme yapılması gerektiğinden şüpheleniyorum.


3

Aklımın ucunda, EnumWindows ile tüm pencereleri numaralandırmayı deneyebilir, ardından geri aramada her pencereye WM_GETHOTKEY gönderebilirsiniz.

Düzenleme: Görünüşe göre bu konuda yanılmışım. MSDN daha fazla bilgiye sahiptir:

WM_HOTKEY, WM_GETHOTKEY ve WM_SETHOTKEY kısayol tuşları ile ilgisizdir. WM_HOTKEY mesajı genel kısayol tuşları için gönderilirken, WM_SETHOTKEY ve WM_GETHOTKEY mesajları pencere etkinleştirme kısayol tuşları ile ilgilidir.

Not: İşte aradığınız işlevselliğe sahip olduğunu iddia eden bir program. Onu yeniden derlemeyi deneyebilirsiniz.


3
Programın bağlantısı artık tamamen kesildi. Bu hangi programdı? Birçok kez kısayol tuşlarını hangi programın kaydettiğini anlamak isterdim çünkü aniden artık çalışmıyorlar veya can sıkıcı yeni şeyler yapıyorlar.
James Oltmans

(Genellikle, Wayback Makinesi, web sayfasının kaybolması durumunda yardımcı olabilir, ancak burada yalnızca 404 Bulunamadı: http://web.archive.org/web/*/tds.diamondcs.com.au/dse/ algılama / hotkeys.php )
Aaron Thoma

2

Bu size çok şey anlatıyor gibi görünüyor: http://hkcmdr.anymania.com/help.html


1
Yapar? Sürücü kılığına girmiş bir DLL mi? DLL işlevi , biri ve biri olmak üzere iki kanca ayarlamak için hookullanım olarak dışa aktarılan ... geri kalanı hemen hemen MSDN'de belgelenmelidir. SetWindowHookExWH_KEYBOARD_LLWH_GETMESSAGE
0xC0000022L

Bu uygulamayı Windows 8 veya 10'da kullanmayın.
Jeff Lange


0

VB6'da alt sınıflandırma dediğimiz şeyi, kendi sürecinizde herhangi bir pencerede mesaj akışını yakalayabileceğinizi biliyorum. (İşlevi hatırlamasam da, belki SetWindowLong?) Bunu, kendi işleminizin dışındaki pencereler için yapıp yapamayacağınızdan emin değilim. Ancak bu yazının iyiliği için, bunu yapmanın bir yolunu bulduğunuzu varsayalım. Daha sonra tüm üst düzey pencereler için mesajları yakalayabilir, WM_HOTKEY mesajını izleyebilirsiniz. Tüm tuşları hemen bilemezsiniz, ancak basıldıklarında hangi uygulamanın onları kullandığını kolayca anlayabilirsiniz. Sonuçlarınızı diske kaydetmeye devam ettiyseniz ve monitör uygulamanız her çalıştırıldığında yeniden yüklediyseniz, uygulamanızın performansını zaman içinde artırabilirsiniz.


-1

Bu, sorunun Windows API ile ilgili kısmına tam olarak cevap vermez, ancak sorunun küresel kısayol tuşlarının bir listesi ve onlara "sahip" olan uygulamalar hakkındaki kısmını yanıtlar.

Http://hkcmdr.anymania.com/ adresindeki ücretsiz Kısayol Tuşu Gezgini, tüm genel kısayol tuşlarının ve bunlara sahip olan uygulamaların bir listesini gösterir. Bu, uygulamaya özel bir kısayol tuşunun neden çalışmayı durdurduğunu ve nasıl düzeltileceğini (kayıtlı olan uygulamadaki kayıtlı genel kısayol tuşunu birkaç saniye içinde yeniden yapılandırarak) anlamama yardımcı oldu.


4
yükledim ve kötü bir şaka gibi en azından alışveriş merkezi amaçlı bir program gibi bir virüs gibi davrandı. Her türlü pencereyi açmak, ses ayırıcıyı etkinleştirmek vb.
Flion

3
@Flion: superuser.com/a/191090/3617 adresindeki tartışmaya bakın . Temel olarak, bazı kısayol tuşları olası her tuş kombinasyonunu araştırarak çalışır. Windows 8+ üzerinde (ve daha az bir ölçüde Windows 7'de), bu araştırma tekniği yalnızca sorgulamak yerine her tuş kombinasyonunu tetikler .
Brian

@Flion FWIW, Win7'de başarıyla kullandım. Ancak Brian'ı doğru anlarsam, bu daha sonraki sürümlerde de işe yaramayabilir ve ne kadar iyi çalıştığı, tanımlanan özel kısayol tuşlarına da bağlı olabilir.
Gerhard
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.