日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

duilib進(jìn)階教程 -- 改進(jìn)List控件 (轉(zhuǎn))

 3D建模仿真 2014-01-17

前情提要:Duilib源碼中的ListDemo,給我們提供了一個可以左右拖拉h(huán)eaderItem,下面的listitem也跟著變化。但實際工作中,往往HeaderItem和listitem都比較復(fù)雜,不可能只是一個text。這就要求他是個容器,可以放option,button,image等。

類似這樣的效果:


1 首先改進(jìn)CListHeaderItemUI

  原來CListHeaderItemUI繼承的事CControlUI,讓他改成繼承CContainerUI就好了,另外需要重寫void SetPos(RECT rc);否則其子控件的有效作用范圍給headerItem的大小,拖拉的觸發(fā)事件失效。

void SetPos(RECT rc); 參考void CHorizontalLayoutUI::SetPos(RECT rc) 拷貝過來就可以了。

另外xml中的寫法有變化

<ListHeader height="30" menu="true">
<ListHeaderItem text="" font="1" width="60" hotimage="file='list_bg.png' source='1,0,2,58'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sepline.png'" sepwidth="5">
<Option float="true" pos="5,0,0,0" width="50" height="30" name="OptionOfListApplication" normalimage="file='checkbox.png' dest='23,8,37,22' source='0,0,14,14'" hotimage="file='checkbox.png' dest='23,8,37,22' source='14,0,28,14'" pushedimage="file='checkbox.png' dest='23,8,37,22' source='28,0,42,14'" disabledimage="file='checkbox.png' dest='23,8,37,22' source='42,0,56,14'" hottextcolor="#FF007AFF" selectedforeimage="file='check.png' dest='23,8,37,22'"/>
</ListHeaderItem>
<ListHeaderItem text="Domain" font="1" width="260" hotimage="file='list_bg.png' source='1,0,2,58'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sepline.png'" sepwidth="1">
</ListHeaderItem>
<ListHeaderItem text="Description" font="1" width="240" hotimage="file='list_bg.png' source='1,0,2,58'" pushedimage="file='list_header_pushed.png'" sepimage="file='list_header_sepline.png'" sepwidth="1">
</ListHeaderItem>
</ListHeader>

注意Option 要設(shè)置 float="true" pos="5,0,0,0" 兩個屬性


2 改進(jìn)CListContainerElementUI

雖然他是個容器,但他對headeritem的拖拉無響應(yīng),不能隨之改變。


源碼中void CListContainerElementUI::DrawItemText(HDC hDC, const RECT& rcItem) 這個方法直接return了。需要實現(xiàn)。


void CListContainerElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
{


if( m_pOwner == NULL ) return;
    TListInfoUI* pInfo = m_pOwner->GetListInfo();
    DWORD iTextColor = pInfo->dwTextColor;


    if( (m_uButtonState & UISTATE_HOT) != 0 ) {
        iTextColor = pInfo->dwHotTextColor;
    }
    if( IsSelected() ) {
        iTextColor = pInfo->dwSelectedTextColor;
    }
    if( !IsEnabled() ) {
        iTextColor = pInfo->dwDisabledTextColor;
    }


    for( int i = 0; i < pInfo->nColumns; i++ )
    {
        RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom };
        rcItem.left += pInfo->rcTextPadding.left;
        rcItem.right -= pInfo->rcTextPadding.right;
        rcItem.top += pInfo->rcTextPadding.top;
        rcItem.bottom -= pInfo->rcTextPadding.bottom;


CControlUI* pControl = GetItemAt(i);
pControl->SetPos(rcItem);
    }
}


而且需要在DoPaint中調(diào)用

void CListContainerElementUI::DoPaint(HDC hDC, const RECT& rcPaint)
{
    if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return;

DrawItemText(hDC, m_rcItem);


    DrawItemBk(hDC, m_rcItem);
    CContainerUI::DoPaint(hDC, rcPaint);
}


另外xml的寫法有所改變,不能像以前那樣隨便寫了,CListContainerElementUI下面的一級子控件為每一列的容器,也可以不是容器,但如果此列包含多個控件,就必須是個容器,可參考如下寫法:

<ListContainerElement  height="58">
<HorizontalLayout float="true" pos="0,0,60,58">
<Option float="true" pos="5,0,0,0" width="50" height="30" name="OptionOfListApplication" normalimage="file='checkbox.png' dest='23,8,37,22' source='0,0,14,14'" hotimage="file='checkbox.png' dest='23,8,37,22' source='14,0,28,14'" pushedimage="file='checkbox.png' dest='23,8,37,22' source='28,0,42,14'" disabledimage="file='checkbox.png' dest='23,8,37,22' source='42,0,56,14'" hottextcolor="#FF007AFF" selectedforeimage="file='check.png' dest='23,8,37,22'"/>
</HorizontalLayout>
<Label float="true" pos="60,0,320,58" name="docsize" text="2222" align="center" textcolor="#FF333333"  width="260"/>
<Label float="true" pos="320,0,560,58" name="appversion" text="3333" align="center" textcolor="#FF333333"  />
</ListContainerElement>


上篇博客寫完,以為改進(jìn)List達(dá)到了項目要求,可后來發(fā)現(xiàn)誘發(fā)了其他的問題,如滾動條部分功能失效,還有程序在運行一段時間后進(jìn)入了無響應(yīng)狀態(tài)。

后來在以下三個方向進(jìn)行了探索:

1 主要改進(jìn)還是在DrawItemText 函數(shù)中,試圖解決由此引起的Bug

結(jié)果:不能解決掉,但證明duilib是可以實現(xiàn)的,只是思路和方法還沒有找對。

       DrawItemText 本來的作用是重繪Text文本,在這里調(diào)用setpos,會引起其父控件重繪,父控件重繪又會調(diào)用DoPaint,有循環(huán)調(diào)用,程序很容易崩掉。思路不對。

2 重寫DoPaint函數(shù)

結(jié)果:只能對其一級子控件進(jìn)行背景,文本的重繪,沒有誘發(fā)其他Bug ,但很難實現(xiàn)一級子控件及它的子控件一起重繪。

        思路: 由于CListContainerElementUI繼承于CContainerUI,原來只是在最后調(diào)用了父類的DoPaint,根據(jù)CContainerUI::DoPaint(hDC, rcPaint);源碼進(jìn)行修改,每列的寬度可以得到,所以子控件的可以根據(jù)頭部的寬度重繪。

3 重寫SetPos函數(shù)

結(jié)果:這次終于完美解決,上張圖,呵呵!


       思路:以前兩種方案,仍舊掉在CListTextElementUI實現(xiàn)思路的坑里。整理思路CListContainerElementUI中的每一列可以是一個簡單控件,也可以是一個容器控件,所以只是在DoPaint里做文章,無法滿足要求。SetPos既然可以實現(xiàn)容器控件的位置,寬高的改變,那為什么不重寫SetPos呢,拿來CContainerUI的SetPos,進(jìn)行重寫。

上代碼


void CListContainerElementUI::SetPos(RECT rc)
{
if( m_pOwner == NULL ) return;
TListInfoUI* pInfo = m_pOwner->GetListInfo();
int iChangeIndex=0;
LONG cx = 0;
for( int i = 0; i < pInfo->nColumns; i++ )
{
CControlUI* pControl = GetItemAt(i);
if(!pControl) break;
RECT rcOldItem = pControl->GetPos();
if(pInfo->rcColumn[i].right-rcOldItem.right!=0){
iChangeIndex =i;
cx=pInfo->rcColumn[i].right-rcOldItem.right;
break;

}


}
RECT rcNew = {rc.left,rc.top,rc.right+cx,rc.bottom};
CControlUI::SetPos(rcNew);
if( m_items.IsEmpty() ) return;
rcNew.left += m_rcInset.left;
rcNew.top += m_rcInset.top;
rcNew.right -= m_rcInset.right;
rcNew.bottom -= m_rcInset.bottom;


for( int it = 0; it < m_items.GetSize(); it++ ) {
CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
if( !pControl->IsVisible() ) continue;
if( pControl->IsFloat() ) {
if(it>=iChangeIndex){
RECT rcItem = { pInfo->rcColumn[it].left, m_rcItem.top, pInfo->rcColumn[it].right, m_rcItem.bottom };
pControl->SetPos(rcItem);
}
}
else {
pControl->SetPos(rcNew); // 所有非float子控件放大到整個客戶區(qū)
}
}
}

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多