2

I have a TMemo on the form and I've set an OnChange event for it. I hope the OnChange event not to be triggered when the user presses Ctrl+X in the memo. But Ctrl+X just cuts the text selection, which will for sure trigger the OnChange event. How can I prevent that?

I've tried to detect Ctrl+X in the KeyUp event, and if the user pressed Ctrl+X I unbind the memo's OnChange event and programmatically cut the text again. But this doesn't work, and I don't how to programmatically send Ctrl+X.

procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Key = Ord('X')) and (Shift = [ssCtrl]) then
  begin
    Memo1.OnChange := nil;
    // programmatically cut the text here, which I don't know how to do
    Memo1.OnChange := Memo1Change;
  end;
end;
4

1 回答 1

4

Don't rely on keyboard events (They are not executed for example when you cut something by using the popupmenu), rely on windows messages instead.

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure Memo1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FPrevMemoWindowProc : TWndMethod;
    procedure MemoWindowProc(var AMessage: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  Clipbrd;

procedure TForm1.MemoWindowProc(var AMessage: TMessage);
begin
  if(AMessage.Msg = WM_CUT) then
  begin
    if(Memo1.SelLength > 0) then
    begin
      Memo1.OnChange := nil;
      try
        Clipboard.AsText := Memo1.SelText;
        Memo1.ClearSelection();
        Exit;
      finally
        Memo1.OnChange := Memo1Change;
      end;
    end;
  end;

  FPrevMemoWindowProc(AMessage);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FPrevMemoWindowProc := Memo1.WindowProc;
  Memo1.WindowProc := MemoWindowProc;
end;

procedure TForm1.Memo1Change(Sender: TObject);
begin
  ShowMessage('Change');
end;
于 2022-01-19T09:16:53.300 回答