【问题标题】:Draw/overlay a rectangle box on top of application and capture mouse XY在应用程序顶部绘制/覆盖一个矩形框并捕获鼠标 XY
【发布时间】:2013-07-10 23:26:31
【问题描述】:

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

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

【问题讨论】:

  • 如果您正在编写插件,那么您并没有完全在 另一个 应用程序上绘图。您的插件可能是在与宿主应用程序相同的地址空间中运行的 DLL。这给了你更多的回旋余地。
  • 这是真的,但我仍然无法直接访问实体,因此我可以选择它们。这是我想出的解决方法。识别鼠标点击和位置似乎是可行的,我只需要在屏幕上直观地抛出一个矩形。
  • 在屏幕上绘制矩形,然后将给定的矩形点从屏幕转换到客户端。
  • 如何在屏幕上画一个矩形?

标签: delphi draw windowing


【解决方案1】:

我曾经按照 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.

【讨论】:

    【解决方案2】:

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

    您必须通过以下方式获取当前桌面的句柄:

    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),可帮助您通过非常简单的步骤为您的应用程序构建插件框架。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多