转自:http://hi.baidu.com/venky_zhou/blog/item/b691432ceca8c021359bf706.html最近做UI,要做一个仿苹果工具栏效果的UI,在网上搜索了很久,结果都没找到VC的代码,倒是JAVA,VB,C#等代码都有人上传了。用VC做UI确实是很头疼的事情,这里我说一下DOCK工具栏的实现思路,要用到GDI+的,GDI图标周边有锯齿。1.设置Dock工具栏的基本信息:
图标信息(路径,大小)——m_PicInfo[i]
鼠标最大响应距离,最小响应距离——m_MaxDisc,m_MinDisc
图标最大缩放比例,最小缩放比例——m_MaxRate,m_MinRate
图标初始大小——m_Width,m_Height
2.获取动态图标中心,公式中的Width和Height必须是动态图标的宽度和长度,不能用原始长宽,
这也是算法的精髓之一,巧妙的地方总是微不足道的。这里用了递归的思路。
  PointCenter(Left.X + Width/2, Left.Y + Height/2)
3.计算鼠标坐标到每个图标中心的距离——Disc[i]。
4.根据距离Disc[i]计算出每个图标的缩放比例——m_PicInfo[i].Rate
现在我用的公式就是最简单的线性公式:y=ax+b,数学没学好,曲线公式整不出来。
Rate=a*Disc+b
把(m_MaxDisc,m_MinRate)和(m_MaxRate, m_MinDisc)两对值代入函数,计算出常量a,b的值,
注意m_MaxDisc是和m_MinRate对应的,就是鼠标距离最远时,图标缩放比例是最小。
  a = (MinRate - MaxRate)/(MaxDisc - MinDisc);
  b = MinRate - a * MaxDisc;
5.根据m_PicInfo[i].Rate计算出动态图标的大小,下面的m_Width,m_Height是图标初始大小,不是动态的。
  m_PicInfo[i].Width = m_Width * m_PicInfo[i].Rate;
  m_PicInfo[i].Height = m_Height * m_PicInfo[i].Rate;
6.然后再根据动态图标的大小,计算出动态工具栏的长度——m_DockLen
  m_DockLen = m_PicInfo[0].Width + ……m_PicInfo[i].Width
7.得到工具栏长度后,我们就可以确定工具栏在窗口的位置了,主要是横坐标,纵坐标没怎么变化
  首先
  GetClientRect(rc);
  cx = rc.Width();
  cy = rc.Height();
  获得窗口的大小(cx, cy),Dock工具栏的起始坐标(X,Y),
  X = (cx - m_DockLen)/2     //目的是使Dock工具栏对称的显示在中间位置
  Y = cy - m_PicInfo[0].Height - c  //常量c是工具栏距离窗口最下端的距离,工具栏默认放在
         //窗口最下端,拖放停靠的功能还有待高手继续开发。
8.最后确定Dock工具栏每个图标的坐标,
  m_PicInfo[i].Left.X = X + m_PicInfo[i-1].Width; //i>0,i=0的坐标就是上面的(X,Y)
  m_PicInfo[i].Left.Y = cy - m_PicInfo[i].Height - c9.最后根据每个图标的坐标画出图标。补充一下,在OnMouseMove()最好只在工具栏的那一小块相应鼠标移动事件。

解决方案 »

  1.   

    我把代码上传到CSDN上了,到这里下载:
    http://download.csdn.net/source/3172416
      

  2.   

    应该是参照TXbar做的,做得还不错,但下载要5分,好贵啊
      

  3.   

    就是参考TXbar的,不过算法重新设计了一下,问一下有可能把这个工具栏做成窗口控件吗?
      

  4.   

    对GDI+不了解的同学可以看看这个,会给你意外的惊喜的,可以做出很多华丽炫酷的效果来。
    http://download.csdn.net/source/3151816