实现仿Win8Metro风格的按钮交换和拖动删除功能

作者:小菜 更新时间:2025-03-16 点击数:
简介:仿Win8 Metro风格如何实现两个按钮拖动交换位置,包括同一个页面按钮交换或者两个页面之间的按钮交换。

另外就是如何拖动删除界面上的快捷方式。

按钮交换和拖动删

【菜科解读】

仿Win8 Metro风格如何实现两个按钮拖动交换位置,包括同一个页面按钮交换或者两个页面之间的按钮交换。

另外就是如何拖动删除界面上的快捷方式。

按钮交换和拖动删除,这两个功能基本上是现在智能手机的标准功能,不管是IOS或者Android都有类似功能。

我实现的功能,主要是参考Android的功能实现。

下面这个就是动态交换按钮效果图:

还是先把逻辑关系图放出来:

1、按钮拖动

怎么样才能实现拖动一个按钮到另外一个按钮位置上,实现交换?这个首先一个需要做的就是拖动按钮的操作。

按钮拖动我放到封装的DUIButton里面实现。

下面我们看看DUIButton里面如何把按钮拖动出来。

int CDUIButton::OnMouseMove(POINT point, CDC * pDC, CDC * backDC)//printf("mythou------->enter the Page::omMouseMove");//判断拖动的条件,按下按钮并且移动的距离大于30像素的时候,认为是拖动按钮 if( abs(point.x - m_iEndSlide) > 30 || abs(m_clickY - point.y) > 30 || m_mouseMove)//拖动快捷键 if(m_ClickState) m_mouseMove = TRUE; CRect rect = CRect(0, 0, ScreenWidth, ScreenHeight); //恢复保存的背景,主要是提高绘画效率 CDC destDC; destDC.CreateCompatibleDC(backDC); CBitmap CompatibleBmp; CompatibleBmp.CreateCompatibleBitmap(backDC,rect.Width(),rect.Height()); CBitmap *pOlddestBmp = destDC.SelectObject(&CompatibleBmp); destDC.FillSolidRect(&rect,RGB(0,0,0)); CDC srcDC; srcDC.CreateCompatibleDC(backDC); HBITMAP hOldBmp; destDC.BitBlt(0, 0, rect.Width(),rect.Height(), backDC, 0, 0, SRCCOPY); //根据用户手指移动的位置,动态刷新按钮,形成按钮跟谁手指移动的效果 hOldBmp = (HBITMAP)srcDC.SelectObject(m_btnHBitmap); m_pngCtrl.BiltPNG(&destDC,&srcDC,(point.x-(m_btnRc.Width()/2) ), (point.y-(m_btnRc.Height()/2)), m_btnRc.Width(),m_btnRc.Height(), m_AlphaSel); srcDC.SelectObject(hOldBmp); //把按钮图片,绘画到屏幕 pDC->BitBlt(0,0,rect.Width(),rect.Height(),&destDC,0,0,SRCCOPY); srcDC.DeleteDC(); destDC.SelectObject(pOlddestBmp); CompatibleBmp.DeleteObject(); destDC.DeleteDC(); return 1; return 0;

从这里可以发现,其实拖动一个按钮,就是把该按钮的图片,跟随手指的移动而动态贴图。

需要注意的是如何才能保证拖动的流畅性。

这个需要把你的背景图做成缓存,保留下来,拖动过程中,都是使用缓存中原始的背景图。

这样每次拖动,只需要绘画一个按钮的图片,才能流畅得拖动按钮。

另外你手指点击按钮还需要做一些条件判断,需要符合条件的情况下,才能拖动按钮。

我这里把手指触摸按钮分为3种行为:

点击按钮,打开某个程序

触摸按钮,滑动切换页面

把按钮拖动出来,执行交换、删除、添加操作

这几个也是目前智能机系统一般都支持的手势操作,上面我们按钮的拖动,就是属于第三种情况。

2、按钮交换

把按钮拖动出来,然后拖动到需要交换的按钮的位置,释放按钮,执行交换操作。

这个就是交换的流程,这里根据释放的位置来识别到底跟哪一个按钮进行交换。

//大按钮移动到大按钮位置 Edited by mythou if (UpBlockBig) //printf("mythou-------->enter change the big block"); CDUIButton * tempDUIBtn; tempDUIBtn = m_pVUICtrlContent.at(m_BlockLine).at(m_BlockClickNum); //保存IDS CString FirstBtnIDS = tempDUIBtn->GetBtnIDS(); m_pVUICtrlContent.at(m_BlockLine).at(m_BlockClickNum) = m_pVUICtrlContent.at(Line).at(vectorBtnIndex); //保存IDS CString SecondBtnIDS = m_pVUICtrlContent.at(Line).at(vectorBtnIndex)->GetBtnIDS(); m_pVUICtrlContent.at(Line).at(vectorBtnIndex) = tempDUIBtn; //动画效果 ChangeBtnPosAni(m_pVUICtrlContent.at(m_BlockLine).at(m_BlockClickNum), m_pVUICtrlContent.at(Line).at(vectorBtnIndex)); //修改配置文件 int PosIndex1 = GetBtnPos(m_BlockLine,m_BlockClickNum); int PosIndex2 = GetBtnPos(Line,vectorBtnIndex); m_pSaveInterFace->SwitchSameButton(Page,m_BlockLine,PosIndex1,FirstBtnIDS, Page,Line,PosIndex2,SecondBtnIDS); }

这是一个简单的交换逻辑,因为我们的按钮都是存放在Page类里面的二维Vector向量里面,按钮交换位置也就是交换Vector里面的值。

因为Vector里面存放只是按钮对象的指针应用。

因此,Vector交换两个指针也不会存在负责的数据交互。

当然如果要做出比较好的交换效果,我们免不了使用动画,交换过程中。

我们加入一个动画效果,我这里做的是一个淡入淡出的效果,主要控制按钮图片的Alpha值,形成一个较好的交换效果。

最后还需要把交换的位置信息记录到文件里面,方便下次启动程序的时候,保存交换后的效果。

需要注意的是交换按钮刷新和动画效果之间的操作。

要做到流程,考虑使用一个线程运行动画。

3、拖动删除按钮

这个功能其实就是参照Android的删除快捷方式做的。

当按钮被拉动出来后,界面上方会出现一个有垃圾桶图标的区域,把按钮拖动到该区域释放,就可以把相对的快捷方式删除。

下面我们看看逻辑上如何实现。

//在删除区域释放,删除按钮 if (m_rcMainInterfaceDel.PtInRect(point)) //printf("\n mythou------> Enter OnLButtonUpDeal() Delete the Btn ************** \n"); //删除选中按钮 CString DelBtnIDS = m_pVUICtrlContent.at(m_BlockLine).at(m_BlockClickNum)->GetBtnIDS(); m_pVUICtrlContent.at(m_BlockLine).at(m_BlockClickNum)->ResetAllClickFlag(); m_pVUICtrlContent.at(m_BlockLine).erase(m_pVUICtrlContent.at(m_BlockLine).begin()+m_BlockClickNum); //填充空按钮 CDUIButton *pBtn = new CDUIButton(); pBtn->SetNullBtn(); m_pVUICtrlContent.at(m_BlockLine).insert((m_pVUICtrlContent.at(m_BlockLine).begin()+m_BlockClickNum),pBtn); //如果是大按钮,再填充一次 if (m_BigBlock) CDUIButton *pBtn = new CDUIButton(); pBtn->SetNullBtn(); m_pVUICtrlPos.at(m_BlockLine).push_back(CPoint(0,0)); m_pVUICtrlContent.at(m_BlockLine).insert((m_pVUICtrlContent.at(m_BlockLine).begin()+m_BlockClickNum),pBtn); //修改配置文件 int PosIndex1 = GetBtnPos(m_BlockLine,m_BlockClickNum); m_pSaveInterFace->DeleteButton(Page,m_BlockLine,PosIndex1,DelBtnIDS,m_BigBlock); //DeleteButton(Page,m_BlockLine,PosIndex1,DelBtnIDS,m_BigBlock); m_BigBlock = FALSE; ReloadBtnPos(); return DEL_BTN;

删除操作在逻辑上也很简单,就是删除我们记录的Vector里面的相对应的按钮指针。

不过删除后,我们需要做一些额外的操作。

第一需要填充一个空按钮指针到原来的位置。

这个操作主要是用来记录界面上哪些位置是可以存放按钮和交换按钮。

空按钮是一个空类,只有一个标记用来记录位置。

删除后还需要针对按钮的类型做不同的添加操作,大按钮和小按钮。

最后还需要在配置文件做记录,记录哪个按钮删除了。

如果需要一个好的效果,可以类似交换按钮一样,加入一个动画效果。

4、添加快捷方式栏

这是额外做的一个功能,主要是把常用的功能加入到一个导航栏上面,可以在任何界面使用相关常用功能。

void CDUIPage::Send2TaskBar(CDUIButton *pBtn) printf("\n mythou-------->Enter Send2TaskBar ********************************\n"); DUIButtonData *pDuiData = new DUIButtonData(); //拷贝数据 wcscpy(pDuiData->name, pBtn->m_btnName.GetBuffer(pBtn->m_btnName.GetLength())); pBtn->m_btnName.ReleaseBuffer(); wcscpy(pDuiData->cmd, pBtn->m_BtnClickCMD.GetBuffer(pBtn->m_BtnClickCMD.GetLength())); pBtn->m_BtnClickCMD.ReleaseBuffer(); wcscpy(pDuiData->animate, pBtn->m_AnimateType.GetBuffer(pBtn->m_AnimateType.GetLength())); pBtn->m_AnimateType.ReleaseBuffer(); wcscpy(pDuiData->ids, pBtn->m_BtnNameIDS.GetBuffer(pBtn->m_BtnNameIDS.GetLength())); pBtn->m_BtnNameIDS.ReleaseBuffer(); CString btnPicName = GetExeName(pBtn->m_btnPic); wcscpy(pDuiData->picName, btnPicName.GetBuffer(btnPicName.GetLength())); btnPicName.ReleaseBuffer(); COPYDATASTRUCT cpdata; cpdata.dwData=PROCESSID cpdata.cbData = sizeof(DUIButtonData); cpdata.lpData = (PVOID)pDuiData; HWND mainWnd = ::FindWindow(NULL,_T("APKTaskBar")); if (!mainWnd) return; printf("\n mythou------->Send the OnCopyData Send2TaskBar ********************************"); ::SendMessage(mainWnd, WM_COPYDATA, (WPARAM)m_MainWndH, (LPARAM)&cpdata); delete pDuiData;

因为我的快捷栏是另外一个独立程序,所以这里把需要添加的按钮拉动到界面底部,然后把按钮的相关数据转换为相关数据包,发送到快捷栏程序里面。

这里也需要加入相关的动画效果,才能达到较好的界面交互效果。

剩下的就是另外一个程序处理发送过来的数据包。

解析然后显示出来就好了。

今天主要是讲解界面上常用的交换按钮、删除按钮、添加快捷栏等操作。

其中交换按钮这里只是把同页面的交换做了解说,除了同页面交换外,也需要做到不同页面之间交换,这个原理是一样,只是不同页面之间交换需要做到逻辑页面的切换。

这个也是我做了Page类作为页面管理类的原因。

不同类之间交换按钮,只要切换Page类就好了。

转载请标明出处:http://www.cnblogs.com/mythou/p/3172707.html

实现,仿,Win8Metro,风格,的,按钮,交换,和,拖动

鬼火存在,打火机里注射墨水就能实现不信试试

鬼火很多人都知道,也有不少人知道鬼火实际上就是磷火,是磷的自燃现象,那么既然是火燃烧,难道不会烧到一些东西吗?尤其鬼火通常出现在山林当中,许多人听到鬼火就感觉到胆怯,认为这是一些鬼怪制造出来的火焰,因为这些火焰都是漂浮在空中的,看不见燃烧物,,但是并不是这样,鬼火通常都只是磷火而已,甚至可以制造出漂浮在空中的火焰。

鬼火为何会追着人跑既然刚才提到了鬼火会追着人跑,这本来也是正常的现象。

如果在没有风的时候,空气是静止不动的,磷火自然也不会动,人经过时鬼火追着人跑是因为磷火的重量非常轻,人经过时会带动空气的流动,从而使得磷火随着空气流动而飘动。

鬼火是真实存在的1.一般我们将漂浮在空中的火焰就会称之为鬼火,因为这种现象经常会发生在坟地旁边,所以不少人都觉得这是死去的人变成鬼魂之后导致的,本来并不是这样。

引起鬼火的真相本来是磷这种元素,磷的燃点非常低,漂浮在空中的磷燃烧起来就像看鬼火了,没有燃烧物,而且火焰还是蓝色的。

2.因为历史,无论是中国还其他一些国家,都是流行的土葬,土葬的时候就会将死者的遗体直接放入棺材然后埋进土里。

因为人体的骨骼中有很多磷酸钙,尸体腐烂之后,这些磷就会转变为磷化氢,变成一种燃点气体,很容易自燃,因此就会产生鬼火这种自然现象了,如果遇到鬼火就狂奔,可能鬼火还会跟着自己跑,有时候确实有点吓人。

3.确实想要漂浮在空中的火焰是可以制作出来的,用打火机和墨水就可以,不过不推荐大家在家里制作,看看就好了。

就像上面视频描述的一样,先将打火机的盖子卸下来,然后往打火机里注入墨水,然后盖上盖子就可以了。

这个时候打火机打出来的火就会漂浮在空中,而不是从打火机口里喷出的火,看起来非常的奇怪。

4.不过这种方法对打火机是有一定要求的,必须要磨石打火机才可以,普通的按压打火机是不可以的。

而且这种做法的风险很高,毕竟是打火机,是易燃易爆物品,因此不推荐大家在家里直接尝试,万一打火机质量不可以,打不出来火都还要,如果爆炸了,甚至会对手部造成一定影响,因此看看就好,不要自己动手尝试。

鬼火会引起火灾吗鬼火实际上是不会引起火灾的,我们知道鬼火是因为磷聚集多了,在遇到氧气之后产生的自燃现象,但本来磷火的温度很低,而且一会儿就没了,所以并不会引起火灾。

而且很多人知道鬼火有很多颜色,所以鬼火本来并不是燃烧的结果,而是一种化学发光的现象,磷在和氧气进行化学反应燃烧的过程当中,其释放出来的并不是热量,而是可见光,所以磷火,也就是鬼火,并不会引起火灾。

磷火的温度会烧伤人吗关于鬼火,很多人也知道鬼火会追着人跑,如果人碰着了鬼火,那么人会被烧伤吗?这本来也是不会的,因为磷化氢在空气当中的浓度并不高,在磷化氢和氧气发生反应燃烧的时候,其产生的热量非常的少,都是以光的形式释放,所以既不会引起火灾,也不会烧伤人。

海上航行的水手们有时在晚间会看到他们驾驶的船只桅杆顶端发出一种灵异的蓝色辉光。

这种光不具有高温,也不会引起火灾,人们将它视作一种好运的征兆...查看细节 以上就是关于鬼火真的存在,打火机里注射墨水就能实现不信试试的全部内容,

巧妙用PS后期 模仿川内伦子作品的光感效果教程

川内伦子Rinko Kawauchi,1972年出生在日本的女生。

1993年,毕业于Seian Women s College,2004年以Aila摄影作品出名,在美国、日本艺廊展出,前后发表过很多个展,更获得2002年第27回木村伊兵卫写真奖,擅长用66的方画幅展现日常生活中的细微事物,而这些细微特写似乎都笼罩在一层朦胧的薄膜之中,色调柔和得接近惨白。

川内伦子将日常生活用柔和地色调细微地表现出来,她的作品意在表现特有的质朴忧郁和韧性,有种抓人的魅力,这种魅力不是从第一眼就把你牢牢抓住那种,但在连续看过大量她的作品以后,你不会审美疲劳,倒有些意犹未尽。

"淡淡的"是她形式操作很重要的一环,这种淡色调下面却藏着意想不到的冲击力,用“低色调高能量”来形容比较合适。

她的图片就像是"轻薄的假象"透着淡淡迷人的幽雅。

因为这层薄雾包藏着"祸心",让人沉溺在轻柔且淡雅的氛围裡,而事后上演的,却是一幕幕惊悚的恐怖片。

这也只是她较为深层的观察能力。

最精彩的部分还在于她成功地展现出了日本两个不同端点的极致文化氛围。

被川内的照片据说是用胶片拍的,迷住了很多内心柔软的人,那么数码照片能通过后期调出这种光感么? 下面来看看知乎后期大师叶明的分析。

这个问题非常之好,值得一答。

首先让我们回顾一下以前的知识: 当我们复制原图,使用高斯模糊,然后把混合模式改为滤色时,会产生发光效果。

原因我在《从后期到后期》里面有讲: 好的,我们来实验一下: 更多Adobe Photoshop CS5教程,尽在photoshop http://www.gezila.com/special/photoshoprj 巧,妙用,后期,模仿,川,内伦,子,作品,的,光感,

加入收藏
               

实现仿Win8Metro风格的按钮交换和拖动删除功能

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录