就是磁性窗体的代码:
不要网上的那个,要你得却调试成功的,谢谢
不要网上的那个,要你得却调试成功的,谢谢
解决方案 »
- delphi中如何杀死进程?
- 如何制作.pdf文件,哪里可下到Acrobat?(不是Adobe Reater)
- vc编写的dll如何调用
- 关于setjob API的问题
- 请问怎么使一个窗体不响应被单击的事件?(被单击后无任何变化,不出现在最顶上)
- 在adocommand里创建存储过程为什么不行?路过帮我看一看。
- 请问这是怎么回事
- 急!急!我有一个表单用一个TabControl控件,有8个PAGE
- 为什么用SHELLEXECUTE打开PDF文件后却马上消失,请指点一下~!
- 我想让一个进度条与一个batchmove相联系,使bctchmove执行时显示进度条进度,怎么作呢?
- 那位能够详细的说一下 Socket.SendBuf() 和 Socket.ReceiveBuf()
- 不要问为什么!来接分!都有分!
先新建一应用程序项目,把主窗口Form1适当改小些,并将BorderStyle设为bsNone。放一个按钮元件,双击它并在OnClick事件中写“Close;”。待会儿就按它来结束程序。现在切换到代码编辑区,定义几个全局变量。
var
Form1: TForm1; //“磁性”窗口
LastX, LastY: Integer; //记录前一次的坐标
WinampRect:Trect; //保存Winamp窗口的矩形区域
hwnd_Winamp:HWND; //Winamp窗口的控制句柄
接着编写Form1的OnMouseDown和OnMouseMove事件。
procedure TForm1.FormMouseDown(Sender: Tobject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
ClassName=‘Winamp v1.x’; //Winamp主窗口的类名
//如果改成ClassName=‘TAppBuilder’,你就会发现连Delphi也有引力啦!
begin
//记录当前坐标
LastX := X;
LastY := Y;
//查找Winamp
hwnd_Winamp := FindWindow(ClassName,nil);
if hwnd_Winamp>0 then //找到的话,记录其窗口区域
GetWindowRect(hwnd_Winamp, WinampRect);
end;
procedure TForm1.FormMouseMove(Sender: Tobject; Shift: TShiftState; X,
Y: Integer);
var
nLeft,nTop:integer; //记录新位置的临时变量
begin
//检查鼠标左键是否按下
if HiWord(GetAsyncKeyState(VK_LBUTTON)) > 0 then
begin
//计算新坐标
nleft := Left + X - LastX;
nTop := Top + Y - LastY;
//如果找到Winamp,就修正以上坐标,产生“磁化”效果
if hwnd_Winamp>0 then
Magnetize(nleft,ntop);
//重设窗口位置
SetBounds(nLeft,nTop,width,height);
end;
end;
别急着,看Magnetize()过程,先来了解一下修正坐标的原理。根据对Winamp实现效果的观察,我斗胆给所谓“磁化”下一个简单的定义,就是“在原窗口与目标窗口接近到某种预定程度,通过修正原窗口的坐标,使两窗口处于同一平面且具有公共边的过程”。依此定义,我设计了以下的“磁化”步骤。第一步,判断目标窗口(即Winamp)和我们的Form1在水平及垂直方向上的投影线是否重叠。“某方向投影线有重叠”是“需要进行坐标修正”的必要非充分条件。判断依据是两投影线段最右与最左边界的差减去它们宽度和的值的正负。第二步,判断两窗口对应边界是否靠得足够近了。肯定的话就让它们合拢。
好了,下面便是“神秘”的Magnetize过程了……
procedure TForm1.Magnetize(var nl,nt:integer);
//内嵌两个比大小的函数
function Min(a,b:integer):integer;
begin
if a>b then result:=b else result:=a;
end;
function Max(a,b:integer):integer;
begin
if a end;
var
H_Overlapped,V_Overlapped:boolean; //记录投影线是否重叠
tw,ww,wh:integer; //临时变量
const
MagneticForce:integer=50; //“磁力”的大小。
//准确的说,就是控制窗口边缘至多相距多少像素时需要修正坐标
//为了演示,这里用一个比较夸张的数字--50。
//一般可以用20左右,那样比较接近Winamp的效果
begin
//判断水平方向是否有重叠投影
ww := WinampRect.Right-WinampRect.Left;
tw := Max(WinampRect.Right,nl+Width)-Min(WinampRect.Left,nl);
H_Overlapped := tw<=(Width+ww);
//再判断垂直方向
wh := WinampRect.Bottom-WinampRect.Top;
tw := Max(WinampRect.Bottom,nt+Height)-Min(WinampRect.Top,nt);
V_Overlapped := tw<=(Height+wh);
//足够接近的话就调整坐标
if H_Overlapped then
begin
if Abs(WinampRect.Bottom-nt)
else if Abs(nt+Height-WinampRect.Top)
end;
if V_Overlapped then
begin
if Abs(WinampRect.Right-nl)
else if Abs(nl+Width-WinampRect.Left)
end;
end;
怎么样?运行后效果不错吧!
这个帖子我也有!
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Button1Click(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
LastX,LastY:Integer;
WinMapRect:TRect;
WinMap_HWND:HWND;
procedure ReSize(ALeft,ATop:Integer);
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
ClassName='TAppBulider';begin
LastX:=X; //X:是鼠标相对与form的位置
LastY:=Y; //left:是form相对Screen的位置
WinMap_HWND:=Windows.FindWindow(ClassName,nil);
if WinMap_HWND<>0 then
begin
GetWindowRect(WinMap_HWND,WinMapRect);
MessageBeep(0);
end;
//showmessage(inttostr(LastX)+'A1');
// showmessage(inttostr(lasty)+'A2');
// showmessage(inttostr(self.Left)+'A3');
// showmessage(inttostr(self.Top)+'A4');end;procedure TForm1.Button1Click(Sender: TObject);
var
S:integer;
begin
Self.Close;
end;procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
nLeft,nTop:integer;
begin
if HIWord(GetAsyncKeyState(VK_LBUTTON))>0 then
begin
nLeft:=Left+(X-LastX);
nTop:=Top+(Y-LastY);
end;
if WinMap_HWND<>0 then
ReSize(nLeft,nTop);
Self.SetBounds(nLeft,nTop,Width,Height);
end;procedure TForm1.ReSize(ALeft, ATop: Integer);
function MIN(A,B:Integer):integer;
begin
if A>B then
result:=B
else
result:=A;
end;
function MAX(A,B:Integer):Integer;
begin
if A>B then
result:=A
else
result:=B;
end;
var
H_,V:Boolean;
tw,ww,wh:integer;
const
Forse:integer=50;
begin
ww:=WinMapRect.Right-WinMapRect.Left;
tw:=MAx(WinMapRect.Right,nl+Width)-Min(WinMapRect.Left,nl)end;end.