Delphi 在应用程序顶部绘制/覆盖一个矩形框并捕获鼠标XY
我有一个CAD应用程序,我正试图建立一个插件,我需要能够选择直线和圆弧。我不能直接从应用程序中执行此操作。在我的代码中,我想开始用鼠标徒手绘制一个窗口矩形。通过API,我可以确定刚才绘制的矩形中包含了哪些线/弧Delphi 在应用程序顶部绘制/覆盖一个矩形框并捕获鼠标XY,delphi,draw,windowing,Delphi,Draw,Windowing,我有一个CAD应用程序,我正试图建立一个插件,我需要能够选择直线和圆弧。我不能直接从应用程序中执行此操作。在我的代码中,我想开始用鼠标徒手绘制一个窗口矩形。通过API,我可以确定刚才绘制的矩形中包含了哪些线/弧 问题是,如何在另一个应用程序上从鼠标中绘制一个矩形?左键单击以开始左上角,拖动以调整大小,然后释放左键单击以结束矩形?也没有真正的表单,所以我不知道是否可以使用picturebox/TCanvas或其他什么。对我来说,这就像是一个窗口屏幕截图,您可以在要保存的屏幕部分上绘制一个矩形。关于
问题是,如何在另一个应用程序上从鼠标中绘制一个矩形?左键单击以开始左上角,拖动以调整大小,然后释放左键单击以结束矩形?也没有真正的表单,所以我不知道是否可以使用picturebox/TCanvas或其他什么。对我来说,这就像是一个窗口屏幕截图,您可以在要保存的屏幕部分上绘制一个矩形。关于您在“如何在屏幕上绘制矩形”的评论部分中的最后一个问题: 您必须通过以下方式获得当前桌面的句柄:
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中完成的,但应该可以工作
在DelphiForFun中还有一个如何在屏幕上绘制矩形的实用示例
在DelphiForfun中还有一些例子,说明了如何创建自己的绘图程序来实现自己的目标。
检查:
1) 计算几何:(用鼠标绘制画布的极好例子)
2) 图形搜索:
顺便说一句,你说你正在开发一个插件,所以:
a) CAD应用程序是否为第三方?如果是这样的话,那么您的CAD程序可能已经有了一个API接口来管理与视口交互的插件,因此应该有一种方法可以获取地图查看器的画布参考以及绘制形状的方法
b) 你开发CAD应用程序吗?然后,如果您想将其添加为插件,那么您应该设计API结构,以便在注册插件时,您还可以添加插件可以访问视口画布的方式
JEDI VCL有一些插件系统组件(TJvPlugin和TJvPluginManager),可以帮助您用非常简单的步骤为应用程序构建插件框架。我曾经按照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.
如果您正在编写插件,那么您并不是在另一个应用程序上绘图。您的插件可能是一个与主机应用程序在同一地址空间中运行的DLL。这给了你更多的空间。这是真的,但我仍然不能直接访问实体,所以我可以选择它们。这就是我想出的解决办法。似乎可以识别鼠标点击和位置,我只需要在屏幕上直观地抛出一个矩形。在屏幕上绘制矩形,然后将给定的矩形点从屏幕转换到客户端。如何在屏幕上绘制矩形?