我在表单上有一个TMemo
,我已经为它设置了一个OnChange
事件。我希望当用户在备忘录中按下Ctrl+X时不要触发OnChange
事件。但是Ctrl+X只是剪切文本选择,这肯定会触发OnChange
事件。我该如何防止这种情况发生?
我尝试在KeyUp
事件中检测Ctrl+X,如果用户按下Ctrl+X,我将解除备忘录的OnChange
事件的绑定,并以编程方式再次剪切文本。但这不起作用,我也不知道如何以编程方式发送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;
不要依赖键盘事件(例如,当您使用弹出菜单剪切内容时,它们不会被执行(,而是依赖窗口消息。
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;