说明:是擦除波形上的一部分,而不是全部!

解决方案 »

  1.   


    procedure TForm1.Button2Click(Sender: TObject);
    begin
      Windows.SetRop2(Canvas.Handle, R2_NOT);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(100, 100);
    end;// 擦除
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Windows.SetRop2(Canvas.Handle, R2_NOT);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(50, 50);
    end;
      

  2.   

    to sanguomi:
    如果我的波形是正弦波,你怎样删除波形上的某一段呢?
      

  3.   

    to sailxia:
    如果我只更新一部分波形,也就是重新画了波形上去,那原来X轴上波形怎么去掉?
      

  4.   


    哎,怎么又安静下来了?怎么连CSDN论坛也这样
      

  5.   

    用异或,原来怎么画的,在画一遍就擦掉了
    type 
     TPoints = class 
     private 
       FCount        : SmallInt; 
       FPoints       : array of TPoint;    function GetCount              :SmallInt; 
       function Getpt(Index: Integer) :TPoint; 
     public 
       constructor Create; 
       destructor Destroy; override;    function Add(pt: TPoint): SmallInt; 
       procedure Remove(Index: Integer); 
       procedure RemoveAll; 
       property Items[Index: Integer]: TPoint read Getpt; 
     published 
       property Count  :SmallInt    read GetCount; 
     end; 
    constructor TPoints.Create; 
    begin 
     inherited Create; 
     FCount := 0; 
     SetLength(FPoints, 0); 
    end; destructor TPoints.Destroy; 
    begin 
     FCount := 0; 
     SetLength(FPoints, 0); 
     inherited; 
    end; function TPoints.Add(pt: TPoint): SmallInt; 
    begin 
     FCount := Length(FPoints) + 1; 
     SetLength(FPoints, FCount); 
     FPoints[FCount - 1] := pt; 
     Result := FCount - 1; 
    end; procedure TPoints.Remove(Index: Integer); 
    var i: integer; 
    begin 
     if Index <= FCount - 1 then 
     begin 
       for i := Index to FCount - 2 do 
       begin 
         FPoints[i] := FPoints[i + 1]; 
       end; 
       FCount := FCount - 1; 
       SetLength(FPoints, FCount); 
     end; 
    end; procedure TPoints.RemoveAll; 
    begin 
     FCount := 0; 
     SetLength(FPoints, 0); 
    end; function TPoints.Getpt(Index: Integer) :TPoint; 
    begin 
     if Index <= FCount - 1 then 
     begin 
       Result := FPoints[Index]; 
     end; 
    end; function TPoints.GetCount: SmallInt; 
    begin 
     FCount := Length(FPoints); 
     Result := FCount; 
    end; var //变量 
       isDraw :Boolean; 
       pts: TPoints; //全部代码 
    procedure TForm1.FormCreate(Sender: TObject); 
    begin 
     pts := TPoints.Create; 
    end; procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; 
     Shift: TShiftState; X, Y: Integer); 
    begin 
     isDraw := True; 
     pts.RemoveAll;  //清除上次画图数据  pts.Add(Point(X, Y)); 
     image1.Canvas.Pen.Mode := pmCopy; 
     image1.Canvas.MoveTo(X, Y); 
    end; procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, 
     Y: Integer); 
    begin 
     if isDraw then 
     begin 
       pts.Add(Point(X, Y)); 
       with image1.Canvas do 
       begin 
         LineTo(X, Y); 
       end; 
     end; 
    end; procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; 
     Shift: TShiftState; X, Y: Integer); 
    begin 
     isDraw := False; 
    end; //清除 
    procedure TForm1.Button1Click(Sender: TObject); 
    var 
     i: integer; 
    begin 
     if pts.Count > 0 then 
     begin 
       with image1.Canvas do 
       begin 
         Pen.Mode := pmNotXor; 
         MoveTo(pts.Items[0].X, pts.Items[0].Y); 
         for i := 1 to pts.Count - 1 do 
         begin 
           LineTo(pts.Items[i].X, pts.Items[i].Y); 
         end; 
         Pen.Mode := pmCopy; 
       end; 
     end; 
     pts.RemoveAll; 
    end; 
      

  6.   

    你是想动态更新波形,但是不想每次全部重绘?
    用ScrollDC就可以了。
      

  7.   

    不知道具体场景,楼主可以尝试记录鼠标位置,或者在MouseMove事件中处理,
    只是给出意见哦,楼主继续努力
      

  8.   

    to DelphiGuy:
    我就是要实现这个功能,你给的ScrollDC函数是做什么的?网上的资料怎么这么少,怎么用,能不能说下?
      

  9.   

    都以xor的方式画点,再画一遍,就是恢复背景了
      

  10.   

       不知道是不是我的表述不够准确!是这样的,我把实现的例子说一下:
        在PaintBox1上已经画好一个正弦波形,X轴0-511,Y轴0-355。
        现在,我想重绘波形,比如,当鼠标按下(PaintBox1MouseDown)并移动(PaintBox1MouseMove)时,在X轴第100-200位置画了一个三角波波形覆盖原来的正弦波形,当鼠标松开,波形画完。
        我实现的方法:先清除X轴第100-200位置原来的正弦波,然后画上三角波形。(这个方法是否可实现)
        现在遇到的问题:不知道如何清除X轴第100-200位置原来的正弦波!    高手们请看看,解决问题了马上给分,如果分还不够,跟我说,我以后凑够了给分,说到做到!
      

  11.   

    你是要后画的覆盖先画的一部分?
    那用ScrollDC(这是一个Windows API)不行,ScrollDC是卷动DC的一部分,比如波形是从左向右出来,每次可以把显示窗口(比如用Image或者PaintBox)的DC向右卷动100像素,在0~99的位置画上新波形,重复执行的效果就是动态波形从左向右滚动。按照你的要求,最简单的方法是把重绘的部分用背景色擦除。
      

  12.   

    to DelphiGuy兄:
    现在有一个问题:
        当鼠标按下并移动时,怎样在擦除原来波形的同时,画上波形呢?也就是一步完成擦除并画波形。。
      

  13.   

        不知道是不是我的表述不够准确!是这样的,我把实现的例子说一下:
        在PaintBox1上已经画好一个正弦波形,X轴0-511,Y轴0-355。
        现在,我想重绘波形,比如,当鼠标按下(PaintBox1MouseDown)并移动(PaintBox1MouseMove)时,在X轴第100-200位置画了一个三角波波形覆盖原来的正弦波形,当鼠标松开,波形画完。
        我实现的方法:先清除X轴第100-200位置原来的正弦波,然后画上三角波形。(这个方法是否可实现)
        现在遇到的问题:不知道如何清除X轴第100-200位置原来的正弦波,并画上三角波!而且这个过程是在鼠标按下并移动时一步完成清除及画波形;
        高手们请看看,解决问题了马上给分,如果分还不够,跟我说,我以后凑够了给分,说到做到!
      

  14.   

    一步完成擦除并画波形应该不行。
    你要想获得鼠标移到哪画到哪的效果(我猜测的),那需要在当鼠标按下时设置一个起始位置(比如x坐标),每次PaintBox1MouseMove时,如果鼠标保持按下的状态,从起始位置擦除到当前位置,再画上新波形,再把起始位置更新为当前位置。
      

  15.   

    to DelphiGuy兄:
       一步完成擦除并画波形的目的就是:在画布上保持有连惯的波形,而且一个X坐标对应一个Y值。我也是看到一个软件是这样实现的
      

  16.   

    MouseDown以后MouseUp以前OnMouseMove返回的所有点都记录下来,LineTo起来就可以画波形。
    修改也是MouseDown以后MouseUp以前OnMouseMove返回的所有点,把MouseDownX和MouseUpX之间的以前点删除。
    把所有点按X排序,LineTo画波形。
      

  17.   

    to lhylhy:
       "MouseDown以后MouseUp以前OnMouseMove返回的所有点都记录下来",但当你鼠标移动快了的话,捕捉到的点是有限的!我试过了
      

  18.   

    你是LineTo连起来的,所以用户看不出来。
      

  19.   

    画图是不需要清除的,只需要不断的重绘。
    楼主可考虑使用矢量图形或位图(有规律的建议用矢量图形)。
    窗体上的图形只要重绘时没画任何东西变什么都没了。
    楼主应该用个容器(数组或链表什么的)保存波形的相关属性(如坐标方程),然后在Paint方法中按保存的波形属性进行绘图(必要时采用双缓冲)。而鼠标移动式就修改容器中保存的波形数据,然后设置无效区域让窗体刷新即可。至于擦除一部分如何实现,你应该想如何保存该信息以方便在重绘时不再绘制该部分的线条,实现的方式很多,这就要看你的波形是如何绘制出来的了。
      

  20.   

    鼠标移动快的话,在mouseMove事件中也不能处理,这时记录的鼠标轨迹也不是连续的。
      

  21.   

    不连续没关系,只要绘制从上次mousemove发生以来的区间就可以了。
      

  22.   

    to 大家:
       我要实现的例子如下:
      在PaintBox1上已经画好一个正弦波形,X轴0-511,Y轴0-355。 
        现在,我想重绘波形,比如,当鼠标按下(PaintBox1MouseDown)并移动(PaintBox1MouseMove)时,在X轴第100-200位置画了一个三角波波形覆盖原来的正弦波形,当鼠标松开,波形画完。 
        我实现的方法:先清除X轴第100-200位置原来的正弦波,然后画上三角波形。(这个方法是否可实现) 
        现在遇到的问题:不知道如何清除X轴第100-200位置原来的正弦波,并画上三角波!而且这个过程是在鼠标按下并移动时一步完成清除及画波形;  其实,这个例子实现的最大难点就是:一步完成擦除并画波形;我看过实现这个画图的软件,优点就是每次不管按下鼠标后怎么画图,X轴都只对应一个Y值
      

  23.   

    擦除用PaintBox.Casnvas.FillRect就可以了。
    不知道你说的“优点就是每次不管按下鼠标后怎么画图,X轴都只对应一个Y值”是什么意思。
      

  24.   

    to DelphiGuy:
       我在56视频网上传了一个视频,演示画图过程,看一下应该就知道了。 
       http://www.56.com/u65/v_NDUyNjk4OTQ.html
      

  25.   


    to 大家:
        我要实现的例子如下:
      在PaintBox1上已经画好一个正弦波形,X轴0-511,Y轴0-355。
        现在,我想重绘波形,比如,当鼠标按下(PaintBox1MouseDown)并移动(PaintBox1MouseMove)时,在X轴第100-200位置画了一个三角波波形覆盖原来的正弦波形,当鼠标松开,波形画完。
        我实现的方法:先清除X轴第100-200位置原来的正弦波,然后画上三角波形。(这个方法是否可实现)
        现在遇到的问题:不知道如何清除X轴第100-200位置原来的正弦波,并画上三角波!而且这个过程是在鼠标按下并移动时一步完成清除及画波形;  其实,这个例子实现的最大难点就是:一步完成擦除并画波形;
        我在56网上传了画图软件的视频,大家看一下应该就清楚了
        http://www.56.com/u65/v_NDUyNjk4OTQ.html
      

  26.   

    看了视频,如果只是波形的话,其实只要保存一个缓冲表,也可以是两个,仿照显卡的双缓冲方式。
    TBitRcd= record
      X,           //X轴位置,
      Y:integer;   //Y轴位置,波形的变换过程中,画点其实只改变这个值
    end;
    TPaintCache= Array[0..Max_Len-1]of TBitRcd;//Max_Len为画图区最大像素长度在MouseMove中捕捉X,Y,根据X值查询TPaintCache缓冲表中对应的TBitRcd记录更新Y;接着可以用一个时钟,比如每50毫秒重画一次,根据人眼每秒24张图的效果,50毫秒应该差不多吧。先擦除原来图案,再复制缓冲表数据画图。
      

  27.   

    用缓冲表主要是避免画图过程耗时太长而错过鼠标捕捉动作。。在MouseMove中只更新Y的值应该是很快的。可以试试具体行不行。。
      

  28.   

    我的代码:
    procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      drawing:=true;
      if(drawing)then
        begin
          paintbox1.Canvas.Pen.Color:=clyellow;
          if(x>=length(Y_Values))then
            begin
              paintbox1.Canvas.MoveTo(Max_Y_Values.x ,Max_Y_Values.y );
              paintbox1.Canvas.LineTo(x,y);
              setlength(Y_Values,x);
              Max_Y_Values.x:=x;
              Max_Y_Values.y:=y;
            end
            else
              begin
              paintbox1.Canvas .moveto(x,Y_Values[x]);
              paintbox1.Canvas .lineto(x,y);    end;
    end;
    procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
       if ((X>=0) and (X<=512)) and ((Y>=0) and (Y<=350)) then
         begin
            label1.Caption :='X:'+inttostr(x)+'  Y:'+inttostr(y);
          if drawing then
            begin
              Y_Values[x]:=y;
              Timer1.Enabled :=true;
            end;
         end;
    end;
    procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      扫描屏幕,并得到整个屏幕的像素点,放在数组Y_Values[x]:=y
    end;
    procedure TForm1.Timer1Timer(Sender: TObject);
    var
      i:word;
    begin
      paintbox1.Refresh;
      image1.Picture.Bitmap.LoadFromFile('1.bmp');//整个屏幕擦除
      paintbox1.Canvas.MoveTo(Zero ,Y_Values[Zero] );
         for i:=1 to Max_Y_Values.x do
           begin
            paintbox1.Canvas.LineTo(i,Y_Values[i]);
           end;
    end;
    问题:鼠标移动快,捕捉到的点太少,而且鼠标按下移动过程只能看到很闪的波形,等鼠标停下来的时候,只剩下一个被擦除了的屏幕,没有波形。请大家提提建议
      

  29.   

    to DelphiGuy:
       问题还没有解决,但为了答谢各位,先给大家结贴了哦,虽然分不多。