winamp的窗口浮动技术(高分,还有美女)(300分)

  • 主题发起人 主题发起人 Chenlili
  • 开始时间 开始时间
C

Chenlili

Unregistered / Unconfirmed
GUEST, unregistred user!
winapi等程序,当playlist的窗口移动到主窗口过程时<br>有一个很突然、很明显的对齐过程(大家应该都可以注意到)<br>这个功能有没有简单一点的实现方法?
 
这个标题倒是满吸引人的 呵呵<br><br>没什么好办法吧,移动的时候判断坐标,在一定范围之内的话,<br>对齐就行了吧
 
高分看到了,美女呢?
 
资料我贴给你,美女在哪儿啊?<br>---------------------------<br>winamp的用户都知道,winamp的播放列表或均衡器在被移动的时候,仿佛会受到一股磁力,<br>每当靠近主窗口时就一下子被“吸附”过去,自动沿边对齐。我想让我的winamp插件也具备<br>这种奇妙特性,于是琢磨出了一种“磁化”窗口的方法。该法适用于delphi的各个版本。为<br>了演示这种技术,请随我来制作一个会被winamp“吸引”的样板程序。<br>  先新建一应用程序项目,把主窗口form1适当改小些,并将borderstyle设为bsnone。放<br>一个按钮元件,双击它并在onclick事件中写“close;”。待会儿就按它来结束程序。现在<br>切换到代码编辑区,定义几个全局变量<br>var<br>&nbsp; form1: tform1; //“磁性”窗口<br>&nbsp; lastx, lasty: integer; //记录前一次的坐标<br>&nbsp; winamprect:trect; //保存winamp窗口的矩形区域<br>&nbsp; hwnd_winamp:hwnd; //winamp窗口的控制句柄<br>&nbsp; <br>&nbsp; 接着编写form1的onmousedown和onmousemove事件。<br>procedure tform1.formmousedown(sender: tobject; button:tmousebutton;<br>&nbsp; shift: tshiftstate; x, y: integer);<br>const<br>&nbsp; classname = 'winamp v1.x'; //winamp主窗口的类名<br>&nbsp; //如果改成classname=‘tappbuilder’,你就会发现连delphi也有引力啦!<br>begin<br>&nbsp; //记录当前坐标<br>&nbsp; lastx := x;<br>&nbsp; lasty := y;<br>&nbsp; //查找winamp<br>&nbsp; hwnd_winamp := findwindow(classname,nil);<br>&nbsp; if hwnd_winamp&gt;0 then //找到的话,记录其窗口区域<br>&nbsp; &nbsp; getwindowrect(hwnd_winamp, winamprect);<br>end;<br><br>procedure tform1.formmousemove(sender: tobject; shift: <br>&nbsp; tshiftstate; x, y: integer);<br>var<br>&nbsp; nleft,ntop:integer; //记录新位置的临时变量<br>begin<br>&nbsp; //检查鼠标左键是否按下<br>&nbsp; if hiword(getasynckeystate(vk_lbutton)) &gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; //计算新坐标<br>&nbsp; &nbsp; nleft := left + x - lastx;<br>&nbsp; &nbsp; ntop := top + y - lasty;<br>&nbsp; &nbsp; //如果找到winamp,就修正以上坐标,产生“磁化”效果<br>&nbsp; &nbsp; if hwnd_winamp&gt;0 then<br>&nbsp; &nbsp; &nbsp; magnetize(nleft,ntop);<br>&nbsp; &nbsp; &nbsp; //重设窗口位置<br>&nbsp; &nbsp; &nbsp; setbounds(nleft,ntop,width,height);<br>&nbsp; end;<br>end;<br>别急着,看magnetize()过程,先来了解一下修正坐标的原理。根据对winamp实现效果的观<br>察,我斗胆给所谓“磁化”下一个简单的定义,就是“在原窗口与目标窗口接近到某种预定<br>程度,通过修正原窗口的坐标,使两窗口处于同一平面且具有公共边的过程”。依此定义,<br>我设计了以下的“磁化”步骤。第一步,判断目标窗口(即winamp)和我们的form1在水平及<br>垂直方向上的投影线是否重叠。“某方向投影线有重叠”是“需要进行坐标修正”的必要<br>非充分条件。判断依据是两投影线段最右与最左边界的差减去它们宽度和的值的正负。第<br>二步,判断两窗口对应边界是否靠得足够近了。肯定的话就让它们合拢。<br>好了,下面便是“神秘”的magnetize过程了……<br><br>procedure tform1.magnetize(var nl,nt:integer);<br>&nbsp; //内嵌两个比大小的函数<br>&nbsp; function min(a,b:integer):integer;<br>&nbsp; begin<br>&nbsp; &nbsp; if a &gt; b then result:=b else result:=a;<br>&nbsp; end;<br>&nbsp; function max(a,b:integer):integer;<br>&nbsp; begin<br>&nbsp; &nbsp; if a &lt; b then result:=b else result:=a; <br>&nbsp; end;<br>var<br>&nbsp; h_overlapped,v_overlapped:boolean; //记录投影线是否重叠<br>&nbsp; tw,ww,wh:integer; //临时变量<br>const<br>&nbsp; magneticforce:integer=50; //“磁力”的大小。<br>&nbsp; //准确的说,就是控制窗口边缘至多相距多少像素时需要修正坐标<br>&nbsp; //为了演示,这里用一个比较夸张的数字——50。<br>&nbsp; //一般可以用20左右,那样比较接近winamp的效果<br>begin<br>&nbsp; //判断水平方向是否有重叠投影<br>&nbsp; ww := winamprect.right - winamprect.left;<br>&nbsp; tw := max(winamprect.right,nl+width) - min(winamprect.left,nl);<br>&nbsp; h_overlapped := tw&lt;=(width+ww);<br>&nbsp; //再判断垂直方向<br>&nbsp; wh := winamprect.bottom - winamprect.top;<br>&nbsp; tw := max(winamprect.bottom,nt + height) - min(winamprect.top,nt);<br>&nbsp; v_overlapped := tw&lt;=(height + wh);<br>&nbsp; //足够接近的话就调整坐标<br>&nbsp; if h_overlapped then<br>&nbsp; begin<br>&nbsp; &nbsp; if abs(winamprect.bottom - nt)    <br>&nbsp; &nbsp; else if abs(nt + height - winamprect.top)    <br>&nbsp; end;<br>&nbsp; if v_overlapped then<br>&nbsp; begin<br>&nbsp; &nbsp; if abs(winamprect.right - nl)    <br>&nbsp; &nbsp; else if abs(nl + width - winamprect.left)    <br>&nbsp; end;<br>end;<br>  
 
有那么神秘吗?两分钟搞定!<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; private<br>&nbsp; &nbsp; procedure WMMOVE(var Msg: TMessage); message WM_MOVE;<br>&nbsp; end;<br>var<br>&nbsp; Form1: TForm1;<br>implementation<br>{$R *.DFM}<br>{ TForm1 }<br>procedure TForm1.WMMOVE(var Msg: TMessage);<br>begin<br>&nbsp; Inherited;<br>&nbsp; if (Left &lt; 10) and (Top &lt; 10) and <br>&nbsp; &nbsp; &nbsp;(Left &lt;&gt; 0) and (Top &lt;&gt; 0) then // 设定移动到左上角 10 点范围内时贴到边上去<br>&nbsp; begin<br>&nbsp; &nbsp; Left := 0;<br>&nbsp; &nbsp; Top := 0;<br>&nbsp; &nbsp; Msg.Result := 0;<br>&nbsp; end;<br>end;<br>end.<br>
 
很简单的说.
 
还有美女?在哪里呢?
 
chenlili是美女
 
嘿嘿!<br>有趣,看来发问者还真是个小丫头。
 
mm?<br>我可不是“色狼”
 
一听到或看到美女字样,众人都来了!呵呵!<br>
 
真的是美女吗?
 
同意BaKuBaKu的说
 
&nbsp; 美女美女。。。。。<br>&nbsp; &nbsp;I LIKE I LIKE
 
就是唐伯虎点秋香一样<br>美女<br>一回头<br>哇
 
世风日下,答问题的少看美女的多。(小声一点:我跟大家的来意差不多)<br>BaKuBaKu的方法应该是可行的,接了WM_MOVE信息。
 
看看DFS的TStickForm的源代码。
 
后退
顶部