因为MoveWindow和SetWindowPos的移动窗口慢,我需要短时间内频繁地移动窗口时,就会出现移动慢的情况,请问还有没有更快的移动做法?

解决方案 »

  1.   

    不能画,我是在视频上面移动窗体平均20ms就移动一个逻辑单元.我知道BCB的框架里就实现了快速移动,但看它的源码有几行看不明白
      

  2.   


    BCB在框架里面移动也许就是先画结束了才真正移动呢
      

  3.   

    Move window to positoin 100 , 100 of its parent window .
    SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER)
      

  4.   

    xuzheng318(忧郁王子) : 谢谢你的参与,但你的答案并不符合题意
      

  5.   

    用非模态的对话框,先ShowWindow(SW_HIDE),再MoveWindow,再ShowWindow(SW_SHOW).我是这样想的没有试过,楼主可以试一下。
      

  6.   

    把BCB的源码,放出来看看它是怎么实现的,应该可以转到VC中。
      

  7.   

    luckyboy1979(一个人的孤单): 之前试过了,会闪的,而且慢的情况还是没有改善!!
      

  8.   

    我是看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;请大家分析一下吧,谢谢了
      

  9.   

    我感觉不是不快的问题而是你不停地动,导致看起来有影子效果实际上一次MoveWindow最多消耗几毫秒你可以试试每次移动后Sleep(20)这样效果可能会好些
      

  10.   

    下面的代码我试过了,没发现会闪
    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 );
    }
      

  11.   

    delphi那个是子窗口重绘背景窗口会快很多,所以没有出现你说的那种情况