delphi – TEdit和WM_PAINT消息处理程序的奇怪行为
我正在尝试在没有焦点的情况下在TEdit控件上实现我自己的绘图(当编辑器没有完全显示其文本时在TEdit中显示省略号).所以我用这段代码明星?ed:
type TEdit = class(StdCtrls.TEdit) private FEllipsis: Boolean; FCanvas: TCanvas; procedure WMPaint(var Message: TWMPaint); message WM_PAINT; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; constructor TEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); FEllipsis := False; FCanvas := TControlCanvas.Create; TControlCanvas(FCanvas).Control := Self; end; destructor TEdit.Destroy; begin FCanvas.Free; inherited; end; procedure TEdit.WMPaint(var Message: TWMPaint); begin if FEllipsis and (not Focused) then begin // Message.Result := 0; // TODO... end else inherited; end; 请注意,当FEllipsis和(未聚焦)消息处理程序不执行任何操作时. 现在我在表单上删除了TButton和2个TEdit控件,并添加了OnCreate形式: procedure TForm1.FormCreate(Sender: TObject); begin Edit2.FEllipsis := True; end; 我希望Edit1正常绘制,Edit2不要在编辑控件中绘制任何内容. 相反,消息处理程序被无休止地处理,Edit1也没有被绘制,整个应用程序都在窒息(占用率为25%!).我也尝试过返回Message.Result:= 0 – 效果相同. 现在,对于“奇怪”部分:当我使用BeginPaint获取画布句柄时,一切都按预期工作. procedure TEdit.WMPaint(var Message: TWMPaint); var PS: TPaintStruct; begin if FEllipsis and (not Focused) then begin if Message.DC = 0 then FCanvas.Handle := BeginPaint(Handle,PS) else FCanvas.Handle := Message.DC; try // paint on FCanvas... finally FCanvas.Handle := 0; if Message.DC = 0 then EndPaint(Handle,PS); end; end else inherited; end; 注意我也没有调用继承. 如何解释这种行为?谢谢. 解决方法
当窗口无效时,要求它在下一个绘制周期中使其自身有效.通常,当GetMessage发现队列为空时,会在主线程消息循环中发生.此时,WM_PAINT消息被合成并分派到窗口.
当窗口收到这些消息时,它的任务是绘制自己.这通常是通过调用BeginPaint然后调用EndPaint来完成的.对BeginPaint的调用验证窗口的客户端rect.这是您缺乏的重要信息. 现在,在你的代码中,你没有调用inherited,所以没有绘制任何东西,也没有调用BeginPaint / EndPaint.因为您没有调用BeginPaint,所以窗口仍然无效.因此,生成了源源不断的WM_PAINT消息. 相关文档可以在here找到:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |