Pergunta

Eu estou usando Delpho 2006. O Cenário:

Sobre os dados do módulo I têm um ActionList. Uma das ações tem um atalho Ctrl + F4 e eu quero ter um atalho secundário Ctrl + W. Eu tentei todos os seguintes:

Adicionando Ctrl + W para listar as ações SecondaryShortcut no IDE.

Adicionando-lo no procedimento DataModuleCreate usando

ActFileCloseFile.SecondaryShortCuts.Add('Ctrl+W');

ou

ActFileCloseFile.SecondaryShortCuts.AddObject('Ctrl+W',
  TObject(Menus.ShortCut(87, [ssCtrl])));

Usando ambos os métodos no procedimento Criar ou FormShow do formulário onde ele será usado.

O atalho primário sempre funciona, mas não é o secundário.

Quando eu colocar o ActionList no formulário principal em vez do módulo de dados, ele funciona apenas adicionando Ctrl + W no IDE. O que eu fiz de errado?

Foi útil?

Solução

A solução mais elegante encontrado até agora é a seguinte:

No formulário você deseja manipular o SecondaryShortCut, adicione ao evento OnShortCut:

procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := dmDataModule.ActionList1.IsShortCut(Msg);
end;

Alternativa:

(Isto não é uma solução real, mas uma solução alternativa.)

Coloque uma lista de ações no formulário que tem uma acção idêntica à do módulo de dados. Na sua execução e eventos atualizá-lo apenas encaminha os eventos para a ação módulo de dados. Os menus no formulário usar a ação local.

Neste caso, basta adicionar Ctrl + W para a propriedade SecondaryShortCuts usando o IDE.

Obviamente, quando a ação sobre as mudanças do módulo de dados, eu tenho que mudar todas as ações locais também.

Outras dicas

Nem uma solução real, mas se você criar o datamodule de dentro do mainform funciona:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  FDataModule := TMyDataModule.Create(self);
  TMyButton.Action := FDataModule.TheAction;
end;


procedure TMyDataModule.DataModuleCreate(Sender: TObject);
begin
  TheAction.SecondaryShortCuts.Add('Ctrl+W');
end;

Eu acho que os atalhos são tratados pelo formulário que tem o foco atual. Então yo provavelmente terá os mesmos problemas se você estiver usando-los de outra forma.

resposta curta:. Ações atalhos não automaticamente o fogo em formulários e dados em módulos

Se você seguir as instruções na pergunta, você verá que nem mesmo os fogos de atalho primários. Isso ocorre porque uma etapa chave foi deixada de fora das instruções. Uma que vai servir para explicar porque OP experimentou o disparo de atalho primária e não o secundário.

Se você incluir os passos adicionais:

  • Adicionar um menu para o formulário.
  • E vincular um item de menu para a ação.

Então, o atalho principal será capaz de disparar a ação. Isso ocorre porque o componente de ação empurra suas configurações para o item de menu (incluindo a propriedade ShortCut). No entanto, TMenuItem não implementa o conceito de atalhos secundários. É por isso que um funciona e não o outro.


pausa para considerar uma aplicação com muitas formas e dados em módulos; ea implicação Se a ação atalhos poderia disparar em todos eles. Deve ser bastante óbvio que eles não devem ser capazes automaticamente fogo sem código explícito para permitir isso. Você não iria querer uma forma de fundo fazendo um monte de coisas, porque as suas teclas de atalho configuradas acontecer a ser pressionado no contexto de outros trabalhos independentes.

documentação fora o benefício de colocar listas de ação em dados -modules. Mas não parece oferecer qualquer explicação como usar ações com atalhos em um módulo de dados corretamente . Certamente nada é mencionado nos lugares esperados, a saber: ShortCut SecondaryShortcuts . (Eu ficaria desapontado, mas as minhas expectativas de documentação decente ter sido arrastado bastante baixa.)

Então ...

O deve ser feito para obter ações com atalhos que trabalham em formas e dados em módulos?

Eu fiz um pouco de investigação e descobriu algumas opções. Como sempre, avaliar o trade-off de em relação ao que você está tentando alcançar.

  • Quando você soltar uma lista de ações em um formulário (não-principal), todos os atalhos funcionam como esperado. Este é o cenário mais comum e se aplica quando as ações são específicas local e forma.

  • Quando você soltar uma lista de ações no formulário principal, todos aqueles atalhos será capaz de fogo de qualquer outra forma. Isto é excelente para a nível da aplicação de curto-cortes, tais como a abertura de outras formas.

NOTA: Há uma seqüência de prioridades quanto ao local onde um atalho é testado pela primeira vez. Então, se a forma activa tem um curto corte uma correspondência no formulário principal, o atalho será processado localmente. E a principal forma compreensivelmente não vai obtê-lo.

  • Quando um formulário é testado para ver se ele lida com um atalho, todas as componentes de propriedade também são verificados. (Isto é, de facto, porque os dois primeiros acima trabalho.) Isso significa que simplesmente definindo o Owner do seu módulo de dados de forma adequada permitirá que seus atalhos para aplicar a sua forma escolhida.

i. Em vez de:

Application.CreateForm(TDataModule1, DataModule1);

Você pode usar o seguinte:

DataModule1 := TDataModule1.Create(LocalForm);

No entanto, uma vez que cada instância de um módulo de dados pode ter apenas um proprietário: você teria que criar várias instâncias para permitir que múltiplas formas compartilhar os atalhos. Se esta é uma opção depende de suas circunstâncias. No entanto, você também pode fazer a principal forma o dono de seu módulo de dados que seria algo equivalente para a segunda opção acima.

  • A opção final que fornece o maior controle é a resposta própria do OP. Ou seja, Qualquer forma que as necessidades para apoiar "atalhos externos" pode manipular o evento OnShortCut com o exerdevido código:

Como pode ser visto no exemplo de código que você pode delegar a várias listas de ação em locais diferentes de acordo com a prioridade que você escolher.

procedure TMyForm.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
  Handled := DataModule1.ActionList3.IsShortCut(Msg);
  Handled := Handled or DataModule2.ActionList1.IsShortCut(Msg);
  Handled := Handled or DataModule1.ActionList1.IsShortCut(Msg);
end;

A ação está sendo engolido pela forma ... Se você quiser uma forma secundária / frame / datamodule para lidar com a ação ... Você tem que desativar a ActionList da primeira primária ...

Form1.ActionList1.State: = asSuspended;

DataModule1.ActionList1.State: = asNormal;

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