实现仿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,风格,的,按钮,交换,和,拖动

斯鲁伊斯海战后 法国入侵英国的野心都没有机会实现

斯鲁伊斯海战发生在公元1340年,为拉开了序幕。

这场英法之间的战争发生在斯鲁伊斯,现位于比利时和荷兰之间。

参与斯鲁伊斯海战的法国舰队在爱德华三世给儿子的信中有所提及。

斯鲁伊斯海战图片 这支舰队总共有一百九十艘战船,还有一部分热那亚佣军,总数为两万人。

英国历史一直声称英国舰队不管是人员还是船只数量都大大少于法国舰队。

但当英国舰队航时,一共有两百艘战船。

在半路中,一支拥有五十艘船的舰队又加入了英国海军。

在这支舰队中,大部分人员没有经过训练。

英国舰队的船只数量在两外五十艘左右,士兵约有两万人。

法国国王将舰队分成三路,并用铁链将船只连起来。

英国舰队抵达海湾时,因为逆光逆流的缘故,停船等待时机。

流向改变后,英国舰队占领占地,开始射击。

法国舰队机动性较差,没有弓箭手和盔甲,受到了英国舰队的欺负。

经过八小时的激战,法国舰队被击败,再无斗志,四下逃窜。

法国舰队惨败,损失战船近一百八十艘,牺牲了近两万名士兵。

法国舰队的两个指挥官,一个战死沙场,一个回国被处以绞刑。

英国舰队在这次战争中伤亡了四千人,数量远远小于法国。

斯鲁伊斯海战也被称为斯勒伊斯海战。

在这场海战中,法国遭受了巨大的打击,法国入侵英国的野心没有机会实现。

这就是斯鲁伊斯海战简介。

斯鲁伊斯海战结果 斯鲁伊斯海战结果是英国取得了最后的胜利。

在这场战役中,法国舰队付出了惨烈的代价。

英国历载,英国舰队花费了很少的代价就打败了法国,并歼敌两万人。

这个数据可能不太正确。

斯鲁伊斯海战结束后,英国舰队停止了行动,这显示出了当时的英国也遭到了一部分损失,需要原地休整。

斯鲁伊斯海战图片 英国得到了这次战役的胜利,从此强大的英国海军以绝对的优势掌握了英吉利海峡。

法国舰队惨败,损失了一百八十艘战船。

法国舰队两个指挥官最终都在劫难逃,只有雇佣军的首领逃脱一劫。

英国在与法国的海战中首战告捷,为日后进犯法国创造了先决条件。

法国舰队再也不能跨入英吉利海峡作战,此后绝大多数英法之间的战争到在法国本土发生。

双方在军乐声中交战。

在开展前,爱德华曾经从临近的城镇中召集拥护他的人前来主战。

按照英国史学家的记载,那些人全部到达,乘着小船从后面偷袭法军。

法国舰队指挥见大势已去,率领船队逃亡公海,躲过了屠杀。

第一列战队战败后,法军放弃了所有希望。

第二、三列人员纷纷逃亡。

可是船只被铁链连在一起,许多都挤翻了。

按爱德华的口述,直至深夜,法国的舰队全被全部歼灭。

斯鲁伊斯战争结束后,爱德华设宴庆祝。

三百名神父在圣母大教堂举行了盛大的弥撒。

斯鲁伊斯战役从战术上来看,是英国海军空前的胜利,在下一代英国都保有制海权。

这就是斯鲁伊斯海战结果。

随机文章淫欲魔王阿斯莫德,诱骗俊美人类关至第二层地狱(至上四柱之一)近期太平洋火山地震连发,两天发生两次地震一次火山爆发(活跃期)被加蓬蝰蛇咬了有救吗,有救/但被咬的部位100%会被截肢挪威NSM精确制导导弹,曾受到F35青睐(制导方式奇特)揭秘河南洛阳盗墓大案,疯狂盗墓贼用火药炸开皇后陵盗掘国宝

便携式电脑读卡器,轻松实现数据传输

专业的在线重装系统软件 全新设计 / 全新代码编写 / 全新支持所有机型 全新支持Window 11 安装 简介:便携式电脑读卡器,轻松实现数据传输。

现代社会,数据传输已经成为人们生活中不可或缺的一部分。

然而,传输数据的过程常常会遇到一些困难,比如电脑和手机之间的连接问题,或者是数据线太短无法满足需求等等。

为了解决这些问题,便携式电脑读卡器应运而生。

它不仅可以轻松实现电脑和手机之间的数据传输,还具有便携性强、操作简单等优点,为人们的生活带来了极大的便利。

工具原料:品牌型号:SanDisk Ultra Dual Drive m3.0操作系统版本:Windows 10软件版本:SanDisk Memory Zone一、便携性强1、小巧轻便:便携式电脑读卡器体积小巧,重量轻,方便携带。

2、无需电源:便携式电脑读卡器通过USB接口供电,无需外接电源,使用更加方便。

二、操作简单1、插入读卡器:将便携式电脑读卡器插入电脑的USB接口。

2、连接手机:将手机通过数据线连接到读卡器的另一端。

3、传输数据:打开SanDisk Memory Zone软件,选择要传输的文件,点击传输按钮即可完成数据传输。

三、高速传输1、USB 3.0接口:便携式电脑读卡器采用USB 3.0接口,传输速度更快,节省时间。

2、支持多种格式:便携式电脑读卡器支持多种格式的文件传输,包括照片、视频、音乐等。

总结:便携式电脑读卡器是一种非常实用的工具,它可以轻松实现电脑和手机之间的数据传输,具有便携性强、操作简单、高速传输等优点。

在现代社会中,数据传输已经成为人们生活中不可或缺的一部分,便携式电脑读卡器的出现为人们的生活带来了极大的便利。

未来,随着科技的不断发展,便携式电脑读卡器可能会进一步提升传输速度,支持更多的文件格式,为人们的数据传输提供更加便捷的解决方案。

加入收藏
               

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

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录