Pergunta

Eu tentei o meu melhor e não consigo descobrir o que aconteceu aqui. Funcionou bem em Delphi 4. Depois de atualizar para Delphi 2009, não sei se é assim que deve funcionar, ou se é um problema:

É assim que o menu do meu programa se parece no modo de design em Delphi 2009:

enter image description here

Observe que cada palavra no menu principal e o submenu do arquivo têm uma carta sublinhada. É para ser assim. Esta letra sublinhada é chamada de chave do acelerador e é padrão nos aplicativos do Windows, para que você possa usar a tecla Alt e a letra para selecionar rapidamente o item de menu e, em seguida, submenu o item com o teclado e não com o mouse.

Você os obtém dessa maneira usando o personagem "&" como parte da legenda do item, por exemplo: salvar e como ...

Quando eu executo meu aplicativo e uso o mouse para abrir o menu de arquivos, parece o seguinte:

enter image description here

Os caracteres estão sublinhados no menu principal, mas não estão sublinhados no menu Arquivo.

Se, em vez disso, eu uso a tecla ALT-F para abrir o submenu do arquivo, então ela parece correta assim:

enter image description here

e todas as letras das chaves do acelerador estão devidamente sublinhadas.

Eu brinquei com a opção Autohotkeys, mas esse não é o problema.

Alguém já encontrou esse problema antes? O exemplo na segunda imagem é o comportamento correto que eu não conheço? Ou há alguma opção ou erro de codificação que eu poderia ter perdido?


Novembro de 2009 (um ano depois): Mghie parece ter chegado à raiz disso e descobriu o problema. Veja sua resposta aceita abaixo.

Foi útil?

Solução

Existe uma configuração padrão do Windows (em propriedades de exibição) para ocultar normalmente esses aceleradores, a menos que a tecla ALT seja retida. Isso explicaria por que abrir o menu com o Alt+F10 os mostra para você. Talvez essa seja a causa?

EDIT]: Não, não é. Acabei de tentar, e um tform simples com um item de menu mostra o acelerador, mas assim que adiciono um timagelista e defino o ImageIndex do item de menu único, ou simplesmente defina o proprietário como true, o sublinhado do acelerador desaparece. Eu acho que realmente é um bug no VCL.

BTW, isso está no Windows XP.

Gambiarra:

Eu depurei isso usando o Delphi 2009 no Windows XP 64, e a causa raiz dos aceleradores ausentes parece ser que o Windows envia WM_DRAWITEM mensagens com o ODS_NOACCEL Conjunto de sinalizadores, o que não deve se o sistema estiver definido para mostrar aceleradores o tempo todo. Então você poderia dizer que não é um bug VCL, mas um problema do Windows que o VCL não funciona.

No entanto, você pode contorná -lo em seu próprio código, basta redefinir o sinalizador antes de passar a mensagem para o VCL. Substituir a janela Proc

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

igual a:

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;

Este é apenas o código de demonstração, você não deve ligar SystemParametersInfo() toda vez que a WM_DRAWITEM a mensagem é recebida, mas uma vez no início do programa e, em seguida, toda vez que seu programa recebe um WM_SETTINGCHANGE mensagem.

Outras dicas

É um "recurso" introduzido com o Windows 2000:

A velha coisa nova: Por que o Windows oculta os aceleradores do teclado e concentra os retângulos por padrão?

Parece que o Delphi 4 não suportou esse recurso do Windows.

Para que os menus de 2000 e XP mostrem teclas de acelerador, clique com o botão direito do mouse em um local vazio na área de trabalho, escolha propriedades, clique na guia Aparência e sob efeitos, desmarcar Ocultar letras sublinhadas para navegação no teclado até que eu pressione a tecla Alt. Clique em OK duas vezes.

Não tenho certeza de como fazer isso no Vista.

Eu não acho que seja um bug gerado por Delphi, pois você tem o mesmo comportamento com o bloco de notas no Vista. Também em Delphi, btw ...
Devo confessar que não prestei atenção antes da sua pergunta. Obrigado por apontar isso.

Como Jim McKeeth observou acima (corretamente), esse é o comportamento "por design". Se os menus forem acionados através da ação do teclado, os aceleradores devem ser mostrados, mas se acionados pelo mouse, os aceleradores não serão intencionalmente mostrados.

Eu tenho meu XP configurado para mostrar aceleradores o tempo todo, mas um teste rápido com essa opção mudou confirma que os menus também não devem mostrar sublinhados (o Visual Studio respondeu como eu esperava, sem sublinhados ao usar o mouse). No entanto, o Microsoft Office ignora essa configuração e sempre mostra os sublinhados. Por isso, parece um bug na maneira como os menus são desenhados em Delphi (não tenho nenhuma experiência com Delphi).

Encontrei a opção para o Vista também: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html

Você pode ativar isso no novo Centro de Acesso (vá para o Painel de Controle, clique em Facilidade de Acesso e clique em Facilidade de Access Center). Na facilidade de acesso, clique em facilitar o teclado e, na parte inferior, selecione os atalhos do teclado sublinhado e a caixa de seleção Teclas de acesso.

Enquanto fazia mais pesquisas, encontrei este bug relacionado nos fóruns da Delphi: http://qc.codegear.com/wc/qcmain.aspx?d=37403

Parece que, no seu caso, as janelas da criança (os menus desenhados) não estão recebendo ou não estão lidando com a mensagem WM_UIUPDATESTATE da janela dos pais, que é o que causa o redesenho com os aceleradores.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top