3

我写了一个例程,它应该为位图添加一个虚线边框:

procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
var
  c: TCanvas;
begin
  c := aBM.Canvas;
  c.Pen.Color := clBlack;
  c.Pen.Mode  := pmXor;
  c.Pen.Style := psDot;

  c.MoveTo(0, 0);
  c.LineTo(0, aBM.Height - 1);
  c.LineTo(aBM.Width - 1, aBM.Height - 1);
  c.LineTo(aBM.Width - 1, 0);
  c.LineTo(0, 0);
end;

但是当放大结果时,生成的边界线而不是点似乎是由小破折号组成的:

在此处输入图像描述

这个对吗?如果没有,我怎样才能得到真正的点而不是破折号?

4

2 回答 2

6

使用起来可能看起来很简单DrawFocusRect,但如果您需要绘制矩形以外的东西,您可能需要提前阅读。

钢笔样式psDot并不意味着每隔一个像素就被着色而另一个被清除。如果您考虑一下,分辨率越高,就越难看出虚线与灰色实线 f.ex 的差异。还有另一种psAlternate交替像素的笔样式。文档说:

ps备用

笔设置每隔一个像素。(此样式仅适用于化妆笔。)此样式仅对使用 ExtCreatePen API 函数创建的笔有效。(请参阅 MS Windows SDK 文档。)这适用于 VCL 和 VCL.NET。

要定义笔并使用它,我们执行以下操作

var
  c: TCanvas;
  oldpenh, newpenh: HPEN; // pen handles
  lbrush: TLogBrush;      // logical brush

...

  c := pbx.Canvas; // pbx is a TPintBox, but can be anything with a canvas

  lbrush.lbStyle := BS_SOLID;
  lbrush.lbColor := clBlack;
  lbrush.lbHatch := 0;

  // create the pen
  newpenh := ExtCreatePen(PS_COSMETIC or PS_ALTERNATE, 1, lbrush, 0, nil);
  try
    // select it
    oldpenh := SelectObject(c.Handle, newpenh);

    // use the pen
    c.MoveTo(0, 0);
    c.LineTo(0, pbx.Height - 1);
    c.LineTo(pbx.Width - 1, pbx.Height - 1);
    c.LineTo(pbx.Width - 1, 0);
    c.LineTo(0, 0);

    c.Ellipse(3, 3, pbx.width-3, pbx.Height-3);

    // revert to the old pen
    SelectObject(c.Handle, oldpenh);
 finally
    // delete the pen
    DeleteObject(newpenh);
 end;

最后是它的样子(放大镜是 x 10)

在此处输入图像描述

于 2017-06-20T19:47:24.463 回答
2

DrawFocusRect 它是一个 Windows API 调用,可以根据您的需要制作边框。

procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
begin
  DrawFocusRect(aBM.canvas.Handle,Rect(0,0,aBM.Width,aBM.Height));
end;
于 2017-06-20T17:37:42.227 回答