为何EN_PROTECTED通知消息未发送至TRichEdit派生控件?
解决TRichEdit派生类收不到EN_PROTECTED通知的问题
问题根源分析
你的代码存在两个关键问题:
- 未给RichEdit控件启用ENM_PROTECTED通知掩码,系统不会主动发送该类型通知。
- 仅设置
DefAttributes.Protected只能让新输入文本默认带保护属性,但空控件下的粘贴操作不会触发保护检查;同时缺少启用控件保护通知的核心设置。
修正后的代码示例
unit Unit1; interface uses Vcl.ComCtrls, Winapi.RichEdit, System.UITypes, Vcl.StdCtrls, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs; type TMyRichEdit = class(Vcl.ComCtrls.TRichEdit) private procedure CNNotify(var AMessage: TWMNotifyRE); message CN_NOTIFY; procedure CreateWnd; override; end; TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TMyRichEdit.CreateWnd; begin inherited; // 启用EN_PROTECTED通知掩码 SendMessage(Handle, EM_SETEVENTMASK, 0, ENM_PROTECTED or GetEventMask); // 设置控件为全局保护模式,任何编辑操作都会触发EN_PROTECTED SendMessage(Handle, EM_SETPROTECTED, WPARAM(True), 0); end; procedure TMyRichEdit.CNNotify(var AMessage: TWMNotifyRE); begin inherited; // 必须先调用inherited,保证系统正常处理其他通知 if (AMessage.NMHdr.code = EN_PROTECTED) then begin // 根据原始消息类型判断操作 case AMessage.ENProtected.msg of WM_PASTE: ShowMessage('尝试粘贴到受保护区域'); WM_CUT: ShowMessage('尝试剪切受保护内容'); WM_DELETE: ShowMessage('尝试删除受保护内容'); end; // 若要阻止编辑操作,设置AMessage.Result := 1; // AMessage.Result := 1; end; end; procedure TForm1.FormCreate(Sender: TObject); var RichEdit : TMyRichEdit; begin RichEdit := TMyRichEdit.Create(Self); RichEdit.Align := alClient; RichEdit.Parent := Self; RichEdit.ScrollBars := ssVertical; // 可选:让新输入的文本默认带保护属性 RichEdit.DefAttributes.Protected := True; // 添加测试用的受保护文本,方便快速验证效果 RichEdit.Text := '这是受保护的文本'; end; end.
关键修正点说明
- 启用通知掩码:在
CreateWnd中通过EM_SETEVENTMASK消息添加ENM_PROTECTED标志,告知系统需要发送该类型通知。 - 全局保护模式:通过
EM_SETPROTECTED消息设置控件为全局保护状态,此时任何编辑操作都会触发EN_PROTECTED;如果只想保护特定文本段,可去掉这条消息,转而给指定文本范围单独设置PROTECTED属性。 - 正确调用inherited:在
CNNotify中先执行inherited,确保系统正常处理其他通知逻辑,避免破坏控件原有功能。 - 添加测试文本:空控件下的粘贴操作可能不会触发保护检查,提前添加受保护文本可快速验证通知是否生效。
内容的提问来源于stack exchange,提问作者Fabrizio
相关产品推荐
相关产品推荐

