그래픽이나 멀티미디어 응용 프로그램을 개발하는 경우 제목 표시줄을 사용하지 않고 양식을 이동하는 방법이 궁금할 수 있습니다. 실제로 폼의 클라이언트 영역을 마우스로 드래그하기만 하면 됩니다.
방법 1
다음은 위 기능을 수행하는 가장 일반적인 방법입니다. 양식의 PRivate 문 섹션에 다음 절차 문을 추가합니다.
절차 WMNCHitTest(var Msg:TWMNCHitTest);메시지 WM_NCHITTEST;
그런 다음 구현 섹션에 다음 코드를 추가합니다.
절차 TForm1{또는 정의한 양식 이름}.WMNCHitTest(var Msg:TWMNCHitTest);
시작하다
DefaultHandler(Msg);
Msg.Result = HTCLIENT인 경우
Msg.Result:= HTCAPTION;
끝;
이 방법을 사용하면 Windows는 양식의 클라이언트 영역을 마우스로 클릭할 때 제목 표시줄을 클릭했다고 생각하게 됩니다.
방법 2
마우스를 사용하여 일반 양식을 이동하는 또 다른 방법은 다음과 같습니다.
절차 TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
시작하다
if (ssLeft in Shift) 다음 시작
릴리스캡처;
SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MOVE+1,0);
끝;
끝;
위 방법의 불완전성
"드래그하는 동안 창 내용 표시" 옵션이 꺼지면 어떤 일이 발생하는지 살펴보겠습니다. 이는 Windows 창에 대한 설정입니다. "시작 메뉴 --> 설정 --> 폴더 옵션 --> 보기 --> 고급 설정"에서 이 속성을 찾을 수 있습니다. Windows95에서는 레지스트리를 수정해야 합니다. 이 속성을 잘못된 것으로 설정하면 양식을 끌 때 사각형 윤곽선으로 변경됩니다. 불규칙한 형태를 사용하더라도 여전히 윤곽선이 표시될 수 있습니다.
양식을 화면 가장자리에 도킹하려는 경우(예: WinAmp에서 양식을 화면 상단의 특정 위치로 드래그하면 양식이 화면 상단에 가까워집니다) 위의 두 번째 단계를 사용합니다. 이렇게 하면 마우스 버튼을 놓을 때까지 양식 위치를 처리할 수 없으며 도킹 문제도 처리할 수 없습니다.
아래에서는 간단한 방법을 사용하여 두 가지 문제를 해결하겠습니다.
첫째, 설정에 관계없이 양식을 드래그할 때 윤곽선이 표시되지 않습니다.
둘째, 폼이 이동하면 위치검출을 하고, 위치가 적당할 때 특정 위치에 도킹한다.
많은 사람들이 이러한 문제를 해결했을 수도 있지만 아래 코드가 도움이 될 수도 있습니다.
방법 3
Form1을 uMain.pas로, Form2를 uDock.pas로 저장한다면 다음 코드를 Delphi에 직접 복사할 수 있습니다. 사용되는 이벤트는 OnMouseDown, OnMouseMove, OnMouseUp, OnShow(Form1)입니다.
uMain, uDock 2가지 폼(Form1, Form2)을 포함하여 마우스 움직임을 기반으로 폼을 이동시키는 방법입니다. Form2는 Form1을 통해 열리며 Form1의 아래쪽에 도킹될 수 있습니다. 도킹되면 Form2를 방해가 되지 않는 위치로 이동할 때까지 Form2는 Form1과 함께 이동합니다.
양식1
유닛 uMain;
인터페이스
용도
Windows, 메시지, SysUtils, 클래스, 그래픽, 컨트롤, 양식, 대화 상자;
유형
TForm1 = 클래스(TForm)
절차 FormMouseDown(Sender:TObject; Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
절차 FormMouseMove(Sender: TObject; Shift: TShiftState;X,Y: Integer);
절차 FormMouseUp(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
절차 FormShow(보내는 사람: TObject);
사적인
{비공개 선언}
공공의
DocktoForm: 부울;
{공개 선언}
끝;
var
Form1: TForm1;
CanMove, CanMoveX, CanMoveY: 부울;
OldX, OldY: 정수;
F1X,F1Y,F2X,F2Y: 정수;
작업 영역: TRect;
구현
uDock을 사용합니다.
{$R *.DFM}
절차 TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
시작하다
CanMoveX := 참;
CanMoveY := 참;
CanMove := 참;
OldX := X;
OldY := Y;
ifDocktoForm 다음
시작하다
F1X := Form1.왼쪽;
F1Y := Form1.Top;
F2X := Form2.왼쪽;
F2Y := Form2.Top;
끝;
끝;
절차 TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
시작하다
if (CanMove) 다음
시작하다
CanMoveX라면
Form1.Left := Form1.Left + (X - OldX);
CanMoveY이면
Form1.Top := Form1.Top + (Y - OldY);
//이 섹션은 상단에 래치됩니다.
if (Form1.Top < WorkArea.Top + 10) 및 (Form1.Top > WorkArea.Top-10) 그러면
시작하다
Form1.Top := 작업 영역.Top;
if (Y-OldY > 10) 또는 (Y-OldY < -10) then
CanMoveY := 참
또 다른
CanMoveY := 거짓;
끝;
//이 섹션은 왼쪽에 래치됩니다.
if (Form1.Left < WorkArea.Left+10) 및 (Form1.Left > WoskArea.Left-10) then
시작하다
Form1.Left := WorkArea.Left;
if (X-OldX > 10) 또는 (X-OldX < -10) then
CanMoveX := 참
또 다른
CanMoveX := 거짓;
끝;
//이 섹션은 오른쪽에 래치됩니다.
if (Form1.Left > WorkArea.Right-Form1.Width-10) 및 (Form1.Left < WorkArea.Right-Form1.Width+10) then
시작하다
Form1.Left := WorkArea.Right-Form1.Width;
if (X-OldX > 10) 또는 (X-OldX < -10) then
CanMoveX := 참
또 다른
CanMoveX := 거짓;
끝;
//이 섹션은 TaskBar에 래치됩니다.
ifDocktoForm 다음
시작하다
if (Form1.Top > WorkArea.Bottom-Form1.Height-Form2.Height-10) 및 (Form1.Top < WorkArea.Bottom-Form1.Height-Form2.Height+10) then
시작하다
Form1.Top := WorkArea.Bottom-Form1.Height-Form2.Height;
if (Y-OldY > 10) 또는 (Y-OldY < -10) then
CanMoveY := 참
또 다른
CanMoveY := 거짓;
끝;
끝
그렇지 않으면 시작하다
if (Form1.Top > WorkArea.Bottom-Form1.Height-10) 및 (Form1.Top < WorkArea.Bottom-Form1.Height+10) then
시작하다
Form1.Top := WorkArea.Bottom-Form1.Height;
if (Y-OldY > 10) 또는 (Y-OldY < -10) then
CanMoveY := 참
또 다른
CanMoveY := 거짓;
끝;
끝;
ifDocktoForm 다음
시작하다
Form2.Left := Form1.Left - (F1X-F2X);// + (X-OldX);
Form2.Top := Form1.Top+Form1.Height;
출구;
끝;
//이 섹션은 Form1 중앙에 재생 목록을 래치합니다.
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) 및 (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Width div 2))+10) 및
(Form2.Top > Form1.Top+Form1.Height-10) 및 (Form2.Top < Form1.Top+Form1.Height+10)
시작하다
Form2.Left := Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2));
DocktoForm := 참;
F1X := Form1.왼쪽;
F1Y := Form1.Top;
F2X := Form2.왼쪽;
F2Y := Form2.Top;
끝;
끝;
끝;
절차 TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
시작하다
CanMove := 거짓;
끝;
절차 TForm1.FormShow(Sender: TObject);
시작하다
//작업 영역 매개변수 가져오기
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
Form2.Show;
끝;
끝.
Form2
유닛 uDock;
인터페이스
용도
Windows, 메시지, SysUtils, 클래스, 그래픽, 컨트롤, 양식, 대화 상자;
유형
TForm2 = 클래스(TForm)
Procedure FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
절차 FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
Procedure FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
사적인
{비공개 선언}
공공의
{공개 선언}
끝;
var
Form2: TForm2;
CanMove, CanMoveX, CanMoveY, DocktoForm: 부울;
OldX, OldY: 정수;
구현
uMain을 사용합니다.
{$R *.DFM}
절차 TForm2.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
시작하다
CanMoveX := 참;
CanMoveY := 참;
CanMove := 참;
OldX := X;
OldY := Y;
끝;
절차 TForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
시작하다
if (CanMove) 다음
시작하다
CanMoveX라면
Form2.Left := Form2.Left + (X - OldX);
CanMoveY이면
Form2.Top := Form2.Top + (Y - OldY);
//이 섹션은 상단에 래치됩니다.
if (Form2.Top < WorkArea.Top + 10) 및 (Form2.Top > WorkArea.Top-10) 그러면
시작하다
Form2.Top := 작업 영역.Top;
if (Y-OldY > 10) 또는 (Y-OldY < -10) then
CanMoveY := 참
또 다른
CanMoveY := 거짓;
끝;
//이 섹션은 왼쪽에 래치됩니다.
if (Form2.Left < WorkArea.Left+10) 및 (Form2.Left > WorkArea.Left-10) then
시작하다
Form2.Left := WorkArea.Left;
if (X-OldX > 10) 또는 (X-OldX < -10) then
CanMoveX := 참
또 다른
CanMoveX := 거짓;
끝;
//이 섹션은 오른쪽에 래치됩니다.
if (Form2.Left > WorkArea.Right-Form2.Width-10) 및 (Form2.Left < WorkArea.Right-Form2.Width+10) then
시작하다
Form2.Left := WorkArea.Right-Form2.Width;
if (X-OldX > 10) 또는 (X-OldX < -10) then
CanMoveX := 참
또 다른
CanMoveX := 거짓;
끝;
//이 섹션은 TaskBar에 래치됩니다.
if (Form2.Top > WorkArea.Bottom-Form2.Height-10) 및 (Form2.Top < WorkArea.Bottom-Form2.Height+10) then
시작하다
Form2.Top := WorkArea.Bottom-Form2.Height;
if (Y-OldY > 10) 또는 (Y-OldY < -10) then
CanMoveY := 참
또 다른
CanMoveY := 거짓;
출구;
끝;
//이 섹션은 플레이어 하단에 고정됩니다.
if (Form2.Top > Form1.Top+Form1.Height-10) 및 (Form2.Top < Form1.Top+Form1.Height+10) 및 (Form2.Left > Form1.Left-Form2.Width) 및 (Form2. 왼쪽 < Form1.Left + Form1.Width) 그런 다음
시작하다
Form2.Top := Form1.Top+Form1.Height;
(Y-OldY > 10) 또는 (Y-OldY < -10)이면 시작됩니다.
CanMoveY := 참;
Form1.DockToForm := 거짓;
끝
그렇지 않으면 시작하다
CanMoveY := 거짓;
Form1.DockToForm := 참;
끝;
끝;
//이 섹션은 Form1 중앙에 재생 목록을 래치합니다.
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) 및 (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Width div 2))+10) 및
(Form2.Top > Form1.Top+Form1.Height-10) 및 (Form2.Top < Form1.Top+Form1.Height+10)
시작하다
Form2.Left := Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2));
if (X-OldX > 10) 또는 (X-OldX < -10) 또는 (Y-OldY > 10) 또는 (Y-OldY < -10) then
CanMoveX := 참
또 다른
CanMoveX := 거짓;
끝;
끝;
끝;
절차 TForm2.FormMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
시작하다
CanMove := 거짓;
끝;
끝.
비슷한 내용으로 고민하시는 분들에게 위의 내용이 도움이 되었으면 좋겠습니다.