Windowos体验iOS滑动解锁特效(更新)
2012-09-16 21:28
411 查看
序:
自苹果手机系统面世以来,一直很喜欢它的滑动解锁特效,有一天突发奇想,能不能在windows上也体验到这种特效呢?这个想法一直在酝酿,直到有一天,2011年7月的一天,决定开始做出来!!说来惭愧,从想法到成品,期间很曲折,浪费了很多时间,由于只能利用晚上的几个小时,中途几个月还暂缓了,所以拖到现在才基本完成。曾经想过放弃,但是又不想这么做,我算是一个“疯狂的程序员吗”?那就做完它!现在已经把写程序当成下班后的放松活动了
= =!
回归正题,我要做成锁屏程序,在笔记本的触摸板上轻轻一划,屏幕解锁,显示出经典的windows桌面,而且还具有图标的动画效果,和你手上的iPhone是相同的界面,是不是很迷人?
值得庆幸的是,当你看到这篇文章时,这个想法已经付诸实践并基本完成了!择日我会发布出来,供大家享用,源码就不发了,那时候的我程序结构写的很乱,没法看,开源了也是给人找麻烦,特别是水平比较高的Coder,会喷我的,呵呵。后面我会把实现的原理和程序结构说一下就可以了。下面先让大家看看期待已久的成品效果吧!!锵~锵~锵~~~~
程序运行界面
演示视频:
无法播放可以点击打开演示视频
界面已经很完美的模拟了苹果系统了,WIFI信号、电池信息、充电图标、解锁滑块、发光文字。你一定很惊讶于它的逼真程度吧?想知道是如何实现的吗?好,请接着看~
正文:
程序最开始设计为MFC开发(如果是现在做我恐怕就不会选择这个了),中途遇到技术难题转到了C#平台,由于托管语言的性能,我又不得不回到了MFC!真是曲折的一条路,如果我那时候知道用DirectUI,我就用Bolt了。所以现在这个程序没有使用任何第三方界面库,完全是GDI和GDI+搭配绘制的,包括动画。程序界面上的各种元素,通过ATL的CImage类承载,这个类很好用,对有Alpha通道的PNG图像支持的很好,程序使用了双缓冲的处理方式,绘制了N多个CImage局部图层,最后合成到一张最终层(CImage),将其贴到界面上。
所有的动画通过定时器不断的绘制到局部图层上,最后在一个消息循环中不断刷新最终层:
GDI+的效果终归不是太理想,有些特效虽然实现了,但是不得不屏蔽了。
电池信息等通过API获取,定时更新到界面上。获取桌面背景这个我找了很长时间,最后通过这句代码实现了:
滑块的移动,自然通过鼠标的点击移动事件来处理,而且还要限制鼠标移动的范围。发光文字特效通过GDI+的线性画刷实现,传递坐标参数用定时器不断调用就能动起来了:
图标的动画,有两种方式,一种是获得桌面的句柄一个个的从图像上扣下来,另一种是调用API获取,以下的代码只是给个思路:
这个是获取图标的图像,存储到CImage当中去,要实现视频中的动画效果,我是写了一个我自己都懒得再分析的你所能想到最笨拙的方法实现了,代码就不贴了,看了废脑子。用自己的想法实现,说不定比我的更好。
图标动画的设计:
首先获取所有图标的图像和位置信息,根据其所在坐标为图标分层。如图,矩形中的是实际桌面上的图标,最中间的标1的作为最里层,向外依次为第二层,第三年层等等。矩形外的图标是动画开始时图标的位置,因为这里我们要实现聚拢的动画效果,所以最里层的图标要放到最外面,依次类推,矩形里的层和矩形外的层的位置是相反的。箭头表明其从起始位置移动到终点位置的示意。这样,聚拢的动画效果就实现了。
下载:
目前Beta1版已发布!推荐Win7环境下运行,XP系统可能存在兼容问题。http://download.csdn.net/download/detecyang/4576409
自苹果手机系统面世以来,一直很喜欢它的滑动解锁特效,有一天突发奇想,能不能在windows上也体验到这种特效呢?这个想法一直在酝酿,直到有一天,2011年7月的一天,决定开始做出来!!说来惭愧,从想法到成品,期间很曲折,浪费了很多时间,由于只能利用晚上的几个小时,中途几个月还暂缓了,所以拖到现在才基本完成。曾经想过放弃,但是又不想这么做,我算是一个“疯狂的程序员吗”?那就做完它!现在已经把写程序当成下班后的放松活动了
= =!
回归正题,我要做成锁屏程序,在笔记本的触摸板上轻轻一划,屏幕解锁,显示出经典的windows桌面,而且还具有图标的动画效果,和你手上的iPhone是相同的界面,是不是很迷人?
值得庆幸的是,当你看到这篇文章时,这个想法已经付诸实践并基本完成了!择日我会发布出来,供大家享用,源码就不发了,那时候的我程序结构写的很乱,没法看,开源了也是给人找麻烦,特别是水平比较高的Coder,会喷我的,呵呵。后面我会把实现的原理和程序结构说一下就可以了。下面先让大家看看期待已久的成品效果吧!!锵~锵~锵~~~~
程序运行界面
演示视频:
无法播放可以点击打开演示视频
界面已经很完美的模拟了苹果系统了,WIFI信号、电池信息、充电图标、解锁滑块、发光文字。你一定很惊讶于它的逼真程度吧?想知道是如何实现的吗?好,请接着看~
正文:
程序最开始设计为MFC开发(如果是现在做我恐怕就不会选择这个了),中途遇到技术难题转到了C#平台,由于托管语言的性能,我又不得不回到了MFC!真是曲折的一条路,如果我那时候知道用DirectUI,我就用Bolt了。所以现在这个程序没有使用任何第三方界面库,完全是GDI和GDI+搭配绘制的,包括动画。程序界面上的各种元素,通过ATL的CImage类承载,这个类很好用,对有Alpha通道的PNG图像支持的很好,程序使用了双缓冲的处理方式,绘制了N多个CImage局部图层,最后合成到一张最终层(CImage),将其贴到界面上。
所有的动画通过定时器不断的绘制到局部图层上,最后在一个消息循环中不断刷新最终层:
switch (pMsg->message) { case WM_TIMER: lfont.DrawLightFont(srcFrameRect,DeskTopImg,offset==180?offset+=5:offset+=5,button); BitBlt(Desk.GetDC(),0,0,scrW,scrH,DeskCopy.GetDC(),0,0,SRCCOPY); //呈现放大8%的背景到桌面,以便收缩图标动画时还原背景大小。 //BitBlt(Desk.GetDC(),scrW/2-DeskCopy.GetWidth()/2,scrH/2-DeskCopy.GetHeight()/2,DeskCopy.GetWidth(),DeskCopy.GetHeight(),DeskCopy.GetDC(),0,0,SRCCOPY); DeskCopy.ReleaseDC(); Desk.ReleaseDC(); DeskTopImg.Draw(Desk.GetDC(),0,0); Desk.ReleaseDC(); Desk.Draw(pDC->m_hDC,0,0,scrW,scrH);//将合成图贴到窗体上 ReleaseDC(pDC); break; case WM_PAINT: break; case WM_KEYDOWN: break; case WM_MOUSEMOVE: KillTimer(SHOW); break; default: break; }
GDI+的效果终归不是太理想,有些特效虽然实现了,但是不得不屏蔽了。
电池信息等通过API获取,定时更新到界面上。获取桌面背景这个我找了很长时间,最后通过这句代码实现了:
PaintDesktop(pDC->m_hDC);
滑块的移动,自然通过鼠标的点击移动事件来处理,而且还要限制鼠标移动的范围。发光文字特效通过GDI+的线性画刷实现,传递坐标参数用定时器不断调用就能动起来了:
Graphics g(_frameRect.GetDC()); g.SetTextRenderingHint(TextRenderingHintAntiAlias); SolidBrush brush(Color(102, 0, 0, 0)); Font font(fontName, size, FontStyleRegular, UnitPixel); StringFormat strFormat; strFormat.SetAlignment(StringAlignmentCenter); WCHAR *w_str=new WCHAR[str.GetLength()*2]; USES_CONVERSION; wcscpy(w_str, CT2CW(str)); RectF rf; g.MeasureString(w_str,(INT)wcslen(w_str),&font,PointF(0,0),&rf); //创建多色数组 Color clrs[] = { Color(255, 138, 139, 139), Color(255, 138, 139, 139), Color.White, Color.White, Color(255, 138, 139, 139), Color(255, 138, 139, 139) }; REAL positions[] = { 0, 0.4F, 0.5F, 0.6F, 0.7F, 1.0F }; //创建线性画刷 Rect rect; rect.X=offset; rect.Y=0; rect.Width=(int)rf.Width+100; rect.Height=(int)rf.Height; LinearGradientMode lmode=LinearGradientModeHorizontal; LinearGradientBrush lbrush(rect, Color.White, Color.White, LinearGradientModeHorizontal); lbrush.SetInterpolationColors(&clrs[0], &positions[0], 6); g.DrawString(w_str,(INT)wcslen(w_str),&font, RectF(FRAME_W/2-(int)rf.Width/2+30,FRAME_H/2-(int)rf.Height/2,rf.Width,rf.Height),&strFormat, &lbrush); _frameRect.ReleaseDC();
图标的动画,有两种方式,一种是获得桌面的句柄一个个的从图像上扣下来,另一种是调用API获取,以下的代码只是给个思路:
#ifdef GET_ICON_MODE HWND hwndParent = ::FindWindow( L"Progman", L"Program Manager" ); HWND hwndSHELLDLL_DefView = ::FindWindowEx( hwndParent, NULL, L"SHELLDLL_DefView", NULL ); HWND hwndSysListView32 = ::FindWindowEx( hwndSHELLDLL_DefView, NULL, L"SysListView32", L"FolderView" ); HDC hDc = ::GetDC(hwndSysListView32); int num = ListView_GetItemCount( hwndSysListView32 ); //Point *icons=new Point[num]; DWORD dwProcessId; GetWindowThreadProcessId(hwndSysListView32, &dwProcessId); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); LPVOID lpvPt = VirtualAllocEx(hProcess, NULL, sizeof(POINT), MEM_COMMIT, PAGE_READWRITE); POINT pt; int layer_x = GET_ODD(scrW / iconWidth); int layer_y = GET_ODD(scrH / iconHeight); int layers; int OFFSET_X, OFFSET_Y; if (layer_x > layer_y) { layers = layer_x / 2; //获得图标层数(以多的为准) OFFSET_Y = -iconHeight*(layer_x - layer_y)/2; OFFSET_X = 0; } else { layers = layer_y / 2; OFFSET_X = -iconWidth*(layer_y - layer_x)/2; OFFSET_Y = 0; } IcoLayer *iLayer = new IcoLayer[layers]; //存储每层的图标 memset(iLayer,0,sizeof(IcoLayer)*9); //修改图标间距 //SystemParametersInfo(SPI_GETICONMETRICS, ico, sizeof(ICONMETRICS)); //获取桌面背景存储到desk CDC *pDC = GetDC(); /*PaintDesktop(pDC->m_hDC); GetDesktop(Desk);*/ stIcon *stIco = new stIcon[num]; memset(stIco,0,sizeof(stIcon)*num); int ico_off_x = 8; int ico_off_y = 8; //截取所有图标所在位置的图像 for( int i = 0; i < num; i++ ) { //#ifdef WIN7 if(!IsXP) { // ico_off_x = 8; // ico_off_y = 8; } //#else else{ // ico_off_x = 21; // ico_off_y = 2; } //#endif ListView_GetItemPosition(hwndSysListView32, i, lpvPt); ReadProcessMemory(hProcess, lpvPt, &pt, sizeof(POINT), NULL); //ImageList_Draw(); //存储图标的img stIco[i].img.Create(iconWidth,iconHeight,BIT_NBPP,CImage::createAlphaChannel); ::BitBlt(stIco[i].img.GetDC(), 0, 0, iconWidth, iconHeight, hDc, pt.x-ico_off_x, pt.y-ico_off_y, SRCCOPY);
这个是获取图标的图像,存储到CImage当中去,要实现视频中的动画效果,我是写了一个我自己都懒得再分析的你所能想到最笨拙的方法实现了,代码就不贴了,看了废脑子。用自己的想法实现,说不定比我的更好。
图标动画的设计:
首先获取所有图标的图像和位置信息,根据其所在坐标为图标分层。如图,矩形中的是实际桌面上的图标,最中间的标1的作为最里层,向外依次为第二层,第三年层等等。矩形外的图标是动画开始时图标的位置,因为这里我们要实现聚拢的动画效果,所以最里层的图标要放到最外面,依次类推,矩形里的层和矩形外的层的位置是相反的。箭头表明其从起始位置移动到终点位置的示意。这样,聚拢的动画效果就实现了。
下载:
目前Beta1版已发布!推荐Win7环境下运行,XP系统可能存在兼容问题。http://download.csdn.net/download/detecyang/4576409
相关文章推荐
- iOS滑动解锁/滑动获取验证码效果实现
- iOS 自定义实现滑动解锁功能
- iOS并发编程指南——超级详细的指南,放弃线程,高效并发,实现完美体验吧!(更新PDF下载)
- iOS之iPhone解锁界面的"滑动来解锁"闪烁动画效果,好奇的赶紧进来取走,别看了,说的就是你0.0
- iOS 闪光的按钮,流光动画,iPhone经典滑动解锁动画
- iOS滑动解锁、滑动获取验证码效果的实现代码
- iOS解锁界面的"滑动来解锁"闪烁动画效果
- ios学习之CALAyerAnimation 的iphone经典滑动解锁动画
- Android自定义绘制:Shader - 模仿iOS滑动解锁
- 仿ios全屏滑动解锁,带阴影效果
- 苹果获iOS滑动解锁界面及第一代iPhone设计专利
- iOS实现手势滑动解锁功能简析
- iOS开发-苹果热更新方案简介
- 值得关注的iOS技术博客(持续更新)
- ios 中 关闭uitableview 中手势滑动出现按钮的功能
- iOS热更新技术被苹果官方警告?涉及到RN、Weex、JSPatch!!!
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- iOS开发编码建议与规范(持续更新中)
- Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
- iOS 检测版本更新