teclas teclado tecla sirve rapido que para orientacion idioma como cambiar atajos atajo acento acceso delphi winapi api hotkeys registerhotkey

delphi - teclado - Descubra qué proceso registró una tecla de acceso rápido global(API de Windows)



teclas de acceso rapido para orientacion en excel (9)

Por lo que he podido averiguar, Windows no ofrece una función de API para indicar qué aplicación ha registrado una tecla de acceso rápido global (a través de RegisterHotkey). Solo puedo descubrir que se ha registrado una tecla de acceso rápido si RegisterHotkey devuelve falso, pero no quién "posee" la tecla de acceso rápido.

En ausencia de una API directa, ¿podría haber una manera indirecta? Windows mantiene el identificador asociado con cada tecla de acceso registrada - es un poco enloquecedor que no haya forma de obtener esta información.

Ejemplo de algo que probablemente no funcionaría: enviar (simular) una tecla de acceso rápido registrada, luego interceptar el mensaje de acceso rápido que Windows enviará al proceso que lo registró. Primero, no creo que interceptar el mensaje revele el identificador de la ventana de destino. En segundo lugar, incluso si fuera posible, sería algo malo de hacer, ya que enviar atajos de teclado desencadenaría todo tipo de actividad potencialmente no deseada de varios programas.

No es nada crítico, pero he visto solicitudes frecuentes de dicha funcionalidad, y he sido víctima de aplicaciones que registran teclas de acceso directo sin siquiera divulgarlas en ningún lugar de la interfaz de usuario o documentos.

(Trabajando en Delphi, y no más que un aprendiz en WinAPI, por favor sea amable).


Después de algunas investigaciones, parece que necesitarás acceder a la estructura interna que MS usa para almacenar las teclas rápidas. ReactOS tiene una implementación de sala limpia que implementa la llamada GetHotKey iterando una lista interna y extrayendo la tecla de GetHotKey que coincide con los parámetros de la llamada.

Dependiendo de qué tan cerca esté la implementación de ReactOS de la implementación de MS, es posible que pueda hurgar en la memoria para encontrar la estructura, pero eso está por encima de mi cabeza ...

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

Supongo que este hilo en sysinternals fue preguntado por alguien relacionado con esta pregunta, pero pensé que lo vincularía de todos modos para mantener los dos juntos. El hilo parece muy intrigante, pero sospecho que sería necesario realizar una espeleología de inmersión profunda para resolver esto sin tener acceso a los internos de MS.


Esto no responde exactamente a la parte de la pregunta que trata sobre la API de Windows, pero responde la parte de la pregunta que trata acerca de una lista de teclas rápidas globales y las aplicaciones que las "poseen".

El Hotkey Explorer gratuito en http://hkcmdr.anymania.com/ muestra una lista de todas las teclas rápidas globales y las aplicaciones que las poseen. Esto me ayudó a descubrir por qué una tecla de acceso directo específica de la aplicación dejó de funcionar y cómo solucionarlo (al reconfigurar la tecla de acceso rápido registrada en la aplicación que la tenía registrada), en unos pocos segundos.



Fuera de la cabeza, podrías intentar enumerar todas las ventanas con EnumWindows, luego en la devolución de llamada, enviar WM_GETHOTKEY a cada ventana.

Editar: Aparentemente estaba equivocado sobre eso. MSDN tiene más información:

WM_HOTKEY no está relacionado con las teclas de acceso rápido WM_GETHOTKEY y WM_SETHOTKEY. El mensaje WM_HOTKEY se envía para teclas rápidas genéricas, mientras que los mensajes WM_SETHOTKEY y WM_GETHOTKEY se relacionan con las teclas rápidas de activación de ventana.

Nota: Here hay un programa que pretende tener la funcionalidad que está buscando. Podrías tratar de descompilarlo.


No he sido un usuario hard-windows durante algunos años (cambié a Mac). Pero solía jurar por Process Explorer para averiguar qué proceso está usando un archivo particular que estaba tratando de eliminar. Tal vez ayude a averiguar qué proceso utiliza una tecla de acceso rápido.



Sé que puede interceptar el flujo de mensajes en cualquier ventana dentro de su propio proceso, lo que solíamos llamar subclases en VB6. (Aunque no recuerdo la función, ¿quizás SetWindowLong?) No estoy seguro si puede hacer esto para Windows fuera de su propio proceso. Pero por el bien de esta publicación, supongamos que encuentras una manera de hacerlo. Luego puede simplemente interceptar los mensajes para todas las ventanas de nivel superior, monitorear el mensaje WM_HOTKEY. No podrías conocer todas las claves desde el principio, pero a medida que las presionas puedes averiguar fácilmente qué aplicación las está usando. Si persistió en sus resultados en el disco y los recargó cada vez que ejecutó la aplicación del monitor, podría aumentar el rendimiento de la aplicación a lo largo del tiempo.


Tu pregunta despertó mi interés, así que he investigado un poco y, aunque lamentablemente no tengo una respuesta adecuada para ti, pensé que compartiría lo que tengo.

Encontré este ejemplo de creación de gancho de teclado (en Delphi) escrito en 1998, pero es compilable en Delphi 2007 con un par de ajustes.

Es una DLL con una llamada a SetWindowsHookEx que pasa a través de una función de devolución de llamada, que luego puede interceptar pulsaciones de teclas: en este caso, está jugando con ellas por diversión, cambiando el cursor izquierdo a la derecha, etc. Una aplicación simple llama al DLL e informa respalda sus resultados basados ​​en un evento TTimer. Si está interesado, puedo publicar el código basado en Delphi 2007.

Está bien documentado y comentado, y es posible que lo utilice como base para determinar dónde va la pulsación de tecla. Si pudieras obtener el control de la aplicación que envió las pulsaciones de tecla, podrías rastrearlo de esa manera. Con ese mango, podrá obtener la información que necesita con bastante facilidad.

Otras aplicaciones han intentado determinar las teclas de acceso rápido a través de sus accesos directos, ya que pueden contener una tecla de acceso directo, que es simplemente otro término para la tecla de acceso directo. Sin embargo, la mayoría de las aplicaciones no tienden a establecer esta propiedad, por lo que es posible que no devuelva demasiado. Si está interesado en esa ruta, Delphi tiene acceso a la interfaz COM de IShellLink que puede usar para cargar un acceso directo y obtener su tecla de acceso directo:

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;

Si tiene acceso a Safari Books Online , hay una buena sección sobre cómo trabajar con accesos directos / enlaces shell en la Guía del desarrollador de Borland Delphi 6 por Steve Teixeira y Xavier Pacheco. Mi ejemplo anterior es una versión eliminada de allí y de este sitio .

¡Espero que ayude!


Una posible forma es usar la herramienta de Visual Studio Spy ++ .

Prueba esto:

  1. Ejecute la herramienta (para mí, está en C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/Tools/spyxx_amd64.exe )
  2. En la barra de menú, selecciona Espía -> Registrar mensajes ... (o presiona Ctrl + M )
  3. Verifique todas las ventanas en el sistema en el marco adicional de Windows
  4. Cambia a la pestaña Mensajes
  5. Haga clic en el botón Borrar todo
  6. Seleccione WM_HOTKEY en el cuadro de lista o revise Teclado en Grupos de mensajes (si está bien con más ruido potencial)
  7. Haga clic en el botón Aceptar
  8. Presiona la tecla rápida en cuestión ( Win + R , por ejemplo)
  9. Seleccione la línea WM_HOTKEY en la ventana Mensajes (Todas las ventanas) , haga clic con el botón derecho y seleccione Propiedades ... en el menú contextual
  10. En el cuadro de diálogo Propiedades del mensaje , haga clic en el enlace Manejador de ventana (este será el identificador de la ventana que recibió el mensaje)
  11. Haga clic en el botón Sincronizar en el cuadro de diálogo Propiedades de ventana. Esto mostrará la ventana en la vista de árbol de la ventana principal de Spy ++.
  12. En el cuadro de diálogo Propiedades de ventana, seleccione la pestaña Proceso
  13. Haga clic en el enlace ID de proceso . Esto le mostrará el proceso (en mi caso Win + R : EXPLORER )