1

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

问题是,我怎样才能在另一个应用程序上用鼠标绘制一个矩形?左键单击开始左上角,拖动调整大小,然后松开左键结束矩形?也没有真正涉及表单,所以我不知道我是否可以使用图片框/TCanvas 或什么。对我来说,这就像一个窗口屏幕截图,您在要保存的屏幕部分上绘制一个矩形。

4

2 回答 2

2

我曾经按照 fduenas 的建议异或绘制一个矩形,它工作得很好,但这在 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.
于 2013-08-15T07:11:24.467 回答
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

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

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

b) 您是否开发 CAD 应用程序?那么如果您想将其添加为插件,那么您应该设计您的 API 结构,以便在注册插件时您还可以添加一种插件可以访问 ViewPort 画布的方式

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

于 2013-07-13T14:33:34.617 回答