磁性窗体的完整解决方案(100分)

  • 主题发起人 主题发起人 zcm1975117
  • 开始时间 开始时间
Z

zcm1975117

Unregistered / Unconfirmed
GUEST, unregistred user!
查询过以前有关磁性窗体的解答,但是还是找不到我要的答案:比如我有四个同时打开的
窗体,我要求它们相互具有吸引力,就象WINMAP那样,任意两个窗体都能够停靠,万重的
磁性窗体控件做得不错,但好象也满足不了这个要求,那位大侠有好的方法呢?有例子最
好了。
 
以前曾写代码试过,下边是我的一个完整DEMO,共有2个窗体。
主窗体是form1,form1上有按钮,按下,弹出form2,托动form2,就会发现form1有磁性了。
你可以修改一下,使所有的form都具有磁性。(D6通过)
--------------
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
form2.show;
end;

end.
--------------
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm2 = class(TForm)

private
procedure WMWINDOWPOSCHANGING(Var Msg: TWMWINDOWPOSCHANGING);message WM_WINDOWPOSCHANGING;
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

uses Types,Unit1;
{$R *.dfm}

procedure TForm2.WMWINDOWPOSCHANGING(var Msg: TWMWINDOWPOSCHANGING);
var
rWorkArea: TRect;
StickAt : Word;
begin
StickAt :=38; //可随意设置,是磁性的范围大小。

rWorkArea.Left:=form1.left;
rWorkArea.Top:=form1.Top;
rWorkArea.Right:=form1.left+form1.Width;
rWorkArea.Bottom:=form1.Top+form1.Height;

// SystemParametersInfo(SPI_GETWORKAREA, 0, @rWorkArea, 0);


//-------------------------------------------
// 磁性窗体图示:
//
// ……………………………………
// | ___________________ |
// | | |___|__________主from边界
// | | …………………… | |
// | | | | | |__________外边界,当超过(向内)外边界时,重新设置为主from边界
// | | | | | |
// | | |……………… |__|___|__________内边界,当超过(向外)内边界时,重新设置为主from边界
// | |___________________| |
// | |
// |…………………………………|
//
//
//---------------------------------------------

with Msg.WindowPos^ do
begin
if (x+cx<rWorkArea.Left+StickAt) then //左方 (x<rWorkArea.Left) and

if (x+cx>rWorkArea.Left-StickAt) or((x+cx>rWorkArea.Left) and (x+cx<rWorkArea.Left+StickAt)) then
begin
x:=rWorkArea.Left-cx;
end;

if (x>rWorkArea.Right-StickAt) then //右方 and (x+cx>rWorkArea.Right)
if (x<rWorkArea.Right+StickAt) or ((x<rWorkArea.Right) and (x>rWorkArea.Right-StickAt)) then
begin
x:=rWorkArea.Right;
end;

if (y+cy<rWorkArea.Top+StickAt) then //上方 (y<rWorkArea.Top) and
if (y+cy>rWorkArea.Top-StickAt) or ((y+cy>rWorkArea.Top) and (y+cy<rWorkArea.Top+StickAt)) then
begin
y:= rWorkArea.Top-cy;
end;

if (y>rWorkArea.Bottom-StickAt) then //下方 and (y+cy>rWorkArea.Bottom)
if (y<rWorkArea.Bottom+StickAt) or ((y<rWorkArea.Bottom) and (y>rWorkArea.Bottom-StickAt)) then
begin
y:= rWorkArea.Bottom;
end;
end;
inherited;
end;

end.
 
to jrp:
谢谢你解答,但我的意思是二个以上的窗体哟,两个窗体的磁性很好实现。
 
你只需将form2的部分代码copy到其他窗体,就可以了!
当然会麻烦一些! 呵呵
你可以给我一个邮箱,我给你发过去我的一个东东!
另:是jrq,不是jrp。
 
jrq:
你好!谢谢:zcm1975117@21cn.com
 
to jrq:
我看了你的程序,如果我看的没有错的话,你的那些窗体也只是只能和主窗体靠齐,
而其它窗体之间没有磁性,你应该看过WINMAP了,他们所有的窗体之间都有磁性。
 
to jrq,
给我发一个行不?
blue_start@163.net
 
先不要安装控件,use那个控件,稍作修改,比如说我有Form1,Form2
MagOption 加上
property MagForm1:Boolean read fMagForm1 write fMagForm1 default true;
property MagForm2:Boolean read fMagForm2 Write fMagForm2 default true;
procedure TMagnetic.WMLButtonDown(var Msg: TMessage);里面加上
if MagOption.fMagForm1 then
HWnd_Form1 := FindWindow('TForm1', nil); { get form1 Handle}
if HWnd_Form1 > 0 then
GetWindowRect(HWnd_Form1, RWnd_Form1); { get form1 rect}
if MagOption.fMagForm1 then
HWnd_Form2 := FindWindow('TForm2', nil); { get form2 Handle}
if HWnd_Form2 > 0 then
GetWindowRect(HWnd_Form2, RWnd_Form2); { get form2 rect}
procedure TMagnetic.Magnetic(var MagPoint:TPoint);里面加上
if (MagOption.fMagForm1) and (HWnd_Form1 > 0) then
begin
if Abs(RWnd_Form1.Bottom-MagPoint.Y)<fMagEffect then MagPoint.Y:=RWnd_Form1.Bottom
else if Abs(MagPoint.Y+fForm.Height-RWnd_Form1.Top)<fMagEffect then MagPoint.Y:=RWnd_Form1.Top-fForm.Height;
if Abs(RWnd_Form1.Right-MagPoint.X)<fMagEffect then MagPoint.X:=RWnd_Form1.Right
else if Abs(MagPoint.X+fForm.Width-RWnd_Form1.Left)<fMagEffect then MagPoint.X:=RWnd_Form1.Left-fForm.Width;
end;
if (MagOption.fMagForm2) and (HWnd_Form2 > 0) then
begin
if Abs(RWnd_Form2.Bottom-MagPoint.Y)<fMagEffect then MagPoint.Y:=RWnd_Form2.Bottom
else if Abs(MagPoint.Y+fForm.Height-RWnd_Form2.Top)<fMagEffect then MagPoint.Y:=RWnd_Form2.Top-fForm.Height;
if Abs(RWnd_Form2.Right-MagPoint.X)<fMagEffect then MagPoint.X:=RWnd_Form2.Right
else if Abs(MagPoint.X+fForm.Width-RWnd_Form2.Left)<fMagEffect then MagPoint.X:=RWnd_Form2.Left-fForm.Width;
end;
两个Form的OnCreate事件写
var
mg: TMagnetic;
begin
mg := TMagnetic.Create(Self);
mg.MagOption.MagForm2 := true;
mg.MagOption.MagForm1 := true;
end;

多个窗体就加上Form3,Form4这么改最简单。
任意两个之间都有磁性。
 
很感兴趣,能给我发一个吗?
 
不好意思,今天才看见这个帖子。等会找找给各位发去。
不一定好用啊。 [:)]
 
给我发一个中啊,目前本人的问题跟提问者一样啊
ipqqqug@163.com
谢谢各位大侠了
 
后退
顶部