在应用程序顶部绘制/覆盖矩形框并捕获鼠标XY

时间:2013-07-10 23:26:32

标签: delphi draw windowing

我有一个CAD应用程序我正在尝试构建一个插件,我需要能够选择线条和弧线。我无法直接从应用程序中执行此操作。在我的代码中,我想开始用鼠标自由地绘制一个窗口矩形。通过API,我可以确定刚刚绘制的矩形中包含哪些线/弧。

问题是,如何从我的鼠标在另一个应用程序的顶部绘制一个矩形?左键单击以开始左上角,拖动以调整大小,然后释放左键单击以结束矩形?也没有涉及的形式,所以我不知道我是否可以使用picturebox / TCanvas或什么。对我来说,这就像一个窗口捕获屏幕,您可以在屏幕上绘制一个要保存的部分。

2 个答案:

答案 0 :(得分:2)

我曾经根据fduenas提出的XOR绘制一个矩形并且效果很好,但是在Windows Vista和7上这不能很好地工作。如果你画出不断变化的区域(和如果你之后删除它,矩形将保留。)

相反,我现在使用一个矩形窗口,里面有一个矩形孔。您所要做的就是重新定位窗口。您可以在 MouseDown 中创建并显示它,在 MouseMove 中重新定位并在 MouseUp 中将其销毁。

将TDragRectangleForm的BorderStyle设置为bsNone。

unit FrmDragRectangle;

// TDragRectangleForm is a rectangular window with a rectangular hole.
// Only its dotted border is visible.

interface

uses
  Windows, Forms, Graphics, Classes;

type
  TDragRectangleForm = class( TForm )
    procedure FormResize( Sender : TObject );
  public
    procedure Show;
  end;

implementation

{$R *.dfm}

procedure TDragRectangleForm.Show;
begin
  // Show the window without stealing the focus from another window:
  ShowWindow( Handle , SW_SHOWNOACTIVATE );
  Visible := True;
end;

procedure TDragRectangleForm.FormResize( Sender : TObject );
const
  nBorderWidth = 1;
var
  hrgnRect1 , hrgnRect2 : HRGN;
begin
  // Make a rectangular hole in the window:
  hrgnRect1 := CreateRectRgn( 0 , 0 , Width , Height );
  hrgnRect2 := CreateRectRgn( nBorderWidth , nBorderWidth , Width - nBorderWidth , Height - nBorderWidth );

  CombineRgn( hrgnRect1 , hrgnRect1 , hrgnRect2 , RGN_DIFF );
  SetWindowRgn( Handle , hrgnRect1 , True );
  DeleteObject( hrgnRect2 );

  Canvas.Pen.Style := psDot;
  Canvas.Pen.Color := clWhite;
  Canvas.Brush.Color := clBlack;
  Canvas.Rectangle( 0 , 0 , Width , Height );
end;

end.

答案 1 :(得分:1)

关于“如何在屏幕上绘制矩形?”的评论部分中的最后一个问题:

您必须使用以下内容获取当前桌面的句柄:

procedure TForm1.FormCreate(Sender: TObject);
begin
  fCanvas := TCanvas.Create;
  fCanvas.Handle := GetWindowDC(0); //or CreateDC('DISPLAY', nil, nil, nil);
end; 

注意:fCanvas被声明为TForm1的一个字段,例如:

Type 
  Tform1=Class(tForm)
  ...
  ...
  protected
   fCanvas: TCanvas
 End;

请记住,在销毁TForm1时必须释放fCanvas

procedure TForm1.FormDestroy(Sender: TObject);
begin
  fCanvas.Free;
end; 

可在此处查看完整示例: 它是在旧版本的Delphi中完成的,但它应该可以工作 http://www.delphitricks.com/source-code/graphic/draw_directly_to_the_desktop.html

另外在DelphiForFun中是一个如何在屏幕上绘制矩形的实际示例 http://www.delphiforfun.org/Programs/Delphi_Techniques/Canvas_Drawing.htm

同样在DelphiForfun中,您可以创建自己的绘图程序,以实现您想要实现的目标。 检查:

1)计算几何:http://www.delphiforfun.org/Programs/Library/geometry1.htm(使用鼠标绘制画布的绝佳示例)

2)图搜索:http://www.delphiforfun.org/Programs/Library/Graphs1.htm

BTW只是为了澄清,你说你正在开发一个插件,所以:

a)CAD应用程序是3rt派对吗?如果是这样,那么您的CAD程序可能已经有一个API接口来管理与ViewPort交互的插件,因此应该有一种方法可以获得Map查看器的画布参考以及绘制形状的方法。

b)您是否开发了CAD应用程序?那么如果你想把它作为插件添加,那么你应该设计你的API结构,这样在注册插件时你还可以添加插件可以访问ViewPort画布的方式

JEDI VCL有一些插件系统组件(TJvPlugin和TJvPluginManager),可帮助您通过非常简单的步骤为您的应用程序构建插件框架。