快速业务通道

建立磁性窗体

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30

一些著名的共享软件不但功能卓著,而且在程序界面的设计技巧上往往领导了一种时尚,WinAmp就是其中的一个代表。WinAmp有两个绝活,一是可以更换窗体的外观,也就是现在俗称的给软件换“皮肤”;另一个即是磁性窗体技巧。

磁性窗体即若干窗体靠近到一定距离以内时会互相粘在一起,或者说相互吸附在一起,然后在拖动主窗体时,粘在其上的其它窗体也一起跟着移动,好像变成了一个窗体。国内的MP3播放器新秀CDOK也实现了这种技巧,而且更绝,把几个窗体粘在一起后,窗体没有主从之分,拖动其中任意一个窗体都会使其它的窗体一起移动。在CSDN上有关怎样设计磁性窗体的帖子非常多,说明这个技巧深得广大程序员的青睐。

本文先把几位网友的方法略加分析,然后给出我认为比较可行的实现方法和源代码。

实现磁性窗体基本上分为两步,第一步是实现当两个窗体靠近到一定距离以内时实现窗体间的粘贴操作,第二步是移动窗体时,同时移动与它粘在一起的其它窗体。

实现窗体的粘贴

实现粘贴的难点在于什么时候进行这个操作,假设有两个窗体Form1和Form2,移动Form2向Form1靠近,当Form2与Form1的最近距离小于distance时粘贴在一起。显然,应该在移动Form2的过程中进行判断,问题是在程序的什么位置插入判断代码呢?

CSDN上有人认为可以使用定时器,每隔一定的时间检查各个窗体的位置。这种方法有着明显的弊病,不说定时器要无谓地浪费系统资源,单单它的即时性就难以保证。如果缩短计时值,浪费的CPU资源就更多了,所以我也就不多说了。

合理的方法是利用系统产生的消息,但是利用什么消息呢?窗体在移动时会产生WM_WINDOWPOSCHANGING和WM_MOVING消息,移动结束后会产生WM_WINDOWPOSCHANGED和WM_MOVE消息。WM_WINDOWPOSCHANGING和WM_WINDOWPOSCHANGED消息的参数lParam是结构WINDOWPOS的指针,WINDOWPOS定义如下:

 typedef struct _WINDOWPOS {
    HWND hwnd; // 窗口句炳
    HWND hwndInsertAfter; // 窗口的Z顺序
    int x; // 窗口x坐标
    int y; // 窗口的y坐标
    int cx; // 窗口的宽度
    int cy; // 窗口的高度
    UINT flags; // 标志位,根据它设定窗口的位置
   } WINDOWPOS;

可以看出,WM_WINDOWPOSCHANGED消息不仅仅在窗口移动时产生,而且在它的Z顺序发生变化时也会产生,包括窗口的显示和隐藏。所以我认为这个消息不是最佳选择。

WM_MOVING和WM_MOVE消息的参数lParam是一个RECT结构指针,与WM_WINDOWPOSCHANGED消息相比较为单纯,我采用的即是这个消息。下面我给出用C++ Builder写的示例程序。

为了方便程序的阅读,先定义了一个枚举数据类型,表示窗体的粘贴状态。同时定义了一个类,封装了窗体粘贴相关的数据,其中的Enable是为了防止重复进行操作,方法是操作时设置Enable为否,操作结束时恢复为真,而在操作前检查这个标志是否为否,否则直接返回。

建立磁性窗体

图2 窗体的粘贴状态示例

// 窗体粘贴状态,含义见图2
   enum enumAttachStyle
   {
    AS_NONE, // 没有粘贴
    AS_TOP,
    AS_BOTTOM,
    AS_T_TOP,
    AS_LEFT,
    AS_RIGHT,
    AS_L_LEFT
   };
   // 处理窗体粘贴的类,为了简化,采用了public声明
   class CFormAttachStyle
   {
    public:
    bool Enabled; // 防止重复进行粘贴相关的操作
    HWND AttachTo; // 被粘贴到哪个窗口
    int XStyle; // 左右方向的粘贴状态
    int YStyle; // 上下方向的粘贴状态
    int xPos; // 粘贴到的x坐标
    int yPos; // 粘贴到的y坐标
    CFormAttachStyle() // 初使化数据
    {
      XStyle =AS_NONE;
      YStyle =AS_NONE

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号