2017-02-14 47 views
5

Używam aplikacji Delphi XE7 VCL na Windows 7.Dlaczego funkcja TEdit.OnChange jest uruchamiana po naciśnięciu klawisza Ctrl + A?

Zauważyłem, że zdarzenie TEdit.OnChange wyzwala gdy Ctrl + A (zaznacz wszystko) jest wciśnięty. Dlaczego?

Muszę niezawodnie wywołać zdarzenie OnChange tylko wtedy, gdy tekst w TEdit naprawdę się zmienia. Niestety nie jest dostępne zdarzenie OnBeforeChange, więc mogę porównać tekst przed zmianą i po niej.

Jak wdrożyć niezawodne wydarzenie OnChange dla TEdit?

+0

Czy to jest VCL czy FMX? –

+0

Dlaczego ma znaczenie, czy OnChange strzela? Być może istnieje bardziej eleganckie rozwiązanie? –

+0

@J ... - Być może, ale fakt, że OnChange uruchamia się, gdy nie ma faktycznej zmiany, jest wystarczająco interesujący :) Powód: W OnChange nawet tworzę i przypisuję unikalny identyfikator do pliku wprowadzonego przez użytkownika w polu edycji . Jeśli zdarzenie zostanie uruchomione więcej niż raz, generowany jest więcej niż jeden identyfikator i nie chcę tego. Ale jak powiedziałeś, mogę zmienić projekt, aby obejść ten brzydki OnChange. – Ampere

Odpowiedz

3

Tak, to nie jest złe wdrożenie podstawa:

procedure TCustomEdit.CNCommand(var Message: TWMCommand); 
begin 
    if (Message.NotifyCode = EN_CHANGE) and not FCreating then Change; 
end; 

Ta wiadomość pochodzi nie biorąc pod uwagę, że „A”, który znajduje się przycisk, który jest wypalanie EN_CHANGE, obecnie przybywa wraz ze stanem ctrl prasowany.

Co można zrobić, to sprawdzić, czy Ctrl jest wciśnięty czy nie:

procedure TForm44.edt1Change(Sender: TObject); 

    function IsCtrlPressed: Boolean; 
    var 
    State: TKeyboardState; 
    begin 
    GetKeyboardState(State); 
    Result := ((State[VK_CONTROL] and 128) <> 0); 
    end; 
begin 
    if IsCtrlPresed then 
    Exit; 

    Caption := 'Ctrl is not pressed'; 
end; 

Aby uniknąć czytania stan całej planszy klucza, można zrobić to, co zostało zasugerowane przez Davida Heffernan:

procedure TForm44.edt1Change(Sender: TObject); 

    function IsCtrlPresed: Boolean; 
    begin 
    Result := GetKeyState(VK_CONTROL) < 0; 
    end; 
begin 
    if IsCtrlPresed then 
    Exit; 

    Caption := 'Ctrl is not pressed'; 
end; 
+3

'GetKeyState (VK_CONTROL) <0' jest tutaj idiomem. Niezdolny do czytania całego stanu klawiatury. –

+0

nie jego sprawie, która wydajność będzie problemem, ale zgadzam się z Davidem –

+1

No, perf nie będzie problemem, ale może równie dobrze być skuteczne, kiedy to łatwo zrobić, a kod jest prostszy. –