提问:如何像winamp一样同时移动几个form?
我用WM_MOVE好像比较麻烦,而且不是像winamp同时移动,是移动了一个,另一个马上更过去
不想用timer,太浪费
我用WM_MOVE好像比较麻烦,而且不是像winamp同时移动,是移动了一个,另一个马上更过去
不想用timer,太浪费
解决方案 »
- 請問誰有toolbar2000的tbskin?
- 在delphi程序中,如何判断sql server中的指定的存储过程是否存在? 急!
- 当打开一个表单时,怎样让这个表单始终在所有表单的前边?谢谢!
- 发布源码《单机泡泡堂》
- 100分 怎么获取CPU的占用率?
- 有人做过这个吗?
- 谁有多余的qq号?
- 制作帮助文件的这个工具shelpm怎么用?谢谢!
- 我想实现如EXCEL一样的表格,可录入,只有几行几列。用什么控件?(stringgrid好像不行)
- 谁知道哪有能自动打印的DBGrid控件?最好有源码
- 关于更新 DBGrid 的问题,老提示 can't modify a read-only dataset
- 为孩子起名
可惜是c的
关键地方看不懂
当主窗体移动的时候,给各从窗体发送一个WM_MYMOVE即可。
Form1.FormStyle:=fsNormal;
Form2.FormStyle:=fsNormal;
Form3.FormStyle:=fsNormal;
Form1.Show;
Form2.Show;
Form3.Show;
如何让它有粘性呢?
winamp的用户都知道,winamp的播放列表或均衡器在被移动的时候,仿佛会受到一股磁力,
每当靠近主窗口时就一下子被“吸附”过去,自动沿边对齐。我想让我的winamp插件也具备
这种奇妙特性,于是琢磨出了一种“磁化”窗口的方法。该法适用于delphi的各个版本。为
了演示这种技术,请随我来制作一个会被winamp“吸引”的样板程序。
先新建一应用程序项目,把主窗口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 < b then result:=b else result:=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;
不过nl,nt等是什么啊
还有好像是讲磁性,不是我问的同时移动多个form的问题吧
我是菜鸟,问的问题比较没水平,不要见怪