西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)其它知識(shí) → 實(shí)現(xiàn)仿Win8 Metro風(fēng)格的按鈕交換和拖動(dòng)刪除功能

實(shí)現(xiàn)仿Win8 Metro風(fēng)格的按鈕交換和拖動(dòng)刪除功能

前往專題相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:mythou時(shí)間:2013/7/7 1:54:51字體大。A-A+

作者:mythou點(diǎn)擊:123次評(píng)論:1次標(biāo)簽: Metro

  • 類型:桌面工具大。6.6M語言:英文 評(píng)分:7.5
  • 標(biāo)簽:
立即下載

仿Win8 Metro風(fēng)格如何實(shí)現(xiàn)兩個(gè)按鈕拖動(dòng)交換位置,包括同一個(gè)頁面按鈕交換或者兩個(gè)頁面之間的按鈕交換。另外就是如何拖動(dòng)刪除界面上的快捷方式。按鈕交換和拖動(dòng)刪除,這兩個(gè)功能基本上是現(xiàn)在智能手機(jī)的標(biāo)準(zhǔn)功能,不管是IOS或者Android都有類似功能。我實(shí)現(xiàn)的功能,主要是參考Android的功能實(shí)現(xiàn)。

下面這個(gè)就是動(dòng)態(tài)交換按鈕效果圖:

還是先把邏輯關(guān)系圖放出來:

1、按鈕拖動(dòng)

怎么樣才能實(shí)現(xiàn)拖動(dòng)一個(gè)按鈕到另外一個(gè)按鈕位置上,實(shí)現(xiàn)交換?這個(gè)首先一個(gè)需要做的就是拖動(dòng)按鈕的操作。按鈕拖動(dòng)我放到封裝的DUIButton里面實(shí)現(xiàn)。下面我們看看DUIButton里面如何把按鈕拖動(dòng)出來。

int CDUIButton::OnMouseMove(POINT point, CDC * pDC, CDC * backDC)
{
//printf("mythou------->enter the Page::omMouseMove");
//判斷拖動(dòng)的條件,按下按鈕并且移動(dòng)的距離大于30像素的時(shí)候,認(rèn)為是拖動(dòng)按鈕
    if( abs(point.x - m_iEndSlide) > 30 || abs(m_clickY - point.y) > 30 || m_mouseMove)//拖動(dòng)快捷鍵
    {
        if(m_ClickState)
        {
            m_mouseMove = TRUE;
            CRect rect = CRect(0, 0, ScreenWidth, ScreenHeight);
 //恢復(fù)保存的背景,主要是提高繪畫效率
            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);
  //根據(jù)用戶手指移動(dòng)的位置,動(dòng)態(tài)刷新按鈕,形成按鈕跟誰手指移動(dòng)的效果
            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;
}

從這里可以發(fā)現(xiàn),其實(shí)拖動(dòng)一個(gè)按鈕,就是把該按鈕的圖片,跟隨手指的移動(dòng)而動(dòng)態(tài)貼圖。需要注意的是如何才能保證拖動(dòng)的流暢性。這個(gè)需要把你的背景圖做成緩存,保留下來,拖動(dòng)過程中,都是使用緩存中原始的背景圖。這樣每次拖動(dòng),只需要繪畫一個(gè)按鈕的圖片,才能流暢得拖動(dòng)按鈕。

另外你手指點(diǎn)擊按鈕還需要做一些條件判斷,需要符合條件的情況下,才能拖動(dòng)按鈕。我這里把手指觸摸按鈕分為3種行為:

點(diǎn)擊按鈕,打開某個(gè)程序

觸摸按鈕,滑動(dòng)切換頁面

把按鈕拖動(dòng)出來,執(zhí)行交換、刪除、添加操作

這幾個(gè)也是目前智能機(jī)系統(tǒng)一般都支持的手勢(shì)操作,上面我們按鈕的拖動(dòng),就是屬于第三種情況。

 2、按鈕交換

把按鈕拖動(dòng)出來,然后拖動(dòng)到需要交換的按鈕的位置,釋放按鈕,執(zhí)行交換操作。這個(gè)就是交換的流程,這里根據(jù)釋放的位置來識(shí)別到底跟哪一個(gè)按鈕進(jìn)行交換。

        //大按鈕移動(dòng)到大按鈕位置 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;

            //動(dòng)畫效果
            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);
        }

這是一個(gè)簡(jiǎn)單的交換邏輯,因?yàn)槲覀兊陌粹o都是存放在Page類里面的二維Vector向量里面,按鈕交換位置也就是交換Vector里面的值。因?yàn)閂ector里面存放只是按鈕對(duì)象的指針應(yīng)用。因此,Vector交換兩個(gè)指針也不會(huì)存在負(fù)責(zé)的數(shù)據(jù)交互。當(dāng)然如果要做出比較好的交換效果,我們免不了使用動(dòng)畫,交換過程中。我們加入一個(gè)動(dòng)畫效果,我這里做的是一個(gè)淡入淡出的效果,主要控制按鈕圖片的Alpha值,形成一個(gè)較好的交換效果。最后還需要把交換的位置信息記錄到文件里面,方便下次啟動(dòng)程序的時(shí)候,保存交換后的效果。需要注意的是交換按鈕刷新和動(dòng)畫效果之間的操作。要做到流程,考慮使用一個(gè)線程運(yùn)行動(dòng)畫。

 3、拖動(dòng)刪除按鈕

這個(gè)功能其實(shí)就是參照Android的刪除快捷方式做的。當(dāng)按鈕被拉動(dòng)出來后,界面上方會(huì)出現(xiàn)一個(gè)有垃圾桶圖標(biāo)的區(qū)域,把按鈕拖動(dòng)到該區(qū)域釋放,就可以把相對(duì)的快捷方式刪除。下面我們看看邏輯上如何實(shí)現(xiàn)。

    //在刪除區(qū)域釋放,刪除按鈕
    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;
    }

刪除操作在邏輯上也很簡(jiǎn)單,就是刪除我們記錄的Vector里面的相對(duì)應(yīng)的按鈕指針。不過刪除后,我們需要做一些額外的操作。第一需要填充一個(gè)空按鈕指針到原來的位置。這個(gè)操作主要是用來記錄界面上哪些位置是可以存放按鈕和交換按鈕?瞻粹o是一個(gè)空類,只有一個(gè)標(biāo)記用來記錄位置。刪除后還需要針對(duì)按鈕的類型做不同的添加操作,大按鈕和小按鈕。。最后還需要在配置文件做記錄,記錄哪個(gè)按鈕刪除了。如果需要一個(gè)好的效果,可以類似交換按鈕一樣,加入一個(gè)動(dòng)畫效果。

4、添加快捷方式欄

這是額外做的一個(gè)功能,主要是把常用的功能加入到一個(gè)導(dǎo)航欄上面,可以在任何界面使用相關(guān)常用功能。

void CDUIPage::Send2TaskBar(CDUIButton *pBtn)
{
    printf("\n mythou-------->Enter Send2TaskBar ********************************\n");
    DUIButtonData *pDuiData = new DUIButtonData();

    //拷貝數(shù)據(jù)
    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;
}

因?yàn)槲业目旖輽谑橇硗庖粋(gè)獨(dú)立程序,所以這里把需要添加的按鈕拉動(dòng)到界面底部,然后把按鈕的相關(guān)數(shù)據(jù)轉(zhuǎn)換為相關(guān)數(shù)據(jù)包,發(fā)送到快捷欄程序里面。這里也需要加入相關(guān)的動(dòng)畫效果,才能達(dá)到較好的界面交互效果。剩下的就是另外一個(gè)程序處理發(fā)送過來的數(shù)據(jù)包。解析然后顯示出來就好了。

今天主要是講解界面上常用的交換按鈕、刪除按鈕、添加快捷欄等操作。其中交換按鈕這里只是把同頁面的交換做了解說,除了同頁面交換外,也需要做到不同頁面之間交換,這個(gè)原理是一樣,只是不同頁面之間交換需要做到邏輯頁面的切換。這個(gè)也是我做了Page類作為頁面管理類的原因。不同類之間交換按鈕,只要切換Page類就好了。。。

轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.cnblogs.com/mythou/p/3172707.html

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(1)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)