前一篇文章讲到非队列消息会直接把消息Dispatch到窗口函数上,窗口函数长什么样?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//就是一个大case分支 //要想拦截消息,override窗口函数是一个办法! procedure TCustomForm.WndProc(var Message: TMessage); var FocusHandle: HWND; SaveIndex: Integer; MenuItem: TMenuItem; Canvas: TCanvas; DC: HDC; begin with Message do case Msg of WM_ACTIVATE, WM_SETFOCUS, WM_KILLFOCUS: begin end; CM_EXIT: if HostDockSite <> nil then DeActivate; end; end;
假如我们要用这种方法拦截Edit的Copy,Cut消息怎么办?
难道我们还要继承CustomEdit,再override窗口函数,生成新的MyEdit?有人想,直接用一个函数先把CustomEdit的WndProc替换掉不就行了,使用完毕后,再还原!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//替换窗口函数 TForm1 = class(TForm) edt1: TEdit; btn1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FOldWndProc: TWndMethod; { Private declarations } public { Public declarations } procedure NewWndProc(var Message: TMessage); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.NewWndProc(var Message: TMessage); begin if (Message.Msg <> WM_CUT) and (Message.Msg <> WM_COPY) and (Message.Msg <> WM_PASTE) then FOldWndProc(Message); end; procedure TForm1.FormCreate(Sender: TObject); begin FOldWndProc := edt1.WindowProc; edt1.WindowProc := NewWndProc; end; procedure TForm1.FormDestroy(Sender: TObject); begin edt1.WindowProc := FOldWndProc; end; end.