我想做这个功能,就是界面上有一些矢量图形,用户用鼠标在图形上拖出一个矩形,我就放大矩形选中的图形到整个界面的大小,不知道说明白了没有。
现在后面的数据和算法都已经写好,就是界面上的效果做不出来。
请有做过的给些想法或代码。

解决方案 »

  1.   

    这个效果我尝试用delphi实现过:在image下面放一个paintBox,image上画图形,在image的mousuDown和mouseUp里面标注信号量,在image的mouseMove里面调用paintBox的mouseMove,paintBox就是用来画选择框的
      

  2.   

    呵呵,就是在LButtonUp()里面计算你拉出来的矩形的坐标,然后根据此坐标重新绘制就行了
      

  3.   

    //框选放大
        if(m_bStartBoxSelect)
        {
            //橡皮矩形类
            m_cTrack.TrackRubberBand(this,pt,true);
            m_cTrack.m_rect.NormalizeRect();//正规化        //得到矩形的中点
            CPoint RectCenter = m_cTrack.m_rect.CenterPoint();
            ClientToLogical(RectCenter); //得逻辑坐标
            double xCenter,yCenter;
            LogicalToWorld(RectCenter,xCenter,yCenter); //得世界坐标        //将框选矩形转化为逻辑矩形
            CRect rect;
            rect = m_cTrack.m_rect;
            ClientToLogical(rect);        //得到客户区矩形
            CRect clientRect;
            GetClientRect(&clientRect);        //得到矩形的世界范围
            double x1,y1,x2,y2;
            LogicalToWorld(rect.BottomRight(),x1,y1);
            LogicalToWorld(rect.TopLeft(),x2,y2);        //得到缩放比例
            double xScale = fabs(x1 - x2) / clientRect.Width();
            double yScale = fabs(y1 - y2) / clientRect.Height();        (yScale > xScale) ? m_dScale = yScale : m_dScale = xScale;        //得到客户区中心
            CPoint clientCenter = clientRect.CenterPoint();
            ClientToLogical(clientCenter);
            double xClientCenter,yClientCenter;
            LogicalToWorld(clientCenter,xClientCenter,yClientCenter); //转成世界坐标        //得到世界坐标差
            double xOffset = -(xClientCenter - xCenter);
            double yOffset =  (yClientCenter - yCenter);        //得到逻辑差
            LONG   xLog    = WorldToLogical(xOffset);
            LONG   yLog    = WorldToLogical(yOffset);        CPoint PosPt   = GetScrollPosition();    //得到原来的滚动条位置        PosPt.Offset(xLog,yLog);        int lpMinPos,lpMaxPos;
            GetScrollRange(SB_HORZ,&lpMinPos,&lpMaxPos);
            int lpMin,lpMax;
            GetScrollRange(SB_VERT,&lpMin,&lpMax);        if(PosPt.x > lpMaxPos)
            {
                SetScrollRange(SB_HORZ,lpMinPos,PosPt.x);
            }        if(PosPt.y > lpMax)
            {
                SetScrollRange(SB_VERT,lpMin,PosPt.y);
            }        SetScrollPos(SB_HORZ,PosPt.x);
            SetScrollPos(SB_VERT,PosPt.y);        m_bStartBoxSelect = false;        Invalidate(TRUE);
        }
      

  4.   

    这个代码放在OnLButtonDown事件中这个代码可能与你的不是很适合,但是思路应该是一样的
      

  5.   

    //橡皮矩形类
            m_cTrack.TrackRubberBand(this,pt,true);
            m_cTrack.m_rect.NormalizeRect();//正规化这个就是框选的代码啊!!矩形框是透明的啊!
      

  6.   

    用CRectTracker么,delphi里面没有这个类。我已经在看msdn里的demo了,希望能找到解决方法
      

  7.   

    哈哈,搞定。首先介绍一个API:DrawFocusRect(handle,rect),调用一次是画选择框,再调用一次就是删除,具体可以去查msdn。
    这样就好办了,image上画图形,paintbox上画选择框,画的时候把前一次的删除,具体代码如下:
    procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      i:Integer;
    begin
      beginX:=X;  beginY:=Y;  lastX:=X;  lastY:=Y;
      moving:=True;
    end;procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if moving then begin
        rct.Left:=beginX;
        rct.Top:=beginY;
        rct.Right:=lastX;
        rct.Bottom:=lastY;
        DrawFocusRect(PaintBox2.Canvas.Handle,rct);
        rct.Right:=X;
        rct.Bottom:=Y;
        DrawFocusRect(PaintBox2.Canvas.Handle,rct);
        lastX:=X;  lastY:=Y;
      end;
    end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      i:Integer;
      zoom:Double;
    begin
      moving:=False;
      endX:=X;  endY:=Y;
      if (endX=beginX) or (endY=beginY) or (endX<beginX) or (endY<beginY) then Exit;
      if (endX-beginX)>(endY-beginY) then zoom:=Image1.Width/(endX-beginX)
      else zoom:=Image1.Height/(endY-beginY);
      ClearImg;
      Image1.Canvas.MoveTo(0-round(beginX*zoom),0-round(beginY*zoom));
      for i:=0 to dataLen-1 do begin
        dataTmp[i,0]:=Round((dataTmp[i,0]-beginX)*zoom);
        dataTmp[i,1]:=Round((dataTmp[i,1]-beginY)*zoom);
        Image1.Canvas.LineTo(dataTmp[i,0],dataTmp[i,1]);
      end;
    end;