delphi menu delphi-2009 autohotkey acceleratorkey

Las teclas del acelerador de menús no se muestran(Delphi 2009)



menu delphi-2009 (4)

He intentado lo mejor posible y no puedo entender qué pasó aquí. Funcionó bien en Delphi 4. Después de actualizar a Delphi 2009, no sé si esta es la forma en que debería funcionar, o si es un problema:

Así es como se ve el menú de mi programa en el modo de diseño en Delphi 2009:

texto alternativo http://www.beholdgenealogy.com/img/menu1.gif

Tenga en cuenta que cada palabra en el menú principal y en el submenú Archivo tienen una letra subrayada. Se supone que es así. Esta letra subrayada se llama tecla de aceleración y es estándar en las aplicaciones de Windows para que pueda usar la tecla Alt y esa letra para seleccionar rápidamente el elemento del menú y luego submenú elemento con el teclado en lugar de con el mouse.

Los obtienes de esta manera al usar el carácter "&" como parte de la leyenda del artículo, por ejemplo: Guardar y como ...

Cuando ejecuto mi aplicación y uso el mouse para abrir el menú Archivo, se ve así:

texto alternativo http://www.beholdgenealogy.com/img/menu2.gif

Los caracteres están subrayados en el menú principal, pero no están subrayados en el menú Archivo.

Si, en cambio, utilizo la tecla Alt-F para abrir el submenú Archivo, entonces se ve correcto así:

texto alternativo http://www.beholdgenealogy.com/img/menu3.gif

y todas las letras de la tecla del acelerador están correctamente subrayadas.

He jugado con la opción AutoHotKeys, pero ese no es el problema.

¿Alguien ha encontrado este problema antes? ¿Es el ejemplo en la 2da imagen el comportamiento correcto que no conozco? ¿O hay alguna opción o error de codificación que podría haber pasado por alto?

Nov 2009 (un año después): mghie parece haber llegado a la raíz de esto y resolvió el problema. Vea su respuesta aceptada a continuación.


No creo que sea un error generado por Delphi ya que tiene el mismo comportamiento con Notepad en Vista. También en Delphi mismo BTW ...
Debo confesar que no presté atención antes de su pregunta. Gracias por mencionarlo.


Es una "característica" presentada con Windows 2000:

The Old New Thing: ¿Por qué Windows oculta los aceleradores de teclado y los rectángulos de enfoque de forma predeterminada?

Parece que Delphi 4 no es compatible con esta característica de Windows.

Para que los menús 2000 y XP muestren las teclas aceleradoras, haga clic con el botón derecho en un lugar vacío en el escritorio, elija Propiedades, haga clic en la pestaña Apariencia y en Efectos, desmarque Ocultar letras subrayadas para la navegación del teclado hasta presionar la tecla Alt . Haga clic en Aceptar dos veces.

No estoy seguro de cómo hacerlo en Vista.


Como Jim McKeeth señaló anteriormente (correctamente), este es el comportamiento "por diseño". Si los menús se activan a través de la acción del teclado, se deben mostrar los aceleradores, pero si se activan con el mouse, los aceleradores no se muestran intencionalmente.

Tengo mi XP configurado para mostrar aceleradores en todo momento, pero una prueba rápida con esa opción modificada confirma que los menús tampoco deberían mostrar subrayados (Visual Studio respondió como esperaba, sin subrayar cuando se usa el mouse). Sin embargo, Microsoft Office ignora esta configuración y siempre muestra los subrayados. Por lo tanto, parece un error sobre cómo se dibujan los menús en Delphi (no tengo ninguna experiencia con Delphi).

También encontré la opción para Vista: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html

Puede activarlo en el nuevo Centro de facilidad de acceso (vaya a Panel de control, haga clic en Facilidad de acceso y luego en Centro de facilidad de acceso). En el Centro de facilidad de acceso, haga clic en Hacer que el teclado sea más fácil de usar, y en la parte inferior, seleccione la casilla de verificación Subrayar atajos de teclado y teclas de acceso.

Mientras investigaba más, encontré esta falla relacionada en los foros de Delphi: http://qc.codegear.com/wc/qcmain.aspx?d=37403

Parece que en su caso las ventanas secundarias (los menús dibujados) no reciben o no están manejando el mensaje WM_UIUPDATESTATE desde su ventana principal, que es lo que causa el redibujado con aceleradores.


Hay una configuración estándar de Windows (en propiedades de pantalla) para ocultar normalmente esos aceleradores a menos que se mantenga presionada la tecla Alt. Eso explicaría por qué abrir el menú con Alt + F10 los muestra para usted. Tal vez esa es la causa?

[EDITAR]: No, no lo es. Lo intenté, y un TForm simple con un elemento de menú muestra el acelerador, pero tan pronto como agregue un TImageList y establezca el ImageIndex del elemento del menú individual, o simplemente configure OwnerDraw en verdadero, el subrayado del acelerador desaparece. Supongo que realmente es un error en el VCL.

Por cierto, esto es en Windows XP.

Solución:

Lo he depurado utilizando Delphi 2009 en Windows XP 64, y la causa raíz de los aceleradores faltantes parece ser que Windows envía mensajes WM_DRAWITEM con el indicador ODS_NOACCEL establecido, lo que no debería ODS_NOACCEL si el sistema está configurado para mostrar aceleradores en todo momento . Entonces, podría decirse que no es un error de VCL, sino un problema de Windows que el VCL no funciona.

Sin embargo, puede solucionarlo en su propio código, solo necesita restablecer el indicador antes de pasar el mensaje a la VCL. Anular el proceso de ventana

protected procedure WndProc(var Message: TMessage); override;

al igual que:

procedure TYourForm.WndProc(var Message: TMessage); const ODS_NOACCEL = $100; var pDIS: PDrawItemStruct; ShowAccel: BOOL; begin if (Message.Msg = WM_DRAWITEM) then begin pDIS := PDrawItemStruct(Message.LParam); if (pDIS^.CtlType = ODT_MENU) and SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @ShowAccel, 0) then begin if ShowAccel then pDIS^.itemState := pDIS^.itemState and not ODS_NOACCEL; end; end; inherited; end;

Esto es solo código de demostración, no debe llamar a SystemParametersInfo() cada vez que se recibe un mensaje WM_DRAWITEM , sino una vez al inicio del programa, y ​​luego cada vez que su programa recibe un mensaje WM_SETTINGCHANGE .