首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Delphi Graphics32将普通层和绘图层相结合

Delphi Graphics32将普通层和绘图层相结合
EN

Stack Overflow用户
提问于 2015-02-20 07:52:16
回答 1查看 1.6K关注 0票数 0

通过绘制图层,我指的是用户可以手动绘制线条、圆圈或其他形状的图层。对于普通层,我指的是graphics32层示例中描述的层(可以在运行时使用鼠标事件移动或调整大小的层),所以我很难组合这两种类型的层。在我的测试项目中,现在我假设我只有一个绘图层和多个PNG层。因此,在我的项目中,我在ImgView32中为OnFormCreate设置了属性,如:

代码语言:javascript
运行
复制
procedure TForm1.FormCreate(Sender: TObject);
begin
  AWidth:= 800;
  AHeight:= 600;
  FillColor:=clWhite;

  with ImgView do
  begin
    Selection := nil;
    RBLayer := nil;
    Layers.Clear;
    Scale := 1;
    Scaled:=true;
    Bitmap.SetSize(AWidth, AHeight);
    Bitmap.DrawMode := dmTransparent;
    Bitmap.Clear(FillColor);
  end;
end;

在此之后,onClick的一个按钮,我添加了许多层(包含透明的PNG图像)。所以就像这样

代码语言:javascript
运行
复制
procedure TForm1.Button1Click(Sender: TObject);
begin
  AddPNGLayer(1);
  AddPNGLayer(2);
  AddDrawingLayer;
  AddPNGLayer(3);
end;

(为了使问题简短,我不想在这里详细说明添加PNG层。我只想说,它使用的onMouseDown事件(layerMouseDown)与drawingLayer中使用的事件不同,AddDrawingLayer如下所示:

代码语言:javascript
运行
复制
procedure TForm1.AddDrawingLayer;
var
  P:TPoint;
  jumaH, JumaW, W, H: Single;
begin
  imwidth := ImgView.Bitmap.Width;
  imheight := ImgView.Bitmap.Height;

  xofx := (ImgView.ClientWidth - 17 - imwidth) div 2; // substracting the width of the scrollbar
  yofy := (ImgView.ClientHeight - 17 - imheight) div 2; // same here with height

  bm32 := TBitmap32.Create;
  bm32.DrawMode := dmTransparent;
  bm32.SetSize(ImgView.Bitmap.Width,ImgView.Bitmap.Height);
  bm32.Canvas.Pen.Width := 3;
  bm32.Canvas.Pen.Color := clBlack32;//pencolor;

  BB := TBitmapLayer.Create(ImgView.Layers);
  try
    BB.Bitmap.DrawMode := dmTransparent;
    BB.Bitmap.SetSize(imwidth,imheight);
    BB.Bitmap.Canvas.Pen.Width := 3;
    BB.Bitmap.Canvas.Pen.Color := pencolor;
    BB.Location := GR32.FloatRect(0, 0, imwidth, imheight);
    BB.Scaled := true;
    BB.Tag:=3;
////    Selection:=BB;  // if I use this then I cant draw because the entire layer is selected and the mouseDown event works as a mover/resizer
//    BB.OnMouseDown := DrLayerMouseDown;
//    BB.OnMouseUp := DrLayerMouseUp;
//    BB.OnMouseMove := DrLayerMouseMove;
//    BB.OnPaint := DrLayerOnPaint;
    RBLayer:=nil;
    EdLayerIndex.Text:=IntToStr(BB.Index);
  finally
    BB.Free;
  end;
  FDrawingLine := false;
//    swapBuffers32; // needed when mouse events are active
end;

EdLayerIndex是一个EditBox,我在其中显示创建/选择的层索引(用于调试)。

  • 正如您在上面看到的,如果我保留了Selection:=BBRBLayer:=nil,那么drawingLayer只能是可移动的和可调整大小的,所以这不是一个好的解决方案,因为我想使用这个特定层中的鼠标事件来绘制。
  • 如果我只评论RBLayer:=nil而保留Selection:=BB,那么drawingLayer就不再是可移动的了,但是我不能选择drawingLayer下的其他层。我只能访问顶层(最后一次添加PNG层)。
  • 如果我评论Selection:=BB,那么我就不能用鼠标选择其他层。因此,在我的例子中,我在drawingLayer之前声明了两个png层,在它之后声明了一个。在运行时,我只能选择最后一个层(“高于”drawingLayer),因此这也不是一个解决方案。

当我单击绘图层(或者在列表框或其他地方选择它)时,drawingLayer将无法移动,但我的绘图鼠标事件会启动?所有这一切,我可以离开drawingLayer,随时我想,并选择其他层移动和播放。所以基本上,我需要一个特殊的图层,而不是其他的层。

我想实现的是拥有一个典型的类似Photoshop或类似paint.net的行为使用graphics32。这些层的属性是如何工作的,这是非常令人困惑的。

到目前为止,我已经知道了如何动态地(使用鼠标事件)在透明层上绘制(线条、圆圈、矩形)。这样我就可以画一个图层了。这幅画发生在我的DrLayerMouseDownDrLayerMouseUpDrLayerMouseMoveDrLayerPaint事件中。但我似乎不明白如何将这样的绘图层与可移动/可调整大小的规则层相结合。

其余的代码(如setSelectionRBResizinglayerMouseDown)主要是从graphics32库的层示例中获取的。

编辑

为了用layerOptions测试您的想法,我做了以下工作:

1.启动一个新的测试项目,上面有一个ImgView,还有一个按钮

2.在创建时,我使用了与前面相同的代码

3.OnButtonClick使用修改后的AddDrawingLayer添加了一个层,如下所示:

代码语言:javascript
运行
复制
...
    BB.Scaled := true;
    Selection:=BB;
    Selection.LayerOptions:=Selection.LayerOptions and (not LOB_MOUSE_EVENTS); // I also tried it with BB instead of Selection
    BB.OnMouseDown := DrLayerMouseDown;
    BB.OnMouseUp := DrLayerMouseUp;
    BB.OnMouseMove := DrLayerMouseMove;
    BB.OnPaint := DrLayerOnPaint;
...

希望它对鼠标事件变得不敏感。但这一层仍然是可移动的,而不是对鼠标不敏感。所以我好像什么都没做

因此,我不认为它帮助我使用这个选项,除非我做错了,所以层的onCreate,这个选项似乎不坚持。但是,如果我禁用了所有层的鼠标事件,像在下一个编辑中一个一个地禁用鼠标事件,那么绘图层将被禁用(鼠标事件)。

编辑

我还尝试了另一个测试项目,相同的想法:相同的onCreate和onButtonClick --我添加了3个层(使用库的图层示例),每个层都包含一个图像(这次没有绘图层,以保持简单)。然后,我添加了一个新按钮,如果单击它,将执行下一段代码:

代码语言:javascript
运行
复制
  for i := 0 to ImgView.Layers.Count-1 do
    (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions:= (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions and (not LOB_MOUSE_EVENTS);

我的目的是让所有层都对鼠标事件不敏感。我成功了,在单击新按钮后,无法再选择这些层,但是,当我希望为这些层重新启用鼠标事件时(添加第三个带有下一个代码onClick的按钮):

代码语言:javascript
运行
复制
  for i := 0 to ImgView.Layers.Count-1 do
    (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions:= (ImgView.Layers.Items[i] as TPositionedLayer).LayerOptions and (LOB_MOUSE_EVENTS);

没有显示错误,但是当我试图选择一个图层来移动它时.所有的图层图像都从视野中消失了.给我留下一个白色背景空ImgView。

我做错了什么?为了执行您对LayerOptions的建议,我需要能够禁用所有层的鼠标事件,并为特定层启用鼠标事件,然后当编辑完成时,我需要能够为所有层重新启用鼠标事件,但我想我做错了。

EN

回答 1

Stack Overflow用户

发布于 2015-02-22 13:15:46

下列项目影响鼠标事件

  • Layers.MouseEvents (布尔型)层是管理层的TLayerCollection of TCustomImage32。如果MouseEvents为False,则鼠标事件不会传播到这些层。
  • Layers.MouseListener (TCustomLayer)。在左侧按钮MouseDown和MouseUp之间“捕获”鼠标事件的层。以quoutes表示的“‘Captures”,因为它没有像Windows上下文所理解的那样捕获鼠标。
  • 图层选项位每个层都有一个32位的LayerOptions属性。有趣的是LOB_MOUSE_EVENTS (位29),它指定层是否响应鼠标事件。一层还可以指定LOB_NO_CAPTURE位(位27)来防止鼠标事件,即使设置了LOB_MOUSE_EVENTS。
  • 层指数对于LOB_MOUSE_EVENTS选项位,将检查层(从最顶层到最低层)。当使用此位找到一个层时,将在层HitTest函数中检查X和Y坐标。如果X和Y坐标在图层位置内,HitTest成功。内置HitTest的结果可以在您自己的OnHitTest事件中重写。最后,如果层选项不包含LOB_NO_CAPTURE位,则调用层MouseDown事件。

基于之前的建议,当用户进入“编辑”模式时,通过将其LayerOptions设置为不包括LOB_MOUSE_EVENTS位,可以禁用除绘图层之外的所有其他层。

代码语言:javascript
运行
复制
Layer.LayerOptions := Layer.LayerOptions and (not LOB_MOUSE_EVENTS);

有关使用层的更多信息,请参阅这里

编辑

要管理LOB_MOUSE_EVENTS创建,例如,如下所示

代码语言:javascript
运行
复制
procedure TForm7.LayerMouseDisEnable(Enable: boolean);
var
  i: integer;
  Lo: cardinal;
begin
  for i := 0 to ImgView.Layers.Count-1 do
  begin
    Lo := ImgView.Layers.Items[i].LayerOptions;
    if Enable then
      ImgView.Layers.Items[i].LayerOptions := Lo or LOB_MOUSE_EVENTS
    else
      ImgView.Layers.Items[i].LayerOptions := Lo and (not LOB_MOUSE_EVENTS);
  end;
end;

在创建绘图层之前调用它(使用False)来禁用图层中的鼠标事件。绘图层将启用鼠标事件,因为新创建的层同时设置了LOB_VISIBLE和LOB_MOUSE_EVENTS。停止绘图以启用鼠标事件时再次调用(使用True)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28623999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档