2008-11-11 13 views
7

J'ai fait de mon mieux et je n'arrive pas à comprendre ce qui s'est passé ici. Cela a fonctionné correctement dans Delphi 4. Après la mise à niveau vers Delphi 2009, je ne sais pas si c'est comme ça que ça fonctionne, ou si c'est un problème:Les touches de l'accélérateur de menu ne s'affichent pas (Delphi 2009)

Voici à quoi ressemble le menu de mon programme en mode Conception sous Delphi 2009:

alt text http://www.beholdgenealogy.com/img/menu1.gif

Notez que chaque mot dans le menu principal et le sous-menu fichier ont une lettre soulignée. C'est censé être comme ça. Cette lettre soulignée est appelée Accelerator Key et est standard dans les applications Windows, de sorte que vous pouvez utiliser la touche Alt et cette lettre pour sélectionner rapidement l'élément de menu, puis l'élément de sous-menu avec le clavier plutôt qu'avec votre souris.

Vous les obtenez ainsi en utilisant le « & » caractère dans le cadre de la légende de l'élément, par exemple: Enregistrer sous ... &

Quand je lance mon application, et utiliser la souris pour ouvrir dans le menu fichier, il ressemble à ceci:

alt text http://www.beholdgenealogy.com/img/menu2.gif

les caractères sont soulignés dans le menu principal, mais ne sont pas soulignées dans le menu fichier.

Si au contraire, j'utiliser la touche Alt-F pour ouvrir le sous-menu Fichier, il semble correct comme ceci:

alt text http://www.beholdgenealogy.com/img/menu3.gif

et toutes les lettres d'accélérateur clés sont bien soulignés. J'ai joué avec l'option AutoHotKeys mais ce n'est pas le problème.

Est-ce que quelqu'un a déjà rencontré ce problème? L'exemple de la 2ème image est-il un comportement correct que je ne connais pas? Ou y a-t-il une option ou une erreur de codage que j'ai peut-être manquée?


Nov 2009 (un an plus tard): mghie semble avoir trouvé la racine de tout cela et avoir compris le problème. Voir sa réponse acceptée ci-dessous.

Répondre

7

Il existe un paramètre Windows standard (sous les propriétés d'affichage) pour masquer normalement ces accélérateurs sauf si la touche Alt est maintenue enfoncée. Cela expliquerait pourquoi l'ouverture du menu avec Alt + F10 les montre pour vous. Peut-être que c'est la cause?

[EDIT]: Non, ce n'est pas le cas. J'ai juste essayé, et un TForm simple avec un élément de menu montre l'accélérateur, mais dès que j'ajoute un TImageList et place le ImageIndex de l'élément de menu simple, ou définit simplement OwnerDraw à vrai, alors le soulignement d'accélérateur disparaît. Je suppose que c'est vraiment un bug dans la VCL.

BTW, c'est sur Windows XP.

Solution:

Je déboguée cela en utilisant Delphi 2009 sur Windows XP 64, et la cause racine pour les accélérateurs manquants semble être que Windows envoie WM_DRAWITEM messages avec le drapeau ODS_NOACCEL, qu'il shouldn » t si le système est configuré pour afficher les accélérateurs à tout moment. Donc, vous pourriez dire que ce n'est pas un bug VCL, mais un problème Windows que la VCL ne fonctionne pas. Cependant, vous pouvez contourner ce problème avec votre propre code, il vous suffit de réinitialiser le drapeau avant de transmettre le message à la VCL. Remplacer la fenêtre proc

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

comme ceci:

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; 

C'est un code de démonstration seulement, vous ne devez pas appeler SystemParametersInfo() chaque fois qu'un message WM_DRAWITEM est reçu, mais une fois au début du programme, puis à chaque fois votre programme reçoit un message WM_SETTINGCHANGE.

+0

Je suis également sur Windows XP. Après ces réponses et ma réflexion sur ceci, et votre aide, je suis d'accord que ce peut être un bug dans la VCL. Je vais le signaler. – lkessler

+0

Rapporté comme un bug à Embarcadero: http://qc.codegear.com/wc/qcmain.aspx?d=68816 – lkessler

+0

BTW, je reçois le même comportement avec Delphi 2007. – mghie

1

Je ne pense pas que ce soit un bug généré par Delphi car vous avez le même comportement avec Notepad sur Vista. Aussi dans Delphi lui-même BTW ...
Je dois avouer que je n'ai pas fait attention avant votre question. Merci de l'avoir signalé.

+0

Non. Dans Delphi 2009 pour moi, tous les éléments de sous-menu montrent la touche d'accélération, même lorsque je sélectionne le menu avec la souris. C'est pourquoi je pensais que c'était un paramètre que j'avais, plutôt que Delphi ou le système d'exploitation. C'est vraiment un stramge, j'ai passé environ 4 heures à essayer de le réparer. – lkessler

6

Il est une "fonctionnalité" introduite avec Windows 2000:

The Old New Thing: Why does Windows hide keyboard accelerators and focus rectangles by default?

Il semblerait que Delphi 4 ne prend pas en charge cette fonctionnalité de Windows. Pour afficher les menus des 2000 et XP, cliquez avec le bouton droit de la souris sur un emplacement vide du bureau, choisissez Propriétés, cliquez sur l'onglet Apparence et sous Effets, décochez Masquer les lettres soulignées pour la navigation clavier jusqu'à ce que j'appuie sur la touche Alt.. Cliquez deux fois sur OK.

Je ne sais pas comment le faire dans Vista.

+0

Je pensais que vous aviez la réponse. Mais malheureusement, quand j'ai regardé cette option "Masquer les Lettres Soulignées" (je ne l'avais jamais su auparavant), j'ai trouvé que c'était décoché. – lkessler

+0

Quel système d'exploitation? Vos captures d'écran ressemblent à XP. Je l'ai juste essayé sur XP et cela fonctionne (décochez l'option et les soulignements de la touche d'accélération apparaissent.) Peut-être que vous avez besoin de redémarrer. –

0

Comme Jim McKeeth noté ci-dessus (correctement), il s'agit d'un comportement «par conception». Si les menus sont déclenchés par l'action du clavier, les accélérateurs doivent être affichés, mais s'ils sont déclenchés par la souris, les accélérateurs ne sont pas affichés intentionnellement. J'ai mon XP configuré pour montrer des accélérateurs à tout moment, mais un test rapide avec cette option changée confirme que les menus ne devraient pas montrer des soulignements non plus (Visual Studio a répondu comme je l'espérais, aucun soulignement en employant la souris). Toutefois, Microsoft Office ignore ce paramètre et affiche toujours les soulignements. Cela ressemble donc à un bug dans la façon dont les menus sont dessinés dans Delphi (je n'ai aucune expérience avec Delphi moi-même).

J'ai trouvé l'option pour Vista ainsi: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html

Vous pouvez activer ce dans la nouvelle Facilité d'accès Centre (allez contrôler Panel, cliquez sur Facilité d'accès, puis cliquez sur Facilité d'accès Centre). Dans la Facilité du Centre d'accès, cliquez sur Rendre le clavier plus facile à utiliser et tout en bas, sélectionnez les raccourcis clavier Souligné et activez la case à cocher .

Tout en faisant des recherches plus poussées, j'ai trouvé ce bug lié sur les forums Delphi: http://qc.codegear.com/wc/qcmain.aspx?d=37403

On dirait que dans votre cas, les fenêtres de l'enfant (les menus tirés) ne reçoivent pas la manipulation ou ne sont pas un message de WM_UIUPDATESTATE de leur fenêtre parent, qui est ce qui provoque le redraw avec les accélérateurs.

+0

"Il semble que dans votre cas, les fenêtres enfants (les menus dessinés) n'obtiennent pas ou ne manipulent pas le message WM_UIUPDATESTATE de leur fenêtre parente, ce qui provoque le redraw avec les accélérateurs" - Exactement! C'est le bogue! – lkessler