判断控件是否在所选方框之内虚线框unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls;type TLineType = (ltHorz, ltVert); TForm1 = class(TForm) procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } FDC: HDC; FStartPos: TPoint; FBoundRect: TRect; FBounding: Boolean; procedure InvertLongRect(ARect: TRect); public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}procedure DotLine(ACanvas: TCanvas; X, Y, W, P, S, PW: integer; LineType: TLineType; LineColor: TColor);var I: integer;begin ACanvas.Pen.Color := LineColor; ACanvas.Pen.Width := PW; case LineType of ltHorz: begin I := 0; while I < W do begin if I + S > W then ACanvas.Polyline([Point(X + I, Y), Point(X + W, Y)]) else ACanvas.Polyline([Point(X + I, Y), Point(X + I + S, Y)]); Inc(I, S + P); end; end; ltVert: begin I := 0; while I < W do begin if I + S > W then ACanvas.Polyline([Point(X, Y + I), Point(X, Y + W)]) else ACanvas.Polyline([Point(X, Y + I), Point(X, Y + I + S)]); Inc(I, S + P); end; end; end;end;procedure DotRect(ACanvas: TCanvas; ARect: TRect; P, S, PW: integer; LineColor: TColor);begin DotLine(ACanvas, ARect.Left, ARect.Top, ARect.Bottom - ARect.Top - 1, P, S, PW, ltVert, LineColor); DotLine(ACanvas, ARect.Right - 1, ARect.Top, ARect.Bottom - ARect.Top, P, S, PW, ltVert, LineColor); DotLine(ACanvas, ARect.Left, ARect.Top, ARect.Right - ARect.Left - 1, P, S, PW, ltHorz, LineColor); DotLine(ACanvas, ARect.Left, ARect.Bottom - 1, ARect.Right - ARect.Left, P, S, PW, ltHorz, LineColor);end;procedure DotRightBottom(ACanvas: TCanvas; ARect: TRect; P, S, PW: integer; LineColor: TColor);begin DotLine(ACanvas, ARect.Right, ARect.Top, ARect.Bottom - ARect.Top, P, S, PW, ltVert, LineColor); DotLine(ACanvas, ARect.Left, ARect.Bottom, ARect.Right - ARect.Left, P, S, PW, ltHorz, LineColor);end;procedure InvertDotLine(FDC: HDC; X, Y, W, P, S, PW: integer; LineType: TLineType);var I: integer;begin case LineType of ltHorz: begin I := 0; while I < W do begin if I + S > W then PatBlt(FDC, X + I, Y, W - I, PW, PATINVERT) else PatBlt(FDC, X + I, Y, S, PW, PATINVERT); Inc(I, S + P); end; end; ltVert: begin I := 0; while I < W do begin if I + S > W then PatBlt(FDC, X, Y + I, PW, W - I, PATINVERT) else PatBlt(FDC, X, Y + I, PW, S, PATINVERT); Inc(I, S + P); end; end; end;end;procedure InvertDotRect(FDC: HDC; ARect: TRect; P, S, PW: integer);begin InvertDotLine(FDC, ARect.Left, ARect.Top, ARect.Bottom - ARect.Top - 1, P, S, PW, ltVert); InvertDotLine(FDC, ARect.Right - 1, ARect.Top, ARect.Bottom - ARect.Top, P, S, PW, ltVert); InvertDotLine(FDC, ARect.Left, ARect.Top, ARect.Right - ARect.Left - 1, P, S, PW, ltHorz); InvertDotLine(FDC, ARect.Left, ARect.Bottom - 1, ARect.Right - ARect.Left, P, S, PW, ltHorz);end;procedure InvertSolidRect(FDC: HDC; ARect: TRect; PW: integer);begin with ARect do begin PatBlt(FDC, Left, Top, Right - Left, PW, PATINVERT); PatBlt(FDC, Left, Top, PW, Bottom - Top, PATINVERT); PatBlt(FDC, Left, Bottom - PW, Right - Left, PW, PATINVERT); PatBlt(FDC, Right - PW, Top, PW, Bottom - Top, PATINVERT); end;end;function CtrlInRect(R: TRect; Ctrl: TWinControl): Boolean;var i: Integer;begin with Ctrl.BoundsRect do begin result := false; for i := Left to Right do begin if PtInRect(R, Point(i, Top)) then begin result := true; exit; end; if PtInRect(R, Point(i, Bottom)) then begin result := true; exit; end; end; for i := Top to Bottom do begin if PtInRect(r, Point(left, i)) then begin result := true; exit; end; if PtInRect(r, Point(Right, i)) then begin result := true; exit; end; end; end;end;procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);var ClipRect: TRect;begin FStartPos.X := X; FStartPos.Y := Y; ClipRect.TopLeft := ClientToScreen(ClientRect.TopLeft); ClipRect.BottomRight := ClientToScreen(ClientRect.BottomRight); ClipCursor(@ClipRect); with FBoundRect do begin Left := X; Top := Y; Right := X; Bottom := Y; end; FBounding := true; InVertLongRect(FBoundRect);end;procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin if FBounding then begin InVertLongRect(FBoundRect); with FBoundRect do begin if FStartPos.X < X then Right := X else begin Right := FStartPos.X; Left := X; end; if FStartPos.Y < Y then Bottom := Y else begin Bottom := FStartPos.Y; Top := Y; end; end; InVertLongRect(FBoundRect); end;end;procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin if FBounding then begin InVertLongRect(FBoundRect); FBounding := False; ClipCursor(nil); end;end;procedure TForm1.InvertLongRect(ARect: TRect);beginFDC := GetDCEx(Handle, 0, DCX_CACHE or DCX_CLIPSIBLINGS or DCX_LOCKWINDOWUPDATE); InvertDotRect(FDC, ARect, 2, 4, 1); ReleaseDC(Handle, FDC);end;end.