我有以下代码,并希望根据在服务器端绘制的区域在远程屏幕(客户端)上的两个表单中绘制相同的孔。
我在双方(服务器和客户端)都有相同的表单( Form3 ),它是一个“镜子”,我正在绘制一个必须保持在客户端相同表单内的区域。
服务器端的Form3有最大值的50% ,这是看到Form3
AlphaBlend
后面的远程屏幕所必需的。
首先,我想说我正在接收服务器端的远程屏幕,并且鼠标点击位置按预期工作。
那么这是我的麻烦:
以下代码产生上图所示的结果。我认为这段代码是正确的,但缺少将这个孔与Form3对齐。
有人可以帮忙吗?抱歉,如果这是一个不好的问题,但这是我所有的实际麻烦,我试图用我能做到的更好的方式表达这个问题。
这是所有相关代码:
服务器端:
Form2(我看到远程屏幕):
unit Unit2;
interface
uses
Unit1;
type
TForm2 = class(TForm)
Panel1: TPanel;
CheckBox1: TCheckBox;
ScrollBox1: TScrollBox;
Image1: TImage;
PaintBox1: TPaintBox;
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1Paint(Sender: TObject);
private
{ Private declarations }
FSelecting: Boolean;
FSelection: TRect;
pos1, pos2, pos3, pos4: Integer;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if CheckBox1.Checked then
begin
FSelection.Left := X;
FSelection.Top := Y;
FSelecting := true;
end;
end;
procedure TForm2.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if FSelecting then
begin
FSelection.Right := X;
FSelection.Bottom := Y;
pbRec.Invalidate;
end;
end;
procedure TForm2.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if CheckBox1.Checked then
begin
FSelecting := false;
FSelection.Right := X;
FSelection.Bottom := Y;
PaintBox1.Invalidate;
FSelection.NormalizeRect;
if FSelection.IsEmpty then
begin
// None selection was made on PaintBox
end
else
begin
pos1 := FSelection.Left;
pos2 := FSelection.Top;
pos3 := X;
pos4 := Y;
end;
end;
end;
procedure TForm2.PaintBox1Paint(Sender: TObject);
begin
if CheckBox1.Checked then
begin
PaintBox1.Canvas.Brush.Style := bsClear;
PaintBox1.Canvas.Pen.Style := psSolid;
PaintBox1.Canvas.Pen.Color := clRed;
PaintBox1.Canvas.Rectangle(FSelection);
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
Socket: TCustomWinSocket;
begin
Socket := TCustomWinSocket(Form1.LV1.Selected.SubItems.Objects[0]);
if CheckBox1.Checked then
begin
Socket.SendText(intToStr(pos1) + ';' + intToStr(pos2) + ';' +
intToStr(pos3) + ';' + intToStr(pos4));
end;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
Form3 := TForm3.Create(Self);
Form3.Show;
end;
表格2 .DFM :
object Panel1: TPanel
Left = -1
Top = 0
Width = 773
Height = 89
Anchors = [akTop]
BevelEdges = [beLeft, beRight]
ParentDoubleBuffered = False
TabOrder = 0
end
object ScrollBox1: TScrollBox
Left = 0
Top = 0
Width = 765
Height = 472
HorzScrollBar.Smooth = True
HorzScrollBar.Tracking = True
VertScrollBar.Smooth = True
VertScrollBar.Tracking = True
Align = alClient
TabOrder = 1
object Image1: TImage
Left = 0
Top = 0
Width = 1362
Height = 621
AutoSize = True
end
object PaintBox1: TPaintBox
Left = 0
Top = 0
Width = 1362
Height = 621
Align = alClient
OnMouseDown = PaintBox1MouseDown
OnMouseMove = PaintBox1MouseMove
OnMouseUp = PaintBox1MouseUp
OnPaint = PaintBox1Paint
ExplicitWidth = 1364
ExplicitHeight = 622
end
Form3(客户端也是一样的“镜像”Form),这个Form是按照远程屏幕分辨率集中的:
unit Unit3;
interface
uses
...
type
TForm3 = class(TForm)
Panel1: TPanel;
Image1: TImage;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure CreateParams(var pr: TCreateParams); override;
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses
Unit1;
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject);
var
MyString: String;
Splitted: TArray<String>;
begin
MyString := Form1.LV1.Selected.SubItems[6]; // Resolution of remote screen
Splitted := MyString.Split(['x']);
Self.Left := (Integer(Splitted[0]) - Self.Width) div 2;
Self.Top := (Integer(Splitted[1]) - Self.Height) div 2;
end;
procedure TForm3.CreateParams(var pr: TCreateParams);
begin
inherited;
pr.WndParent := Form2.Handle;
pr.ExStyle := pr.ExStyle or WS_EX_TOPMOST or WS_EX_TRANSPARENT;
pr.ExStyle := WS_EX_TRANSPARENT or WS_EX_TOPMOST;
end;
表格3 .DFM :
object Form3: TForm3
Left = 328
Top = 143
BorderStyle = bsNone
ClientHeight = 567
ClientWidth = 526
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 801
Height = 569
TabOrder = 0
object Image1: TImage
Left = 1
Top = 1
Width = 799
Height = 567
Align = alClient
ExplicitLeft = 2
ExplicitTop = 0
ExplicitHeight = 447
end
object Label1: TLabel
Left = 92
Top = 69
Width = 28
Height = 13
Caption = 'Nome'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlack
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
ParentColor = False
ParentFont = False
end
客户端:
Form2(“储物柜”表格):
unit Unit2;
private
{ Private declarations }
procedure CreateParams(var Params: TCreateParams); override;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WndParent := Application.Handle;
Params.ExStyle := Params.ExStyle or WS_EX_TOPMOST or WS_EX_TRANSPARENT;
Params.ExStyle := WS_EX_TRANSPARENT or WS_EX_TOPMOST;
end;
procedure TForm2.FormCreate(Sender: TObject);
begin
windowstate := wsmaximized;
Top := 0;
Left := 0;
Height := Screen.Height;
Width := Screen.Width;
end;
{
Properties of Form2:
Align => alNone
AlphaBlend => True
BorderStyle => BsNone
}
end.
Form3(与服务器端相同):
unit Unit3;
interface
uses
...
type
TForm3 = class(TForm)
Panel1: TPanel;
Label1: TLabel;
procedure FormShow(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure CreateParams(var pr: TCreateParams); override;
public
{ Public declarations }
end;
var
Form3: TForm3;
implementation
uses
Unit2;
{$R *.dfm}
procedure TForm3.FormCreate(Sender: TObject);
begin
Self.Left := (GetSystemMetrics(SM_CXSCREEN) - Self.Width) div 2;
Self.Top := (GetSystemMetrics(SM_CYSCREEN) - Self.Height) div 2;
end;
procedure TForm3.FormShow(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;
procedure TForm3.CreateParams(var pr: TCreateParams);
begin
inherited;
pr.WndParent := Form2.Handle;
end;
{
Properties of Form3:
Align => alNone
BorderStyle => BsNone
}
end.
在客户端接收区域:
procedure CS1_Read(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
var
X1, X2, Y1, Y2: Integer;
List: TStrings;
FormRegion, HoleRegion: HRGN;
StrCommand: string;
begin
if Pos(';', StrCommand) > 0 then
begin
List := TStringList.Create;
try
ExtractStrings([';'], [], PChar(StrCommand), List);
Form3 := TForm3.Create(Form2); // The Form2 already was created and is showing
X1 := Round(StrToIntDef(List[0], 0) - Form2.Left);
Y1 := Round(StrToIntDef(List[1], 0) - Form2.Top);
X2 := Round(StrToIntDef(List[2], 0) - Form2.Left);
Y2 := Round(StrToIntDef(List[3], 0) - Form2.Top);
FormRegion := CreateRectRgn(0, 0, Form3.Width, Form3.Height);
HoleRegion := CreateRectRgn(X1, Y1, X2, Y2);
CombineRgn(FormRegion, FormRegion, HoleRegion, RGN_DIFF);
SetWindowRgn(Form3.handle, FormRegion, true);
FormRegion := CreateRectRgn(0, 0, Form2.Width, Form2.Height);
HoleRegion := CreateRectRgn(X1, Y1, X2, Y2);
CombineRgn(FormRegion, FormRegion, HoleRegion, RGN_DIFF);
SetWindowRgn(Form2.handle, FormRegion, true);
Form3.ShowModal;
Form3.Release;
finally
List.Free;
end;
end;
end;