Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 在TBitmap周围绘制点的边界线?_Delphi_Draw_Delphi 10.1 Berlin_Tcanvas - Fatal编程技术网

Delphi 在TBitmap周围绘制点的边界线?

Delphi 在TBitmap周围绘制点的边界线?,delphi,draw,delphi-10.1-berlin,tcanvas,Delphi,Draw,Delphi 10.1 Berlin,Tcanvas,我已经编写了一个例程,它应该在位图中添加点边框: 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 -

我已经编写了一个例程,它应该在位图中添加点边框:

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;
但放大结果时,生成的边界线(而不是点)似乎由小破折号组成:


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

DrawFocusRect这是一个Windows API调用,可以生成您需要的边框

procedure AddDottedBorderToBitmap(aBM: Vcl.Graphics.TBitmap);
begin
  DrawFocusRect(aBM.canvas.Handle,Rect(0,0,aBM.Width,aBM.Height));
end;

使用
DrawFocusRect
似乎很简单,但如果您需要绘制矩形以外的内容,可能需要提前阅读

画笔样式并不意味着每秒钟的像素都是彩色的,而另一个像素是清除的。如果你仔细想想,分辨率越高,就越难看出虚线和灰色实线f.ex的区别。还有另一种钢笔样式
psAlternate
,它交替像素。文件说:

诗篇

这支笔每隔一个像素设置一次。(此样式仅适用于 此样式仅对使用创建的笔有效 ExtCreatePenAPI函数。(请参阅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;
最后是它的外观(放大镜在x10处)


谢谢,这很有效!但出于好奇:为什么我的代码的结果中会出现小破折号而不是真正的点(就像你的例子中那样?@user1580348我不会把这称为提示,我会让它成为公认的答案:-)@Jerry谢谢你的支持。@Kobik谢谢你的编辑,我还添加了try-finally@TomBrunberg,如果您选择在此处使用try/finally,您还需要保护
oldpenh:=SelectObject(c.Handle,newpenh)
/
SelectObject(c.Handle,oldpenh)使用try/finally块使其一致;)@kobik是的,确实如此,但是你听起来(…如果你选择使用…)因为你不会为这些麻烦,最后试试?