前几天开始写仿Win8 Metro界面文章,部分网友觉得不错,感谢各位的意见。本来今天一直在折腾Android VLC播放器,没时间写。不过明天休息,所以今天就抽时间先写一下。

言归正传,我们都知道Win8的Metro界面只要手指一划,页面就跟着滑动(准确来说是按钮跟着滑动,背景其实没动),这个操作目前的Android和iPhone都是这种操作,个人感觉都是从iPhone借鉴来,滑动切换很早就有,不过按钮和壁纸分开滑动,这个还是iPhone时代开始。

(这效果图是截了几张图弄的,所以看上去不流畅)

类逻辑关系图

1、界面逻辑层次

开始说滑动前,先要解析一下屏幕显示的原理。我们都知道屏幕最后呈现出来的画面,其实都是显存的数据,这个只有一份。也就是说最后用户看到的都是只有一张画面。如果你只是单纯按钮滑动,而背景不滑动,给人感觉是一个二维动画。

没错,逻辑上的确是二维的,我们在显示逻辑上可以划分多个逻辑层,最后组合成一个显示画面。

例如下面的结构体:

我这里区分了三个逻辑层

1、背景层

2、按钮层

3、时间控件层

这三个层次在逻辑上是分开的,最后需要显示的时候,才需要把他们组合起来,把画面绘画到兼容DC上,兼容DC再拷贝到屏幕DC上。这样才完成一次画面输出。这个有点想PhotoShop的图层,一张图片,由多个图层叠加完成。用过PS的人,应该很容易理解。

为了实现两个页面滑动切换,我增加了一个Page类,(界面类之间关系,可以查看上一篇文章)用来管理每个页面的按钮,下面列出Page类的类声明。

//只支持2行
#define ROW_NUM 2 //识别操作
#define DEL_BTN 0x10
#define ADD_BTN 0x11
#define SWITCH_BTN 0x12 class CDUIPage:public CDUIBase
{
public:
CDUIPage(void);
~CDUIPage(void); public:
//保存界面按钮的二维容器
vector<vector<CDUIButton *> > m_pVUICtrlContent; //保存界面按钮位置二维容器
vector<vector<CPoint> > m_pVUICtrlPos; //标记是否按钮滑动
//BOOL m_slideBtn; //标记是否滑动页面
//BOOL m_enterMouseMove; //点击了按钮
BOOL m_ClickBtn; //按下点击点
CPoint m_ClickDownPoint; //内存DC,保存滑动时候背景
CDC m_BackDC;//记录有多少方块(目前只支持两行)
int m_BlockNum[]; //点击的是大按钮还是小按钮,大按钮为True
BOOL m_BigBlock; //点击第几行按钮
int m_BlockLine; //点击第几个按钮
int m_BlockClickNum; //删除区域
CRect m_rcMainInterfaceDel;
   //...............
public:
//初始化一个页面
void InitPage(CDC * pDC, HWND MainWnd); //画图
void Draw(CDC * pDC); //响应窗口OnLButtonDown
BOOL OnLButtonDown(POINT point); //响应窗口OnLButtonUp
void OnLButtonUp(POINT point); //响应窗口OnMouseMove
int OnMouseMove(POINT point, CDC * pDC, CDC * pBackDC); //处理按钮移动交换
int OnLButtonUpDeal(int Page, POINT point); //添加新的按钮
void AddItem(CDUIButton * btn, int lineNum); //重新计算按钮位置
void ReloadBtnPos(); //设置偏移量
void SetOffsetPoint(int point);//插入项
void InsertItem(CDUIButton * btn, int lineNum, int Pos);//按钮排序//删除释放空按钮
void ReleaseBtn(int Line, int index);    //...............
};

从上面定义可以看出,这个Page类,其实主要作用就是管理Button类的,定义了一个二维向量容易,对应界面的二维布局,因为我那里界面屏幕分辨率相对比较固定。所以最多只能放两排按钮,所以最上面我定义了多少行现在。不过二维向量理论上没有限制多少行多少列。也就是说创建的所有CDUIButton对象都会被添加到二维向量里面,下面是添加的操作:

void CDUIPage::AddItem(CDUIButton * btn, int lineNum)
{
ASSERT(btn != NULL);
m_pVUICtrlContent.at(lineNum).push_back(btn);
//重新计算按钮位置
ReloadBtnPos();
}
lineNum表示是第几行的按钮,添加傲二维向量容器后,会根据按钮大小,计算出这个按钮的位置。按钮的位置都是动态排布的,所以没有按钮滑动的时候显示区域是动态变化的。其实这个就是把屏幕划分为一个二维格子,有点像棋盘,每个按钮就是一个棋子,放到对应的格子上面。只是Metro界面棋子大小不一样,需要做些特殊处理,其中一种棋子占用了两个格子。其实这种设计思维在现在的Android界面上也同样如此,Android的Launcher就是按照一个个格子来放按钮和widget。至于iPhone,没看过源码,不敢确定。不敢按照它界面排布,多半也是类似的思想。

2、按钮绘画
按钮绘画的时候,是调用的Page的Draw函数,来绘画。我们看看Draw函数内容:
void CDUIPage::Draw(CDC * pDC)
{
//把原来的背景DC拷贝到控件内部DC
m_BackDC.BitBlt(,,ScreenWidth,ScreenHeight, pDC, , , SRCCOPY); for (int outer=; outer<ROW_NUM; outer++)
{
int vectorNum = m_pVUICtrlContent.at(outer).size();
for (int k=; k<vectorNum; k++)
{
m_pVUICtrlContent.at(outer).at(k)->Draw(pDC);
}
}
}

Draw的代码其实很简单,就是调用了Page里面每个DUIButton的Draw函数,也就是说Page本身并没有提供绘画的功能,真正绘画显示按钮,是DUIButton类的功能。

DUIButton类绘画的功能也很简单,就是显示一张按钮的PNG图片。Draw(CDC * pDC)里面的DC指针其实就是指向内存兼容DC的指针。。目前可以理解为把所有按钮绘画到内存兼容DC上,而这个内容兼容DC其实已经绘画好了背景(这是我在上一层Container实现的内,这个后面会讲)。

3、界面滑动实现

界面滑动,就是两个Page对象之间的切换。下面是onMouseMove的执行代码:

int CDUIPage::OnMouseMove(POINT point, CDC * pDC, CDC * pBackDC)
{
for (int outer=; outer<ROW_NUM; outer++)
{
int vectorNum = m_pVUICtrlContent.at(outer).size();
for (int k=; k<vectorNum; k++)
{
m_pVUICtrlContent.at(outer).at(k)->OnMouseMove(point, pDC, pBackDC);
}
}
return TRUE;
}

同上面onDraw函数一样,MouseMove也是调用了DUIButton自身的MouseMove函数。具体代码可以查看上一篇文章。

因此Page类的作用只是用来管理Button,统一所有界面的操作。为上层提供统一的处理接口。对于最上层的Dialog来说,

是不需要知道下面的按钮是如何工作的。

今天就讲到这里,下一次会把Container和上层对接说明。有问题的朋友可以留意!

新建的讨论群,有兴趣可以加入

VC/Wince群:87053214

Edited by mythou

原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3161754.html

系列文章链接:

VC/Wince 实现仿Win8 Metro风格界面1——设计概述和自绘Button(附效果图)

VC/Wince 实现仿Win8 Metro风格界面2——页面滑动切换(附效果图)的更多相关文章

  1. VC/Wince 实现仿Win8 Metro风格界面1——设计概述和自绘Button(附效果图)

    去年用VC做了一个仿Win8 Metro风格的界面,感觉挺有意思,最近打算把实现过程和一些技术原理记录下来. 主要是风格上类似Win8,其实功能上很多借鉴了Android的操作方式.界面只支持两种大小 ...

  2. VC/Wince 实现仿Win8 Metro风格界面3——按钮移动交换、删除、添加快捷方式(附效果图)

    上一篇文章写了如何进行页面滑动切换,今天我讲一下如何实现两个按钮拖动交换位置,包括同一个页面按钮交换或者两个页面之间的按钮交换.另外就是如何拖动删除界面上的快捷方式.按钮交换和拖动删除,这两个功能基本 ...

  3. Win8 Metro风格的Web桌面HteOS

    前言     曾经天天折腾ExtJS,折腾累了.近期这段时间開始用jquery来做一些东西,发现还是蛮有意思的.可是做到最后才发现,原来做好设计真的很重要. 上图就是HteOS项目的截图,眼下正在开发 ...

  4. android仿win8 metro磁贴布局

    代码下载     //更新代码,   这里是更新后的代码 //////////////////////// 1,含一个图片无限滚动的控件,自己实现的 2.可新增删除每个磁贴 3.来个图片吧 ////* ...

  5. windows8开发-关于wp7应用迁移到win8 metro风格

    虽然微软说,wp7应用移植到win8上面是比较简单,只需要修改部分API和设计原则上的细节,同时它也提供了一份比较简洁的参考文档: 而实际上这种移植的工作量还是不小的,尤其当应用引用了较多底层的API ...

  6. 如何完美打造Win8 Metro版IE10浏览器页面(转)

    Windows8 内置两种 Internet Explorer 10 (以下简称 IE10),一个是在桌面环境下使用的 IE10:视窗操作.可以支持各种插件(ActiveX):而另外一个则是在新的开始 ...

  7. Android 仿Win8的metro的UI界面(上)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23441455 昨晚没事手机下载了一些APP,发现现在仿win8的主界面越来越多, ...

  8. devexpress实现模仿Win8桌面metro风格

    1.devexpress强大的控件库,可很容易的实现Win8桌面metro风格.使用的TileControl控件,拖动与Win效果相同.所有图片均来自网络资源.每个块也可实现如图所示的四种大小,如何实 ...

  9. 仿win8磁贴界面以及功能

    做移动产品界面占很大的一部分,同时也是决定一款产品好的的重要因素,最近看见有人放win8的界面效果,搜了两款,一款是只是仿界面没有特效,另一款是自定义组件能够实现反转效果,今天分析一下这两类界面. 仿 ...

随机推荐

  1. GIF Brewery for Mac(录制 Gif 动图工具)安装

    1.软件简介    GIF Brewery 一款用于录制 Gif 动图等的工具. 2.资源列表 链接 提取密码 系统要求 软件语言 GIF Brewery for Mac v3.9.5 ltmf ma ...

  2. Win7 安装 MongoDB

    MongoDB 下载 MongoDB 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制包下载地址:https://www.mon ...

  3. python中数组与多维数组用法介绍

    增加时a.append( 'a ')就可以了.只要按顺序加,就没有问题 . 使用时,完全可以使用下标: 代码如下 复制代码 a[0] a[1] 但出果引用不存在的下标,则会引发异常.这时,你需要先添加 ...

  4. 《TCP/IP详解卷1:协议》读书笔记

    <TCP/IP详解卷1:协议>读书笔记 - QingLiXueShi - 博客园https://www.cnblogs.com/mengwang024/p/4425834.html < ...

  5. Shell脚本:向磁盘中批量写入数据

    一.关于本文 工作要做的监控系统需要监控磁盘空间的使用率并报警.在测试这个功能的时候需要模拟两个场景:一是磁盘空间不断增长超过设定的阈值时,需要触发报警机制:二是磁盘空间降落到低于报警阈值的时候,不再 ...

  6. 【转】java原理—反射机制

    一.什么是反射:反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言 ...

  7. svm工具箱快速入手简易教程

    首先svm是用来做分类的,是一种有监督的分类器. 什么是有监督的呢?就是说在你给我一个数据集让我做分类之前.我已经有一些经验数据了.即要先进行学习,再进行分类. 这里就有了训练集和测试集.先用训练集来 ...

  8. 关于 隐藏元素(样式为 display: none 的元素)及其子元素 获取不到高度的问题

    IE 和 Edge 中都是这样,Chrome中好像还好. 方法就是换一个样式,还有一个控制显示隐藏的:visibility 相关文档:http://www.w3school.com.cn/cssref ...

  9. zabbix 实现对服务器的负载监控

    # grep Include /etc/zabbix/zabbix_agentd.conf ### Option: Include # Include= Include=/etc/zabbix/zab ...

  10. Spark VS Presto VS Impala

    https://www.quora.com/What-is-the-difference-between-Spark-and-Presto