gpt4 book ai didi

delphi - 如何保留确定的表格区域不被剪切?

转载 作者:行者123 更新时间:2023-12-03 19:36:23 25 4
gpt4 key购买 nike

使用下面的代码,可以使用鼠标绘制矩形。每个矩形都存储在TQueue(列表)中,该列表不能超过2个元素(可以自定义此值)。我绘制这两个区域的目标是,第一个区域可以切割,第二个区域不能切割,最终结果如下所示:

enter image description here

我该如何实现?切割步骤必须在绘制两个区域之后进行。到目前为止,我所做的只是逆过程(我认为)。遵循代码:

uses
Generics.Collections;

type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FSelecting: Boolean;
FSelection: TRect;
Region, Region2: hrgn;
pos1, pos2, pos3, pos4: Integer;
FRectangles: TQueue<TRect>;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

const
MAXRECTANGLECOUNT = 2;

procedure TForm1.FormCreate(Sender: TObject);
begin
FRectangles := TQueue<TRect>.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
FRectangles.Free;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FSelection.Left := X;
FSelection.Top := Y;
FSelecting := true;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FSelecting then
begin
FSelection.Right := X;
FSelection.Bottom := Y;
Invalidate;
end;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
I: Integer;
begin
FSelecting := false;
FSelection.Right := X;
FSelection.Bottom := Y;
Invalidate;

FSelection.NormalizeRect;

if not FSelection.IsEmpty then
begin

pos1 := FSelection.Left;
pos2 := FSelection.Top;
pos3 := X;
pos4 := Y;

FRectangles.Enqueue(FSelection);
if FRectangles.Count > MAXRECTANGLECOUNT then
FRectangles.Dequeue;

for I := 0 to FRectangles.Count - 1 do
begin
if I = 1 then
begin
Region := CreaterectRgn(0, 0, Width, Height);
Region2 := CreaterectRgn(pos1, pos2, pos3, pos4);
CombineRgn(Region, Region, Region2, RGN_DIFF);
SetWindowRgn(Handle, Region, True);
end;
end;
end;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
R: TRect;
begin
Canvas.Brush.Style := bsClear;
Canvas.Pen.Style := psSolid;
Canvas.Pen.Color := clRed;
Canvas.Rectangle(FSelection);

for R in FRectangles do
Canvas.Rectangle(R);
end;

最佳答案

您所需要做的就是以一种可以产生所需结果的方式将第三个区域合并到合并的区域。可能的模式在函数的documentation中进行了说明。

下面的示例是OnMouseUp事件处理程序的相应修改版本。假定先绘制较大的矩形。修改包括考虑绘制矩形的标题和边框(因为鼠标向上处理程序可提供客户端坐标,但SetWindowRegion需要具有窗口坐标的区域),并在不再需要时删除区域。

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
Pt: TPoint;
I: Integer;
begin
FSelecting := false;
FSelection.Right := X;
FSelection.Bottom := Y;
Invalidate;

FSelection.NormalizeRect;
if not FSelection.IsEmpty then
begin
FRectangles.Enqueue(FSelection);
if FRectangles.Count = MAXRECTANGLECOUNT then
begin
Region := CreateRectRgn(0, 0, Width, Height);

Region2 := CreateRectRgnIndirect(FRectangles.Dequeue);
// offset region to account for caption and borders
Pt := ClientOrigin;
OffsetRgn(Region2, Pt.X - Left, Pt.Y - Top);

CombineRgn(Region, Region, Region2, RGN_DIFF);
DeleteObject(Region2);


Region2 := CreateRectRgnIndirect(FRectangles.Dequeue);
// offset region to account for caption and borders
OffsetRgn(Region2, Pt.X - Left, Pt.Y - Top);

CombineRgn(Region, Region, Region2, RGN_OR);
DeleteObject(Region2);

SetWindowRgn(Handle, Region, True);
DeleteObject(Region);
end;
end;
end;


..并删除未使用的整数变量(pos1 .. pos4)。

设置窗口区域后,将两个使用的矩形从矩形列表中出队。由于有两个,所以现在为空。

关于delphi - 如何保留确定的表格区域不被剪切?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58332074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com