1.以下得到桌面窗口的代码有没有错误?
var
dc:hdc;
canvas:tcanvas;
begin
dc:=getdc(getdesktopwindow);
canvas:=tcanvas.create;
canvas.handle:=dc;...releasedc(dc);
end;2.如果得到了canvas,那么用framerectange等方法确实可以画一个矩形,
但是我想在鼠标按下后托动的过程中,动态的出现一个虚线匡矩形,起点就是鼠标按下的点,终点就是现在鼠标的位置。
但是鼠标是在不断移动的,矩形的尺寸也应该是随鼠标移动变化的,但是单纯的画矩形就会留下一连串矩形,很难看,请问已经画完的矩形怎样消除?请注意,我要在image上画图,并不是单色的背景。谢谢!

解决方案 »

  1.   

    canvas.Pen.Mode := pmNotXor;
      

  2.   

    好像不行啊,我的image里面已经装载了一幅图片,但是一画矩形,就变成白背景了,原来的位图没了阿?!unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, EnJpgGr, ExtCtrls,jpeg;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Panel1: TPanel;
        Image1: TImage;
        OpenDialog1: TOpenDialog;
        procedure FormCreate(Sender: TObject);
        procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure Button1Click(Sender: TObject);
      private
        fselecting:boolean;
        fbeginpt,fendpt:tpoint;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
      
      fselecting:=false;  
    end;procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      fselecting:=true;
      fbeginpt:=image1.ScreenToClient(mouse.CursorPos);
      image1.Canvas.Pen.Mode:=pmNotXor;
      //image1.Canvas.Pen.Color:=clblue;
    end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      fselecting:=false;
      fendpt:=image1.ScreenToClient(mouse.CursorPos);
    end;procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      fendpt:=image1.ScreenToClient(mouse.CursorPos);
      if fselecting then
      begin    image1.Canvas.FillRect(image1.Canvas.ClipRect);
        //image1.Canvas.DrawFocusRect(rect(fbeginpt,fendpt));
        image1.Canvas.Rectangle(rect(fbeginpt,fendpt));
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
    jpg:tjpegimage;
    begin
      if opendialog1.Execute then
      begin
        jpg:=tjpegimage.Create;
        jpg.LoadFromFile(opendialog1.FileName);
        image1.Picture.Bitmap.Assign(jpg);
        jpg.Free;
      end;
    end;end.
      

  3.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, EnJpgGr, ExtCtrls,jpeg;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Panel1: TPanel;
        Image1: TImage;
        OpenDialog1: TOpenDialog;
        procedure FormCreate(Sender: TObject);
        procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure Button1Click(Sender: TObject);
      private
        fselecting:boolean;
        fbeginpt,fendpt:tpoint;
        FRect:TRect;    //全局rect;
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
    begin
      
      fselecting:=false;  
    end;procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      fselecting:=true;
      fbeginpt:=image1.ScreenToClient(mouse.CursorPos);
    end;procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      fselecting:=false;
      fendpt:=image1.ScreenToClient(mouse.CursorPos);
    end;procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      fendpt:=image1.ScreenToClient(mouse.CursorPos);
      if fselecting then
      begin
        image1.Canvas.Pen.Mode:=pmNotXor;
        Image1.Canvas.Brush.Style := bsClear;
        image1.Canvas.Pen.Color:=clblue;    //image1.Canvas.FillRect(image1.Canvas.ClipRect);//不要
        //image1.Canvas.DrawFocusRect(rect(fbeginpt,fendpt));
        image1.Canvas.Rectangle(Frect);
        FRect:=rect(fbeginpt,fendpt);
        image1.Canvas.Rectangle(Frect);  
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
    jpg:tjpegimage;
    begin
      if opendialog1.Execute then
      begin
        jpg:=tjpegimage.Create;
        jpg.LoadFromFile(opendialog1.FileName);
        image1.Picture.Bitmap.Assign(jpg);
        jpg.Free;
      end;
    end;end.
      

  4.   

    var
      OldRect,NewRect:TRect;
      MouseDown:Boolean;
    //在MouseDown事件中:
    OldRect.Left:=x;
    OldRect.Top:=y;
    OldRect.Right:=x;
    OldRect.Bottom:=y;
    MouseDown:=true;
    //在MouseMove事件中:
    if MouseDown=true then
    begin
      image1.Canvas.DrawFocusRect(OldRect);
      NewRect.Right:=x;
      NewRect.Bottom:=y;
      Image1.Canvas.DrawFocusRect(NewRect);
    end;//这样写只能从左上角画到右下角,如果需要全方位的话,自己考虑处理新矩形区域的关系吧!//在mouseUp事件中:
    MouseDown:=false;
      

  5.   

    十分感谢各位的帮助!
    还有个小问题,就是画矩形的时候经常出现图片闪动,但是把image.strech:=true就没有了闪动,请问这是怎么回事?我想考屏,用全局鼠标钩子再桌面上选个区域,请问怎样避免闪动?谢谢!
      

  6.   

    {以下是dll的代码,请问为什么不能实现在桌面canvas上画出矩形?还有个大问题,似乎只有delphi程序的窗口中鼠标按下是513消息,鼠标松开是514,其他窗口都不是,我这个全局鼠标钩子肯定是挂上了,但是在其他窗口,比如资源管理器里面按下鼠标就不会beep,就是说在那里的鼠标按下消息不是513,请问怎样解决?}
    unit captureunit;interface
    uses
    windows,sysutils,messages,global,debug_san,
    classes,graphics;
    function beginselect(awnd:integer):integer;stdcall;
    function endselect():integer;stdcall;implementation
    var
    selecting:boolean=false;
    startpoint,endpoint:tpoint;
    hhook:cardinal;
    wnd:cardinal;
    dc:hdc;
    canvas:tcanvas;
    frect:trect;
    //////////////////////
    function hookproc(ncode:smallint;wparam,lparam:integer):integer;stdcall;
    begin
      result:=1;
      
      case wparam of
      sm_mouseup:
      begin
        beep;
        selecting:=false;
        endpoint:=PMOUSEHOOKSTRUCT(lparam)^.pt;
        postmessage(wnd,sm_selected,integer(@startpoint),integer(@endpoint));
        
      end;
      sm_mousedown:
      begin
        beep;
        selecting:=true;
        //getcursorpos(endpoint);
        startpoint:=PMOUSEHOOKSTRUCT(lparam)^.pt;  end;
      WM_MOUSEMOVE:
      begin
         //getcursorpos(endpoint);
    //     result:=0;     if selecting then
         begin
           endpoint:=PMOUSEHOOKSTRUCT(lparam)^.pt;
           //canvas.Lock;
           Canvas.Rectangle(frect);
           fRect:=rect(startpoint,endpoint);
           Canvas.Rectangle(frect);
           //canvas.TextOut(0,0,'sss');
           //canvas.Unlock;
           beep;
         end;  end;
      else
         result:=0;
      end;
      if ncode<0 then
        result:=callnexthookex(hhook,ncode,wparam,lparam);
    end;
    //////////////////function beginselect(awnd:integer):integer;stdcall;
    begin
      wnd:=awnd;
      //msg2(wnd);
      dc:=getdc(getdesktopwindow);
      canvas.Handle:=dc;
      hhook:=setwindowshookex(WH_MOUSE,@hookproc,hinstance,0);
      result:=hhook;
      canvas.Pen.Mode:=pmNotXor;
      Canvas.Pen.Color:=clblue;
      Canvas.Brush.Style := bsClear;end;function endselect():integer;stdcall;
    begin
      releasedc(getdesktopwindow,dc);
      unhookwindowshookex(hhook);
    end;
    initialization
      canvas:=tcanvas.Create;
    finalization
      canvas.Free;  
    end.
    ///////////////////////////////////////////unit global;interfaceuses
    windows,sysutils,messages;const
    sm_mouseup=514;
    sm_mousedown=513;sm_selected=wm_user+1000;c_capturedll='capture.dll';
    c_beginselect='beginselect';
    c_endselect='endselect';implementationend.
      

  7.   

    library capture;uses
      SysUtils,
      captureunit in 'captureunit.pas';{$R *.res}exports
      beginselect,
      endselect;
    end.
      

  8.   

    解决闪动问题的办法是:在窗体的oncreate事件中,将Image1.parent.DoubleBuffered:=true;设置图像双缓冲就可以了!