2010-03-09 5 views
0

Parfois, une frappe sur un formulaire peut avoir différents destinataires, en fonction de l'état de l'application. Voir l'exemple suivant:Répartir les touches entre le parent et le contrôle enfant

unit Unit1; 

interface 

uses 
    Windows, 
    Messages, 
    SysUtils, 
    Variants, 
    Classes, 
    Graphics, 
    Controls, 
    Forms, 
    Dialogs, 
    ComCtrls, 
    Buttons; 

type 
    TForm1 = class(TForm) 
    private 
    ListView1: TListView; 
    ButtonOK: TBitBtn; 
    ButtonCancel: TBitBtn; 
    procedure ButtonClick(Sender: TObject); 
    public 
    constructor Create(AOwner: TComponent); override; 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

constructor TForm1.Create(AOwner: TComponent); 
begin 
    inherited CreateNew(AOwner); 
    ClientWidth := 300; 
    ClientHeight := 240; 

    ListView1 := TListView.Create(Self); 
    ListView1.Name := 'ListView1'; 
    ListView1.Parent := Self; 
    ListView1.Height := 200; 
    ListView1.Align := alTop; 
    ListView1.AddItem('aaaaa', nil); 
    ListView1.AddItem('bbbbb', nil); 
    ListView1.AddItem('ccccc', nil); 

    ButtonOK := TBitBtn.Create(Self); 
    ButtonOK.Parent := Self; 
    ButtonOK.Left := 8; 
    ButtonOK.Top := 208; 
    ButtonOK.Kind := bkOK; 
    ButtonOK.OnClick := ButtonClick; 

    ButtonCancel := TBitBtn.Create(Self); 
    ButtonCancel.Parent := Self; 
    ButtonCancel.Left := 90; 
    ButtonCancel.Top := 208; 
    ButtonCancel.Kind := bkCancel; 
    ButtonCancel.OnClick := ButtonClick; 
end; 

procedure TForm1.ButtonClick(Sender: TObject); 
begin 
    ShowMessage((Sender as TBitBtn).Caption); 
    Application.Terminate; 
end; 

end. 

(. Pour exécuter, créez une application VCL standard et remplacer le contenu de Unit1.pas au-dessus)

Si on commence l'application et presses Entrez ou Esc, le bouton approprié est "cliqué". Cependant, quand on commence à éditer la liste (en cliquant une fois et demie sur un article) Entrez et Esc devrait accepter ou annuler l'édition qu'ils n'ont pas - ils "cliquent" toujours sur les boutons.

scénarios similaires existent si l'on a des actions avec des raccourcis F2 ou F4 sur un formulaire contenant un cxGrid, qui utilise par défaut ces raccourcis pour lancer le mode d'édition ou déroulant éditeurs de combobox. Avez-vous une idée de la façon dont je peux continuer à utiliser le confort de TButton.Default/Cancel et actions, alors que pas devoir réimplémenter la manipulation des touches de tous les composants que j'utilise?

Répondre

2

Je suppose que vous avez de la malchance avec les contrôles que vous utilisez. TMemo le gère correctement, mais en fait, TListView éditable ne le fait pas. Le problem seems to originate from win32 plutôt que l'encapsuleur VCL qui l'entoure. Il semble donc que vous devez réimplémenter la gestion des clés sur TListView si vous n'aimez pas son comportement actuel.

procedure WMGetDlgCode(var Message: TMessage); message WM_GETDLGCODE; 

procedure TMyListView.WMGetDlgCode(var Message: TMessage); 
begin 
    inherited; 

    if IsEditing then 
    Message.Result := Message.Result or DLGC_WANTALLKEYS; 
end; 

Comme tous les contrôles se comportent différent et ce sont les contrôles eux-mêmes qui décident quelles clés qui les intéressent, je ne vois pas comment vous pouvez le fixer sans avoir à changer les comportements indésirables.

+1

Il devrait également être possible de faire la même chose sans créer de classe descendante, comme ici: http://stackoverflow.com/questions/2363456/how-do-i-catch-a-vk-tab-key-in -my-tedit-control-et-not-let-it-lose-the-focus – kludg

+0

Au lieu de créer votre propre TmyEdit ou similaire, utilisez simplement une ligne comme 'type TEdit = class (StdCtrls.TEdit) {... } end; 'pour ajouter ce que vous voulez à TEdit, y compris la gestion des nouveaux messages pour les touches. Partout sur votre formulaire que vous avez un standard TEdit utilisera maintenant votre nouvelle version étendue. Alternativement, ajoutez votre nouvelle déclaration de type à une unité pour l'utiliser à partir de plusieurs formulaires. Vous devrez vous assurer que votre unité est ajoutée à la clause uses APRES toutes les unités qui contiennent les contrôles d'origine (l'ajouter à la fin est la solution la plus simple). –

Questions connexes