2012-05-11 15 views
5

Estoy tratando de poner un icono en la bandeja del sistema y luego darle un atajo de teclado global para llevar a cabo una función.RegisterHotKey no funciona con formularios invisibles (C#)

Estoy utilizando RegisterHotKey para establecer el atajo de teclado global, y funciona si el formulario principal asociado con el icono es visible. Pero si la forma es invisible, entonces el método WndProc nunca se invoca.

¿Alguna idea?

Editar: Lo que quiero decir con "oculta" es que se añade lo siguiente a la forma principal:

protected override void OnLoad(EventArgs e) 
{ 
    hotKey = new GlobalHotkey(GlobalHotkey.WIN, Keys.T, this); 
    bool registered = hotKey.Register(); 
    Visible = false; 
    ShowInTaskbar = false; 
    base.OnLoad(e); 
} 

"registrado" se muestra como "verdadero", y las obras clave de acceso directo bien si omita el "Visible = falso"; y el "ShowInTaskbar = false;"

+2

¿Puedes mostrar un código de muestra de lo que has probado? – ImGreg

+0

sí, muestre su código porque no debería haber diferencia si el parámetro RegisterHotKey HWND es invisible, los mensajes aún se procesan –

+0

No podrá registrar una tecla de acceso directo antes de que se cree la ventana. ¿Es eso lo que quieres decir con "visible"? –

Respuesta

4

Winforms funciona alrededor de una restricción bastante draconiana en el winapi. Algunas propiedades de una ventana solo se pueden especificar cuando se crea una ventana y no se pueden cambiar más adelante. O, en otras palabras, se especifican en la llamada nativa CreateWindowEx().

Funciona a su alrededor llamando nuevamente a CreateWindowEx(). O en otras palabras, destruir la ventana existente y crearla de nuevo. Es un truco ingenioso pero tiene algunos efectos secundarios. Puede ver un poco de parpadeo, por ejemplo, cuando la nueva ventana se pinta sola. Algunos efectos secundarios más grandes son visibles en, por ejemplo, un TreeView. Todos los nodos colapsan cuando se vuelve a crear. Es difícil de evitar, simplemente hay demasiado estado asociado con la ventana original. Para un formulario, la propiedad ShowInTaskbar es una de esas propiedades. Pero también RightToLeft, FormBorderStyle, ControlBox, etcétera.

El efecto secundario más relevante es el que se está ejecutando. Volver a crear la ventana siempre cambia la propiedad Manejar, inevitablemente. Y eso va mal cuando usa RegisterHotKey(), o una biblioteca que lo usa, esa llamada winapi utiliza el identificador de ventana. Entonces, cuando Winforms destruye esa ventana, nunca más habrá una devolución de llamada.

Es fácil de arreglar, solo está utilizando el controlador de eventos incorrecto. Realice la llamada en una anulación para el método OnHandleCreated en su lugar. Se vuelve a ejecutar cuando la ventana se vuelve a crear. Otra solución fácil, pero no tan confiable, es establecer propiedades como ShowInTaskbar en el constructor.

4

El problema es que si se establece ShowInTaskbar en los cambios falsos, el manejador de la ventana, lo que significa que el hwnd pasado a RegisterHotkey ya no es válido.

Registro de la tecla de acceso directo después de configuración ShowInTaskBar funciona bien.