如何限制Panel按钮在窗口上移动位置,让它不要超过form1.left和form1.top(18分)

  • 主题发起人 主题发起人 laohe
  • 开始时间 开始时间
L

laohe

Unregistered / Unconfirmed
GUEST, unregistred user!
我将pandl设置处理成可移动的,但就是不能限制作移动的位置
如何限制Panel按钮在窗口上移动位置,让它不要超过form1.left和form1.top
 
procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
releasecapture;
panel1.Perform(wm_syscommand,$f012,0);
end;
 
我在拖动开始的时候挂上一个鼠标钩子。 拖动结束的时候释放钩子

根据鼠标钩子的位置来判断是否允许PANEL继续移动。
 
一个新的思路:
在MouseDown的时候根据鼠标坐标以及Panel相对于Form的位置,确定鼠标的可移动范围
——一定是矩形,然后呢...把鼠标的可能移动范围限制死,等MouseUp了再还原鼠标的移动范围。
具体实现可以参考:

// 限制
procedure TForm1.Button1Click(Sender: TObject);
var
rtButton2: TRect;
begin
rtButton2 := Button2.BoundsRect;
MapWindowPoints(handle, 0, rtButton2, 2); // 座标换算
ClipCursor(@rtButton2); // 限制鼠标移动区域
end;
// 还原
procedure TForm1.Button2Click(Sender: TObject);
var
rtScreen: TRect;
begin
rtScreen := Rect(0, 0, Screen.Width, Screen.Height);
ClipCursor(@rtScreen);
end;
 
试了不能用,
procedure TBF_Form.panel1MouseDown(Sender: TObject;Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
(Sender as TWinControl).Perform(WM_SysCommand,$F012,0);
end;

上面是我让panel移动的代源
 
createtion_zy, 我当初做了一个小控件。开始也是按你这么想。只是效果不好
鼠标被管死了很难受。后来才改用钩子。

Public
Constructor Create(AOwner : TComponent); Override;
destructor destroy;Override;
Procedure DragOver(Source : TObject; X, Y : Integer;
State : TDragState; Var Accept : Boolean); Override;
Procedure DragDrop(Source : TObject; X, Y : Integer); Override;
procedure StartDrag(Sender: TObject; var DragObject: TDragObject);
procedure EndDrag(Sender, Target: TObject; X, Y: Integer);

Function CallBackProc(Code:integer;wParam:wParam;Lparam:Lparam):Longint; {$IFDEF Win32} stdCall; {$ELSE}Export;{$ENDIF}

var
DragImage : THiStarImage;
Hwd : THandle;
Implementation
Function CallBackProc(Code:integer;wParam:wParam;Lparam:Lparam):Longint;
var
CursorPos : TPoint;
WndRect : TRect;
Begin
if DragImage = Nil then
begin
Result := 0;
Exit;
end;

If DragImage.Dragging then
Begin
// 向上滚动
Windows.GetCursorPos(CursorPos);
GetWindowRect(DragImage.Parent.Handle, Wndrect);

if (CursorPos.y <= WndRect.Top+20) then
if TScrollBox(DragImage.Owner).VertScrollBar.Position > 0 then
TScrollBox(DragImage.Owner).VertScrollBar.Position := TScrollBox(DragImage.Owner).VertScrollBar.Position - 20;
// 向下滚动
if (CursorPos.y >= WndRect.Bottom-20) then
if TScrollBox(DragImage.Owner).VertScrollBar.Position < TScrollBox(DragImage.Owner).VertScrollBar.Range then
TScrollBox(DragImage.Owner).VertScrollBar.Position := TScrollBox(DragImage.Owner).VertScrollBar.Position + 20;
End;

Result := CallNextHookEx(Hwd, Code, wParam, lParam);
End;
procedure THiStarImage.StartDrag(Sender: TObject; var DragObject: TDragObject);
Begin
DragImage := Self;
Hwd:=SetWindowsHookEx(WH_Mouse,CallBackProc,hInstance,0);
End;

procedure THiStarImage.EndDrag(Sender, Target: TObject; X, Y: Integer);
begin
unHookWindowsHookEx(hwd);
DragImage := Nil;
end;


这个是很久以前写的了(Delphi2.0, 3.0). 大致就是这个意思,应该没问题。
 
实在不行用timer控件来控制
当panel.left<0 then panel.left:=0;
top也一样
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部