【问题标题】:(Hole) align hole inside the panel form 1 [closed](孔)对齐面板形式 1 内的孔 [关闭]
【发布时间】:2021-02-15 18:43:10
【问题描述】:

嗯,我有一个开始最大化的表格,带有黑色图像 我需要在表格上打个洞,打开表格 1,打开一个新表格, 面板内孔 与form 2孔对齐

它在屏幕左侧的最顶部工作,但在面板内未对齐:https://prnt.sc/znemgc

在屏幕右侧,不要移动表格,不要在面板内开孔,不,将孔对准表格2:https://prnt.sc/znexpa

type
  TForm2 = class(TForm)
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
    var
    x1, y1, x2, y2: Integer;
    ptnd: Boolean;
    AnchorX, AnchorY, CurX, CurY: Integer;
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

const
  vH: Byte = 10;
  vV: Byte = 30;


procedure TForm2.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  x1 := x + vH;
  y1 := y + vV;
  ptnd := True;
  AnchorX := X;
  CurX := X;
  AnchorY := Y;
  CurY := Y;
end;

procedure TForm2.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  Caption := 'x1: ' + IntToStr(x1) + '; y1 ' + IntToStr(y1) + '; x2 ' + IntToStr(x2) + '; y2 ' + IntToStr(y2) + ';';
  if ptnd then
  begin
    Canvas.Pen.Mode := pmNot;
    Canvas.Pen.Width := 2;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
    CurX := X;
    CurY := Y;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
  end;
end;

procedure TForm2.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
   region1, region2, rg2, rg1: hrgn;
  RECT : TRECT;
  ScreenTopLeft, ScreenBottomRight: TPoint;
  NewX1, NewX2, NewY1, NewY2: Integer;
begin
  x2 := x + vH;
  y2 := y + vV;
  //if Shift = [ssCtrl] then
  begin
    region1 := CreateRectRgn(0, 0, Self.Width, Self.Height);
    region2 := CreateRectRgn(x1, y1, x2, y2);
    CombineRgn(region1, region1, region2, RGN_DIFF);
    SetWindowRgn(Handle, region1, True);


    getwindowrect(form1.Panel1.Handle,rect);


    //Form1.Left := Form2.Left - Form1.Left;
    //Form1.Top  := Form2.Top  - Form1.Top;

    //Transfer into screen coordinates
    //Note: ClientToScreen and ScreenToClient work with Points and not
    //separate coordinates
    ScreenTopLeft := Self.ClientToScreen(Point(X1,Y1));
    ScreenBottomRight := Self.ClientToScreen(Point(X2,Y2));

    //Transfer from screen back to form1 coordiantes
    NewX1 := Form1.ScreenToClient(ScreenTopLeft).X;
    NewY1 := Form1.ScreenToClient(ScreenTopLeft).Y;
    NewX2 := Form1.ScreenToClient(ScreenBottomRight).X;
    NewY2 := Form1.ScreenToClient(ScreenBottomRight).Y;

    form1.Show;
    region1 := CreateRectRgn(0, 0, self.Width, self.Height);
    //region2 := CreateRectRgn(x1, y1, x2, y2);
    region2 := CreateRectRgn(NewX1, NewY1, NewX2, NewY2);
    CombineRgn(region1, region1, region2, RGN_DIFF);
    SetWindowRgn(form1.Handle, region1, True);

  end;
  if ptnd then
  begin
    ptnd := False;
    Canvas.Pen.Mode := pmNot;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
  end;
end;

【问题讨论】:

  • 我不确定我是否理解您想要做什么。您是否想在两种形式中都打孔,以便它们的屏幕相对位置匹配,因此看起来好像您在两种形式中都打了一个孔?如果是这样,那么我不明白您为什么要更改 Form1 的位置。
  • 但是如果要设置Form1的位置,使其孔的位置与Form2中的孔的位置相匹配。那么工作就很简单了。由于您将孔定位在与 Form1 或 Form2 窗口相同的相对位置,因此您可以匹配 Form1 和 Form2 Left 和 Top 位置。
  • 是的,我想做的是 form2 中的孔和 form1 与面板示例中的 form2 的孔对齐 -> prnt.sc/zlp562
  • 您希望通过移动表格或调整这些孔的位置来实现这一点?
  • Form2最大化我打孔,打开form1在面板内打出相同大小的孔,form 1,与form 2中的孔对齐

标签: delphi pascal


【解决方案1】:

如果您希望在不同的 Windows 上创建两个孔以便它们的相对屏幕位置匹配,那么您首先必须将坐标从一个窗体上的孔更改为屏幕坐标,然后再返回到目标窗体上的窗体坐标。

为此,您可以使用ClinetToScreenScreentoClient 方法。

所以你的 OnMouseUp 事件过程看起来像这样:

procedure TForm2.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  region1, region2, rg2, rg1: hrgn;
  RECT : TRECT;
  ScreenTopLeft, ScreenBottomRight: TPoint;
  NewX1, NewX2, NewY1, NewY2: Integer;
begin
  x2 := x + vH;
  y2 := y + vV;
  //if Shift = [ssCtrl] then
  begin
    region1 := CreateRectRgn(0, 0, Self.Width, Self.Height);
    region2 := CreateRectRgn(x1, y1, x2, y2);
    CombineRgn(region1, region1, region2, RGN_DIFF);
    SetWindowRgn(Handle, region1, True);


    getwindowrect(form1.Panel1.Handle,rect);


    //Form1.Left := Form2.Left - Form1.Left;
    //Form1.Top  := Form2.Top  - Form1.Top;

    //Transfer into screen coordinates
    //Note: ClientToScreen and ScreenToClient work with Points and not 
    //separate coordinates
    ScreenTopLeft := Self.ClientToScreen(Point(X1,Y1));
    ScreenBottomRight := Self.ClientToScreen(Point(X2,Y2));

    //Transfer from screen back to form1 coordiantes
    NewX1 := Form1.ScreenToClient(ScreenTopLeft).X;
    NewY1 := Form1.ScreenToClient(ScreenTopLeft).Y;
    NewX2 := Form1.ScreenToClient(ScreenBottomRight).X;
    NewY2 := Form1.ScreenToClient(ScreenBottomRight).Y;

    form1.Show;
    region1 := CreateRectRgn(0, 0, form1.Width, form1.Height);
    //region2 := CreateRectRgn(x1, y1, x2, y2);
    region2 := CreateRectRgn(NewX1, NewY1, NewX2, NewY2);
    CombineRgn(region1, region1, region2, RGN_DIFF);
    SetWindowRgn(form1.Handle, region1, True);

  end;
  if ptnd then
  begin
    ptnd := False;
    Canvas.Pen.Mode := pmNot;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(AnchorX, AnchorY, CurX, CurY);
  end;
end;

我对您的代码进行了更改,并将更改后的原始代码保留为 cmets,以便您更容易发现差异。

【讨论】:

  • 我可以私下联系你吗?所以我们可以决定结合Skype、discord、电报、whatssap?
  • 堆栈溢出不允许我们在不将联系人发布到全世界的情况下交换联系人。所以恐怕我不会和你分享我的任何联系方式。
  • 如果我的解决方案不起作用,请告诉我有什么问题没有按预期工作,我们仍然可以一起找到解决方案。
  • 好的,这个解决方案只适用于最顶部的屏幕右侧-> prnt.sc/zncasi
  • 屏幕直接侧不移动窗体且剪切不在面板内->prnt.sc/znchzl
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 2014-01-19
  • 2013-09-01
  • 2014-09-30
  • 2010-09-26
相关资源
最近更新 更多