我是看DELPHI的代码// 这是关键的 procedure TControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); begin if CheckNewSize(AWidth, AHeight) and ((ALeft <> FLeft) or (ATop <> FTop) or (AWidth <> FWidth) or (AHeight <> FHeight)) then begin InvalidateControl(Visible, False); FLeft := ALeft; FTop := ATop; FWidth := AWidth; FHeight := AHeight; UpdateAnchorRules; Invalidate; // 我使用了BUTTON控件,所以该控件重载了该方法 Perform(WM_WINDOWPOSCHANGED, 0, 0); RequestAlign; if not (csLoading in ComponentState) then Resize; end; end;procedure TControl.UpdateAnchorRules; var Anchors: TAnchors; begin if not FAnchorMove and not (csLoading in ComponentState) then begin Anchors := FAnchors; if Anchors = [akLeft, akTop] then begin FOriginalParentSize.X := 0; FOriginalParentSize.Y := 0; Exit; end; if akRight in Anchors then if akLeft in Anchors then FAnchorRules.X := Width else FAnchorRules.X := Left else FAnchorRules.X := Left + Width div 2; if akBottom in Anchors then if akTop in Anchors then FAnchorRules.Y := Height else FAnchorRules.Y := Top else FAnchorRules.Y := Top + Height div 2; if Parent <> nil then if csReading in Parent.ComponentState then begin if not (csDesigning in ComponentState) then FOriginalParentSize := Parent.FDesignSize end else if Parent.HandleAllocated then FOriginalParentSize := Parent.ClientRect.BottomRight else begin FOriginalParentSize.X := Parent.Width; FOriginalParentSize.Y := Parent.Height; end; end; end;procedure TControl.InvalidateControl(IsVisible, IsOpaque: Boolean); var Rect: TRect; function BackgroundClipped: Boolean; var R: TRect; List: TList; I: Integer; C: TControl; begin Result := True; List := FParent.FControls; I := List.IndexOf(Self); while I > 0 do begin Dec(I); C := List[I]; with C do if C.Visible and (csOpaque in ControlStyle) then begin IntersectRect(R, Rect, BoundsRect); if EqualRect(R, Rect) then Exit; end; end; Result := False; end;begin if (IsVisible or (csDesigning in ComponentState) and not (csNoDesignVisible in ControlStyle)) and (Parent <> nil) and Parent.HandleAllocated then begin Rect := BoundsRect; InvalidateRect(Parent.Handle, @Rect, not (IsOpaque or (csOpaque in Parent.ControlStyle) or BackgroundClipped)); end; end;// BUTTON使用了重载后的方法 procedure TWinControl.Invalidate; begin Perform(CM_INVALIDATE, 0, 0); end;function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint; var Message: TMessage; begin Message.Msg := Msg; Message.WParam := WParam; Message.LParam := LParam; Message.Result := 0; if Self <> nil then WindowProc(Message); Result := Message.Result; end;请大家分析一下吧,谢谢了
BCB在框架里面移动也许就是先画结束了才真正移动呢
SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER)
procedure TControl.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
if CheckNewSize(AWidth, AHeight) and
((ALeft <> FLeft) or (ATop <> FTop) or
(AWidth <> FWidth) or (AHeight <> FHeight)) then
begin
InvalidateControl(Visible, False);
FLeft := ALeft;
FTop := ATop;
FWidth := AWidth;
FHeight := AHeight;
UpdateAnchorRules;
Invalidate; // 我使用了BUTTON控件,所以该控件重载了该方法
Perform(WM_WINDOWPOSCHANGED, 0, 0);
RequestAlign;
if not (csLoading in ComponentState) then Resize;
end;
end;procedure TControl.UpdateAnchorRules;
var
Anchors: TAnchors;
begin
if not FAnchorMove and not (csLoading in ComponentState) then
begin
Anchors := FAnchors;
if Anchors = [akLeft, akTop] then
begin
FOriginalParentSize.X := 0;
FOriginalParentSize.Y := 0;
Exit;
end;
if akRight in Anchors then
if akLeft in Anchors then
FAnchorRules.X := Width else
FAnchorRules.X := Left
else
FAnchorRules.X := Left + Width div 2;
if akBottom in Anchors then
if akTop in Anchors then
FAnchorRules.Y := Height else
FAnchorRules.Y := Top
else
FAnchorRules.Y := Top + Height div 2;
if Parent <> nil then
if csReading in Parent.ComponentState then
begin
if not (csDesigning in ComponentState) then
FOriginalParentSize := Parent.FDesignSize
end
else if Parent.HandleAllocated then
FOriginalParentSize := Parent.ClientRect.BottomRight
else
begin
FOriginalParentSize.X := Parent.Width;
FOriginalParentSize.Y := Parent.Height;
end;
end;
end;procedure TControl.InvalidateControl(IsVisible, IsOpaque: Boolean);
var
Rect: TRect; function BackgroundClipped: Boolean;
var
R: TRect;
List: TList;
I: Integer;
C: TControl;
begin
Result := True;
List := FParent.FControls;
I := List.IndexOf(Self);
while I > 0 do
begin
Dec(I);
C := List[I];
with C do
if C.Visible and (csOpaque in ControlStyle) then
begin
IntersectRect(R, Rect, BoundsRect);
if EqualRect(R, Rect) then Exit;
end;
end;
Result := False;
end;begin
if (IsVisible or (csDesigning in ComponentState) and
not (csNoDesignVisible in ControlStyle)) and (Parent <> nil) and
Parent.HandleAllocated then
begin
Rect := BoundsRect;
InvalidateRect(Parent.Handle, @Rect, not (IsOpaque or
(csOpaque in Parent.ControlStyle) or BackgroundClipped));
end;
end;// BUTTON使用了重载后的方法
procedure TWinControl.Invalidate;
begin
Perform(CM_INVALIDATE, 0, 0);
end;function TControl.Perform(Msg: Cardinal; WParam, LParam: Longint): Longint;
var
Message: TMessage;
begin
Message.Msg := Msg;
Message.WParam := WParam;
Message.LParam := LParam;
Message.Result := 0;
if Self <> nil then WindowProc(Message);
Result := Message.Result;
end;请大家分析一下吧,谢谢了
CRect rc;
GetWindowRect( &rc );
for ( int i = 0; i < 100; i++ )
{
SetWindowPos( NULL, rc.left + i, rc.top + i, 0, 0, SWP_NOSIZE );
Sleep( 10 );
}