0

描画レイヤーとは、ユーザーが線、円、またはその他の形状を手動で描画できるレイヤーを意味します。また、通常のレイヤーとは、graphics32 レイヤーの例で説明されているレイヤー (実行時にマウス イベントを使用して移動またはサイズ変更できるレイヤー) を意味するため、これら 2 種類のレイヤーを組み合わせることが困難です。私のテスト プロジェクトでは、今のところ、1 つの描画レイヤーと複数の PNG レイヤーしかないと仮定します。したがって、私のプロジェクトでは、OnFormCreate で ImgView32 のプロパティを次のように設定します。

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 画像を含む) を追加します。だからこんな感じ

procedure TForm1.Button1Click(Sender: TObject);
begin
  AddPNGLayer(1);
  AddPNGLayer(2);
  AddDrawingLayer;
  AddPNGLayer(3);
end;

(質問を短くするために、ここでは PNG レイヤーの追加について詳しく説明しません。drawingLayer で使用されているものとは異なる onMouseDown イベント (layerMouseDown) を使用しているとだけ言います) AddDrawingLayer は次のとおりです。

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:=nildrawingLayer は移動およびサイズ変更のみ可能であり、この特定のレイヤーでマウス イベントを使用して描画したいので、これは良い解決策ではありません。
  • RBLayer:=nilwhile keepだけコメントするとSelection:=BB、drawingLayer はもう移動できませんが、drawingLayer のにある他のレイヤーを選択することはできません。一番上のレイヤー (最後に追加された PNG レイヤー) にしかアクセスできません

  • コメントするSelection:=BBと、マウスで他のレイヤーを選択できなくなります。したがって、私の場合、drawingLayer の前に 2 つの png レイヤーを宣言し、その後に 1 つ宣言しました。実行時に最後のレイヤー (drawingLayer の「上」) しか選択できないため、これも解決策ではありません。

描画レイヤーをクリックすると(またはリストボックスなどで選択すると)、drawingLayerは移動できませんが、描画マウスイベントが開始されますか?そして、必要なときにいつでも drawingLayer から離れて、他のレイヤーを選択して移動したり遊んだりすることができます。したがって、基本的に、他のレイヤーのように機能しない特定のレイヤーが必要です。

私が達成したいのは、graphics32 を使用して、古典的な Photoshop のような、または paint.net のような動作をすることです。そして、これらのレイヤー プロパティが実際にどのように機能するかは非常にわかりにくいものです。

これまでのところ、(マウスイベントを使用して)透明レイヤーに(線、円、長方形)を動的に描画する方法を理解しました。だから私は描画レイヤーを持つことができます。描画は、、、、イベントで行わDrLayerMouseDownれます。しかし、そのような描画レイヤーを通常の可動/サイズ変更可能なレイヤーと組み合わせる方法を理解できないようです。DrLayerMouseUpDrLayerMouseMoveDrLayerPaint

コードの残りの部分 ( 、setSelectionRBResizingなどlayerMouseDown) は、ほとんどが graphics32 ライブラリのレイヤーの例から取られています。

編集

でアイデアをテストするためにlayerOptions、次のことを行いました。

1. ImgView とボタンを含む新しいテスト プロジェクトを開始します。

2.作成時に、以前と同じコードを使用しました

3.OnButtonClick 次のように、修正された AddDrawingLayer を使用して 1 つのレイヤーを追加しました。

...
    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 では、このオプションは固執していないようです。しかし、次の編集のように、すべてのレイヤーのマウス イベントを 1 つずつ無効にすると、描画レイヤーが無効になります (マウス イベント)。

編集

また、同じアイデアの別のテスト プロジェクトを試してみました: 同じ onCreate と onButtonClick それぞれに画像を含む 3 つのレイヤー (ライブラリのレイヤーの例を使用) を追加します (今回は単純にするために描画レイヤーはありません)。次に、クリックすると次のコードが実行される新しいボタンを追加しました。

  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で3番目のボタンを追加):

  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で提案したことを行うには、すべてのレイヤーのマウスイベントを無効にし、特定のレイヤーのマウスイベントを有効にする必要があり、編集が完了したら、マウスイベントを再度有効にする必要がありますすべてのレイヤーに対してですが、間違っていると思います。

4

1 に答える 1

0

以下の項目はマウスイベントに影響します

  • Layers.MouseEvents (ブール値)。Layers は、レイヤを管理する TCustomImage32 の TLayerCollection です。MouseEvents が False の場合、マウス イベントはレイヤーに伝達されません。

  • Layers.MouseListener (TCustomLayer)。左ボタン MouseDown と MouseUp の間のマウス イベントを「キャプチャ」するレイヤー。Windows コンテキストで理解されているようにマウスをキャプチャしていないため、引用符で「キャプチャ」します。

  • レイヤ オプション ビット。各レイヤーには、32 ビットの LayerOptions プロパティがあります。興味深いビットは、レイヤがマウス イベントに反応するかどうかを指定する LOB_MOUSE_EVENTS (ビット 29) です。レイヤーは、LOB_MOUSE_EVENTS が設定されている場合でも、マウス イベントを防止する LOB_NO_CAPTURE ビット (ビット 27) を指定することもできます。

  • レイヤー インデックス。レイヤーは、LOB_MOUSE_EVENTS オプション ビットについて (最上位から最下位の順に) チェックされます。このビットを持つレイヤーが見つかると、レイヤーの HitTest 関数で X 座標と Y 座標がチェックされます。X 座標と Y 座標がレイヤーの位置内にある場合、HitTest は成功します。組み込みの HitTest の結果は、独自の OnHitTest イベントでオーバーライドできます。最後に、レイヤ オプションに LOB_NO_CAPTURE ビットが含まれていない場合、レイヤの MouseDown イベントが呼び出されます。

前に基づいて、ユーザーが「編集」モードに入ると、描画レイヤーを除く他のすべてのレイヤーを無効にすることをお勧めします

Layer.LayerOptions := Layer.LayerOptions and (not LOB_MOUSE_EVENTS);

レイヤーの使用に関する詳細情報は、こちらから入手できます

編集

LOB_MOUSE_EVENTS を管理するには、たとえば次のように作成します。

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 を指定して) 再度呼び出します。

于 2015-02-22T13:15:46.397 に答える