首页 > Windows开发 > 详细

把消息送到默认窗口函数里,并非一点用都没有,可能会产生新的消息(以WM_WINDOWPOSCHANGED为例)

时间:2015-08-30 06:31:18      阅读:152      评论:0      收藏:0      [点我收藏+]

我在追踪执行:

procedure TForm1.Button1Click(Sender: TObject);
begin
  panel1.Left:=panel1.Left-10;
end;

并且屏蔽TWinControl.WMWindowPosChanged里的UpdateBounds函数后

procedure TWinControl.WMWindowPosChanged(var Message: TWMWindowPosChanged);
var
  Framed, Moved, Sized: Boolean;
begin
  Framed := FCtl3D and (csFramed in ControlStyle) and (Parent <> nil) and (Message.WindowPos^.flags and SWP_NOREDRAW = 0);
  Moved := (Message.WindowPos^.flags and SWP_NOMOVE = 0) and IsWindowVisible(FHandle); // API
  Sized := (Message.WindowPos^.flags and SWP_NOSIZE = 0) and IsWindowVisible(FHandle);
  if Framed and (Moved or Sized) then InvalidateFrame;  
  // if not (csDestroyingHandle in ControlState) then UpdateBounds; // 屏蔽这句
  inherited; 

  if Framed and ((Moved or Sized) or (Message.WindowPos^.flags and (SWP_SHOWWINDOW or SWP_HIDEWINDOW) <> 0)) then
    InvalidateFrame; // 类函数,简单调用API
end;

继续追踪WM_WINDOWPOSCHANGED过程中,意外发现它一旦执行了:

procedure TWinControl.DefaultHandler(var Message);
begin
   Result := CallWindowProc(FDefWndProc, FHandle, Msg, WParam, LParam); 
end;

就会更改相应的panel1.left属性值。原因是,默认窗口函数会发送WM_SIZE和WM_MOVE消息,因此panel1.left的值仍得以改变。

具体参考MSDN: https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms632652(v=vs.85).aspx

把消息送到默认窗口函数里,并非一点用都没有,可能会产生新的消息(以WM_WINDOWPOSCHANGED为例)

原文:http://www.cnblogs.com/findumars/p/4770283.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!