设为首页 收藏本站
查看: 1528|回复: 0

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

[复制链接]

尚未签到

发表于 2015-5-20 11:24:15 | 显示全部楼层 |阅读模式
    上一篇文章写了如何进行页面滑动切换,今天我讲一下如何实现两个按钮拖动交换位置,包括同一个页面按钮交换或者两个页面之间的按钮交换。另外就是如何拖动删除界面上的快捷方式。按钮交换和拖动删除,这两个功能基本上是现在智能手机的标准功能,不管是IOS或者Android都有类似功能。我实现的功能,主要是参考Android的功能实现。
  下面这个就是动态交换按钮效果图:
DSC0000.gif
  
  还是先把逻辑关系图放出来:
DSC0001.jpg
  
  1、按钮拖动
  怎么样才能实现拖动一个按钮到另外一个按钮位置上,实现交换?这个首先一个需要做的就是拖动按钮的操作。按钮拖动我放到封装的DUIButton里面实现。下面我们看看DUIButton里面如何把按钮拖动出来。




//Edited by mythou
//http://www.iyunv.com/mythou/

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;
}
//http://www.iyunv.com/mythou/p/3172707.html Edited by mythou
    从这里可以发现,其实拖动一个按钮,就是把该按钮的图片,跟随手指的移动而动态贴图。需要注意的是如何才能保证拖动的流畅性。这个需要把你的背景图做成缓存,保留下来,拖动过程中,都是使用缓存中原始的背景图。这样每次拖动,只需要绘画一个按钮的图片,才能流畅得拖动按钮。
    另外你手指点击按钮还需要做一些条件判断,需要符合条件的情况下,才能拖动按钮。我这里把手指触摸按钮分为3种行为:


  • 点击按钮,打开某个程序
  • 触摸按钮,滑动切换页面
  • 把按钮拖动出来,执行交换、删除、添加操作
  这几个也是目前智能机系统一般都支持的手势操作,上面我们按钮的拖动,就是属于第三种情况。
  
   2、按钮交换
  把按钮拖动出来,然后拖动到需要交换的按钮的位置,释放按钮,执行交换操作。这个就是交换的流程,这里根据释放的位置来识别到底跟哪一个按钮进行交换。


//Edited by mythou
//http://www.iyunv.com/mythou/

   //大按钮移动到大按钮位置 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);
}

//http://www.iyunv.com/mythou/p/3172707.html Edited by mythou
    这是一个简单的交换逻辑,因为我们的按钮都是存放在Page类里面的二维Vector向量里面,按钮交换位置也就是交换Vector里面的值。因为Vector里面存放只是按钮对象的指针应用。因此,Vector交换两个指针也不会存在负责的数据交互。当然如果要做出比较好的交换效果,我们免不了使用动画,交换过程中。我们加入一个动画效果,我这里做的是一个淡入淡出的效果,主要控制按钮图片的Alpha值,形成一个较好的交换效果。最后还需要把交换的位置信息记录到文件里面,方便下次启动程序的时候,保存交换后的效果。需要注意的是交换按钮刷新和动画效果之间的操作。要做到流程,考虑使用一个线程运行动画。
  
   3、拖动删除按钮
    这个功能其实就是参照Android的删除快捷方式做的。当按钮被拉动出来后,界面上方会出现一个有垃圾桶图标的区域,把按钮拖动到该区域释放,就可以把相对的快捷方式删除。下面我们看看逻辑上如何实现。


//Edited by mythou
//http://www.iyunv.com/mythou/

//在删除区域释放,删除按钮
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;
}

//http://www.iyunv.com/mythou/p/3172707.html Edited by mythou
    删除操作在逻辑上也很简单,就是删除我们记录的Vector里面的相对应的按钮指针。不过删除后,我们需要做一些额外的操作。第一需要填充一个空按钮指针到原来的位置。这个操作主要是用来记录界面上哪些位置是可以存放按钮和交换按钮。空按钮是一个空类,只有一个标记用来记录位置。删除后还需要针对按钮的类型做不同的添加操作,大按钮和小按钮。。最后还需要在配置文件做记录,记录哪个按钮删除了。如果需要一个好的效果,可以类似交换按钮一样,加入一个动画效果。
  
  4、添加快捷方式栏
  这是额外做的一个功能,主要是把常用的功能加入到一个导航栏上面,可以在任何界面使用相关常用功能。




//Edited by mythou
//http://www.iyunv.com/mythou/

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;
}

//http://www.iyunv.com/mythou/p/3172707.html Edited by mythou
    因为我的快捷栏是另外一个独立程序,所以这里把需要添加的按钮拉动到界面底部,然后把按钮的相关数据转换为相关数据包,发送到快捷栏程序里面。这里也需要加入相关的动画效果,才能达到较好的界面交互效果。剩下的就是另外一个程序处理发送过来的数据包。解析然后显示出来就好了。
    今天主要是讲解界面上常用的交换按钮、删除按钮、添加快捷栏等操作。其中交换按钮这里只是把同页面的交换做了解说,除了同页面交换外,也需要做到不同页面之间交换,这个原理是一样,只是不同页面之间交换需要做到逻辑页面的切换。这个也是我做了Page类作为页面管理类的原因。不同类之间交换按钮,只要切换Page类就好了。。。
  
  Edited by mythou
原创博文,转载请标明出处:http://www.iyunv.com/mythou/p/3172707.html

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-68858-1-1.html 上篇帖子: win8快捷键大全分享,非常全 下篇帖子: 一起学习win8应用1-构建我们的第一个应用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表