Pertanyaan Anda menarik minat saya, jadi saya telah melakukan sedikit penggalian dan sementara, sayangnya saya tidak memiliki jawaban yang tepat untuk Anda, saya pikir saya akan membagikan apa yang saya miliki.
Saya menemukan contoh pembuatan hook keyboard ini (dalam Delphi) yang ditulis pada tahun 1998, tetapi dapat dikompilasi di Delphi 2007 dengan beberapa tweak.
Ini adalah DLL dengan panggilan ke SetWindowsHookEx
yang melewati fungsi panggilan balik, yang kemudian dapat menghalangi penekanan tombol: Dalam hal ini, ia mengotak-atiknya untuk bersenang-senang, mengubah kursor kiri ke kanan, dll. Sebuah aplikasi sederhana kemudian memanggil DLL dan melaporkan kembali hasilnya berdasarkan acara TTimer. Jika Anda tertarik, saya dapat memposting kode berbasis Delphi 2007.
Ini didokumentasikan dan dikomentari dengan baik dan Anda berpotensi dapat menggunakannya sebagai dasar untuk menentukan ke mana penekanan tombol akan dilakukan. Jika Anda bisa mendapatkan pegangan aplikasi yang mengirim penekanan tombol, Anda dapat melacaknya kembali seperti itu. Dengan pegangan itu Anda akan bisa mendapatkan informasi yang Anda butuhkan dengan cukup mudah.
Aplikasi lain telah mencoba menentukan tombol pintas dengan menelusuri Pintasannya karena dapat berisi tombol Pintasan, yang merupakan istilah lain untuk tombol pintas. Namun sebagian besar aplikasi tidak cenderung menyetel properti ini sehingga mungkin tidak mengembalikan banyak. Jika Anda tertarik dengan rute itu, Delphi memiliki akses ke IShellLink
antarmuka COM yang dapat Anda gunakan untuk memuat pintasan dan mendapatkan hotkey-nya:
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;
Jika Anda memiliki akses ke Buku Safari Online , ada bagian bagus tentang bekerja dengan pintasan / tautan shell di Panduan Pengembang Borland Delphi 6 oleh Steve Teixeira dan Xavier Pacheco. Contoh saya di atas adalah versi yang dibantai dari sana dan situs ini .
Semoga membantu!
WM_HOTKEY
pesan di log Pesan setelah menekan tombol pintas, Anda mungkin perlu menjalankan Spy ++ versi 32-bit .Setelah beberapa penelitian, tampaknya Anda perlu mendapatkan akses ke struktur internal yang digunakan MS untuk menyimpan hotkey. ReactOS memiliki implementasi ruang bersih yang mengimplementasikan
GetHotKey
panggilan dengan mengulang daftar internal dan mengekstrak hotkey yang cocok dengan parameter panggilan.Bergantung pada seberapa dekat implementasi ReactOS dengan implementasi MS, Anda mungkin dapat melihat-lihat dalam memori untuk menemukan strukturnya, tapi itu di luar kepala saya ...
Saya kira utas tentang sysinternals ini ditanyakan oleh seseorang yang terkait dengan pertanyaan ini, tetapi saya pikir saya akan menautkannya untuk menjaga keduanya tetap bersama. Utasnya terlihat sangat menarik, tetapi saya menduga bahwa beberapa spelunking yang mendalam perlu terjadi untuk mengetahui hal ini tanpa akses ke internal MS.
sumber
Di luar kepalaku, Anda dapat mencoba menghitung semua jendela dengan EnumWindows, lalu di callback, kirim WM_GETHOTKEY ke setiap jendela.
Edit: Sepertinya saya salah tentang itu. MSDN memiliki lebih banyak informasi:
Catatan: Berikut adalah program yang mengaku memiliki fungsionalitas yang Anda cari. Anda dapat mencoba membongkar itu.
sumber
Ini sepertinya memberi tahu Anda banyak hal: http://hkcmdr.anymania.com/help.html
sumber
hoo
kegunaanSetWindowHookEx
untuk mengatur dua kait, satuWH_KEYBOARD_LL
dan satuWH_GETMESSAGE
... sisanya harus cukup banyak didokumentasikan di MSDN.Utas lain menyebutkan pengait keyboard tingkat NT global:
Tetapkan ulang / timpa hotkey (Win + L) untuk mengunci jendela
mungkin Anda bisa mendapatkan pegangan dari proses yang disebut hook seperti itu, yang kemudian bisa Anda selesaikan ke nama proses
(penafian: Saya memilikinya di bookmark saya, belum benar-benar mencoba / menguji)
sumber
Saya tahu Anda dapat mencegat aliran pesan di jendela mana pun dalam proses Anda sendiri - apa yang biasa kami sebut subclassing di VB6. (Meskipun saya tidak ingat fungsinya, mungkin SetWindowLong?) Saya tidak yakin apakah Anda dapat melakukan ini untuk windows di luar proses Anda sendiri. Tetapi demi posting ini mari kita asumsikan Anda menemukan cara untuk melakukan itu. Kemudian Anda cukup mencegat pesan untuk semua jendela tingkat atas, memantau pesan WM_HOTKEY. Anda tidak akan bisa langsung mengetahui semua tombol, tapi saat ditekan, Anda bisa dengan mudah mengetahui aplikasi apa yang menggunakannya. Jika Anda mempertahankan hasil Anda ke disk dan memuat ulang setiap kali aplikasi monitor Anda dijalankan, Anda dapat meningkatkan kinerja aplikasi Anda dari waktu ke waktu.
sumber
Ini tidak benar-benar menjawab bagian dari pertanyaan tentang Windows API, tetapi menjawab bagian dari pertanyaan tentang daftar hotkey global dan aplikasi yang "memiliki" mereka.
Hotkey Explorer gratis di http://hkcmdr.anymania.com/ menampilkan daftar semua hotkey global dan aplikasi yang memilikinya. Ini hanya membantu saya mencari tahu mengapa tombol pintas khusus aplikasi berhenti berfungsi dan cara memperbaikinya (dengan mengkonfigurasi ulang tombol pintas global terdaftar di aplikasi yang telah mendaftarkannya), dalam beberapa detik.
sumber