在 Delphi 中使用创建多边形

xzlaal3s  于 2023-02-22  发布在  其他
关注(0)|答案(1)|浏览(238)

我想在Canvas上使用区域来检测鼠标在其上的移动,但是我无法使CreatePolygonRgn()正常工作。
下面是一个示例代码:

var
  regs : array of HRGN;

procedure TForm8.Button1Click(Sender: TObject);
var
  n : integer;
  p : array[0..3] of integer;
begin
  SetLength(regs, 10);
  for n := 1 to Length(regs) do try
    p[0] := n*50-20;
    p[1] := n*50+20;
    p[2] := n*50+20;
    p[3] := n*50-20;
    regs[n-1] := CreatePolygonRgn(p[0], 2 {neither with 4}, 1); // seems not working as expected
    // regs[n-1] := CreateRectRgn(p[0], p[1], p[2], p[3]); // this works

    FillRgn(image.Canvas.Handle, regs[n-1], image.Canvas.Brush.Handle); // doesn't draw anything             
  except
    ShowMessage('error creating region');
  end;
  Application.ProcessMessages;
end;

procedure TForm8.ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
  if (ssCtrl in Shift) then begin
    for var i : integer := 0 to Length(regs)-1 do
      if PtInRegion(regs[i], X, Y) then begin // works only with CreateRectRgn 
        ShowMessage('region ' + IntToStr(i));
        break;
      end;
  end;
end;

我做错了什么?

cwxwcias

cwxwcias1#

CreatePolygonRgn()将X/Y坐标数组作为POINT结构( Delphi 中为TPoint):
[in] pptl
一个指向POINT结构数组的指针,该数组以逻辑单位定义多边形的顶点。多边形假定为闭合的。每个顶点只能指定一次。
[in] cPoint
数组中的数量。
但是,您将为函数提供一个Integer数组。
因此,当您将cPoint参数设置为2时,您将告诉函数您的数组具有2个X/Y坐标(它确实是这样,(p[0],p[1])(p[2],p[3])),当你把cPoint参数设置为4时,你就告诉这个函数你的数组有4个X/Y坐标(这超出了数组的范围)。这两种情况都没有定义有效的多边形。
编译器没有捕捉到这种差异,因为Winapi.Windows单元将pptl参数简单地声明为const Points,这意味着它是一个无类型参数,基本上允许您传入任何您想要传入的内容,因此由您来确保您传入的任何内容实际上对函数有效(在这种情况下,它不是)。
CreateRectRgn()可以工作,因为它只需要左上角和右下角的2个X/Y坐标(作为4个整数传入),这正是您要给它的。如果您想用CreatePolygonRgn()复制相同的形状,您还必须为其他2个角提供X/Y坐标。

相关问题