procedure TForm2.Timer1Timer(Sender: TObject);
var
  Fullscreen:TBitmap;
  FullscreenC:TCanvas;
  dc:HDC;
begin
  Timer1.Enabled:=false;
  Fullscreen:=TBitmap.Create;
  Fullscreen.Width:=Screen.Width;
  Fullscreen.Height:=Screen.Height;
  DC:=GetDC(0);
  FullscreenC:=Tcanvas.Create;
  FullscreenC.Handle:=DC;
  Fullscreen.Canvas.CopyRect(Rect(0,0,Screen.Width,screen.Height),FullScreenC,
  rect(0,0,Screen.Width,screen.Height));
  FullscreenC.Free;
  ReleaseDC(0,DC);
  self.Image1.Picture.Bitmap:=Fullscreen;
  self.Image1.Width:=Fullscreen.Width;
  Self.Image1.Height:=FullScreen.Height;
  Fullscreen.Free;
  Form2.WindowState:=wsMaximized;
  Form2.Show;
  MessageBeep(1);
  foldx:=-1;
  foldy:=-1;
  self.Image1.Canvas.Pen.Mode:=pmNot;
  self.Image1.Canvas.Pen.Color:=clBlack;
  self.Image1.Canvas.Brush.Style:=BSCLEAR;
  flag:=true;
end;
    //能解释下么???

解决方案 »

  1.   

    Timer ....  你是问 Timer 还是问你上面代码里面的内容啊?Timer的用途就是在 VCL 里面定时的执行一段过程. 是封装好了的系统的 SetTime API
      

  2.   

    代码的作用是时间一到,就对屏幕进行截图,将图反映在Form2(可能是个无边框的窗体)里的Image1(可能Image1.Align是=alClient的)上,Form2最大化,接下来的代码  foldx:=-1;//估计是记录鼠标x坐标的全局变量
      foldy:=-1;//估计是记录鼠标y坐标的全局变量
      //下面三行设置Image1的画布的Pen和Brush的风格:
      self.Image1.Canvas.Pen.Mode:=pmNot;
      self.Image1.Canvas.Pen.Color:=clBlack;
      self.Image1.Canvas.Brush.Style:=BSCLEAR;
      flag:=true;//估计是表示鼠标被按下的标识估计,这时候,就可以利用鼠标在Form2里的Image上进行涂鸦了。
    你看看,Form2的单元里,是否还有这样的代码:procedure TForm1.Image2MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      foldx:=x;
      foldy:=y;
      image1.Canvas.MoveTo(x,y);
      flag:=true;
    end;procedure TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if flag then image1.Canvas.LineTo(x,y);
    end;procedure TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      flag:=false;
    end;
      

  3.   

    或者是这个样子:procedure TForm2.Image2MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      foldx:=x;
      foldy:=y;
      image1.Canvas.MoveTo(x,y);
      flag:=fale;
    end;procedure TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if not flag then image1.Canvas.LineTo(x,y);
    end;procedure TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      flag:=true;
    end;
      

  4.   

    假如Image1是放在一个Panel1(Panel1.Align是=alClient的)上的,而代码是这样子:procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      Form2.Canvas.MoveTo(foldx,foldy);
      Form2.Canvas.LineTo(x,y);
      foldx:=x;
      foldy:=y;
    end;
    哼哼,这代码就不是在涂鸦那么简单了哦!
      

  5.   

    timer 只是一个定时器,有timer的程序,也是单线程,多个timer也是有先后顺序的。
      

  6.   

    我仅仅是个业余爱好的新手,上面都是乱猜的。
    确实如此。不过,截屏就截屏了,但后面的动作就渗透着一些诡异(可能我太阴谋论了):让我来假设一下,截完屏后,打开一个无边框的、最大化的窗体,窗体最前面是刚截的图,这图将整个屏幕盖住了,让人看起来感到还是面对着一个平时的桌面(为什么要这么做呢),接着,代码初始化了一个坐标[-1,-1](它不在屏幕内),然后,还设置了一个标志flag(这些都真的为了涂鸦吗?),不要忘了,这一切动作,是由一个定时器触发的(为什么定时地去用一张假的屏幕截图去盖着桌面?),如果这截图盖着屏幕的时刻,刚好是我调用了qq的软键盘在输入密码,鼠标事件中,利用foldx、foldy变量来记录着我点过的位置(就如我在4楼的猜测那样),窗体背后,有个相当于模拟点击作用的代码,去点击真正的软键盘,当密码点击完的时候,揭开伪装的屏幕....,呵呵,不用我再往下解释了吧。
    其实,我想太多了!即使如此,我现在感兴趣的,已经不是悬赏的那40分了,很想搂主能贴出 Image1MouseDown 事件的代码,以释去心中的好奇。
      

  7.   

    可能真的想歪了,  self.Image1.Canvas.Pen.Mode:=pmNot;
      self.Image1.Canvas.Pen.Color:=clBlack;
      self.Image1.Canvas.Brush.Style:=BSCLEAR;
    分明就是为了在Image1上绘、画
      

  8.   

    procedure TForm2.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      width,height:integer;
      nb:TBitmap;
    begin
      if tr=false then
      begin
        flag:=false;
        with self.Image1.Canvas do
        begin
          Moveto(foldX,0);
          Lineto(Foldx,screen.Height);
          moveto(0,foldy);
          lineto(screen.Width,foldy);
        end;
        x1:=X;
        y1:=y;
        oldx:=x;
        oldy:=y;
        tr:=true;
        image1.Canvas.Pen.Mode:=pmnot;
        image1.Canvas.Pen.Color:=clblack;
        image1.Canvas.Brush.Style:=bsclear;
      end
      else
      begin
        x2:=x;
        y2:=y;
        tr:=false;
        image1.Canvas.Rectangle(x1,y1,oldx,oldy);
        width:=abs(x2-x1);
        height:=abs(y1-y2);
        form1.Image1.Width:=Width;
        nb:=TBitmap.Create;
        nb.Width:=width;
        nb.Height:=height;
        nb.Canvas.CopyRect(Rect(0,0,width,height),form2.Image1.Canvas,
        rect(X1,y1,x2,y2));
        form1.Image1.Picture.Bitmap:=nb;
        nb.Free;
        form2.Hide;
        form1.Show;
      end;
    end;procedure TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if tr=true then
      begin
        with image1.Canvas do
        begin
          rectangle(x1,y1,oldx,oldy);
          Rectangle(x1,y1,x,y);
          oldx:=x;
          oldy:=y;
        end;
      end
      else if flag=true then
      begin
        with image1.Canvas do
        begin
          moveto(foldx,0);
          lineto(foldx,screen.Height);
          moveto(0,foldy);
          lineto(screen.Width,foldy);
          moveto(x,0);
          lineto(x,screen.Height);
          moveto(0,y);
          lineto(screen.Width,y);
          foldx:=x;
          foldy:=y;
        end;
      end;
    end;procedure TForm2.FormCreate(Sender: TObject);
    begin
      timer1.Enabled:=False;
      self.WindowState:=wsMaximized;
    end;end.
      

  9.   

    非常感谢楼主!!!我再次献丑,将我对代码的理解描述如下:......var
      Form2: TForm2;implementationuses Unit1;{$R *.dfm}
    var foldx, foldy, oldx, oldy, x1, y1, x2, y2:integer;
        tr, flag: boolean;procedure TForm2.Timer1Timer(Sender: TObject);
    var Fullscreen:TBitmap;
        FullscreenC:TCanvas;
        dc:HDC;
    begin
      Timer1.Enabled:=false;//将定时器关闭
      Fullscreen:=TBitmap.Create;//在内存里建立一个位图
      Fullscreen.Width:=Screen.Width;//让位图设置为屏幕的尺寸,下同
      Fullscreen.Height:=Screen.Height;
      DC:=GetDC(0);//取桌面的DC
      FullscreenC:=Tcanvas.Create;//建立一个画布
      FullscreenC.Handle:=DC;//将桌面的DC作为画布的句柄(这时候,FullscreenC 就指向了桌面的画布了)
      Fullscreen.Canvas.CopyRect(Rect(0,0,Screen.Width,screen.Height),FullScreenC,
        rect(0,0,Screen.Width,screen.Height));//将整个桌面的位图复制到 Fullscreen
      FullscreenC.Free;//画布对象用完了,所以将它释放
      ReleaseDC(0,DC);//释放DC
      self.Image1.Picture.Bitmap:=Fullscreen;//将Image1的位图指向内存中 Fullscreen 的数据
      self.Image1.Width:=Fullscreen.Width; //将Image1的尺寸设置为 Fullscreen 的尺寸(等同屏幕尺寸了)
      Self.Image1.Height:=FullScreen.Height;//同上
      Fullscreen.Free;//将内存中的位图释放(利用内存中的位图而不是拿Image1来操作,是为了不产生闪烁)
      Form2.WindowState:=wsMaximized;//最大化 Form2
      Form2.Show;//将 Form2 显示出来
      MessageBeep(1);//哔 一声
      foldx:=-1;//将坐标值设置到[-1,-1]
      foldy:=-1;
      self.Image1.Canvas.Pen.Mode:=pmNot;//设置画笔与背景的颜色混合模式——背景反色
      self.Image1.Canvas.Pen.Color:=clBlack; //画笔为黑色
      self.Image1.Canvas.Brush.Style:=BSCLEAR;//设置画刷风格
      flag:=true; //将标志设置为真。(需要画十字线的标志)
    end;procedure TForm2.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer); //鼠标键被按下
    var
      width,height:integer;
      nb:TBitmap;
    begin
      if tr=false then begin //第一次按下
        flag:=false;//不再画十字线
        with self.Image1.Canvas do begin //画十字线:
          Moveto(foldX,0);
          Lineto(Foldx,screen.Height);//画竖线
          moveto(0,foldy);
          lineto(screen.Width,foldy);//画横线
        end;
        x1:=X;//记住目前坐标,以作画矩形和截图时的"起始"坐标点
        y1:=y;//同上
        oldx:=x;//记住目前坐标,以作下次清除矩形时的"结束"坐标点
        oldy:=y;//同上
        tr:=true;//改变标志状态,当这状态为真时,就是第二次按下鼠标键了
        image1.Canvas.Pen.Mode:=pmnot;
        image1.Canvas.Pen.Color:=clblack;
        image1.Canvas.Brush.Style:=bsclear;
      end
      else begin             //第二次按下
        x2:=x; //记住目前坐标,以作截图时的"结束"坐标点
        y2:=y; //同上
        tr:=false;//不再画矩形
        image1.Canvas.Rectangle(x1,y1,oldx,oldy);//清除矩形
        width:=abs(x2-x1);//根据记住的坐标,计算出截图的宽度(由于"起始"点有可能大于"结束"点,所以采用两数差的绝对值)
        height:=abs(y1-y2);//根据记住的坐标,计算出截图的高度
        form1.Image1.Width:=Width;//将Form1里的Image1设置相同的宽度
        nb:=TBitmap.Create;//建立内存位图
        nb.Width:=width;//根据矩形选定的范围设置内存位图的尺寸
        nb.Height:=height;//同上
        nb.Canvas.CopyRect(Rect(0,0,width,height),form2.Image1.Canvas,
          rect(X1,y1,x2,y2));//将form2.Image1被矩形选定的范围复制到内存位图
        form1.Image1.Picture.Bitmap:=nb;//将Form1的Image1的位图指向内存位图的数据
        nb.Free;//释放内存位图
        form2.Hide;//隐藏Form2
        form1.Show;//将Form1显示出来,至此,截图结束。
      end;
    end;procedure TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer); //鼠标在 Image1 上移动
    begin
      if tr=true then begin//如果需要画矩形
        with image1.Canvas do begin
          rectangle(x1,y1,oldx,oldy);//清除上次画的矩形
          Rectangle(x1,y1,x,y);//画新的矩形
          oldx:=x; //记下目前坐标,以作下次清除矩形时的"结束"坐标
          oldy:=y; //同上
        end;
      end
      else if flag=true then begin //如果需要画十字线
        with image1.Canvas do begin
          moveto(foldx,0);
          lineto(foldx,screen.Height);//清除上一次画的十字线的竖线
          moveto(0,foldy);
          lineto(screen.Width,foldy);//清除上一次画的十字线的横线
          moveto(x,0);
          lineto(x,screen.Height);//画新的十字线的竖线
          moveto(0,y);
          lineto(screen.Width,y);//画新的十字线的横线
          foldx:=x;//记录目前的坐标,以作下一次画十字线的起点
          foldy:=y;//同上
        end;
      end;
    end;......