一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

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

 3D建模仿真 2014-01-17

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

類似這樣的效果:


1 首先改進(jìn)CListHeaderItemUI

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

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

另外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" 兩個(gè)屬性


2 改進(jìn)CListContainerElementUI

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


源碼中void CListContainerElementUI::DrawItemText(HDC hDC, const RECT& rcItem) 這個(gè)方法直接return了。需要實(shí)現(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下面的一級(jí)子控件為每一列的容器,也可以不是容器,但如果此列包含多個(gè)控件,就必須是個(gè)容器,可參考如下寫法:

<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á)到了項(xiàng)目要求,可后來(lái)發(fā)現(xiàn)誘發(fā)了其他的問(wèn)題,如滾動(dòng)條部分功能失效,還有程序在運(yùn)行一段時(shí)間后進(jìn)入了無(wú)響應(yīng)狀態(tài)。

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

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

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

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

2 重寫DoPaint函數(shù)

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

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

3 重寫SetPos函數(shù)

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


       思路:以前兩種方案,仍舊掉在CListTextElementUI實(shí)現(xiàn)思路的坑里。整理思路CListContainerElementUI中的每一列可以是一個(gè)簡(jiǎn)單控件,也可以是一個(gè)容器控件,所以只是在DoPaint里做文章,無(wú)法滿足要求。SetPos既然可以實(shí)現(xiàn)容器控件的位置,寬高的改變,那為什么不重寫SetPos呢,拿來(lái)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子控件放大到整個(gè)客戶區(qū)
}
}
}

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产免费一区二区三区av大片| 久久国产精品熟女一区二区三区| 日本高清一区免费不卡| 美女黄色三级深夜福利| 免费国产成人性生活生活片| 黄色污污在线免费观看| 欧美日韩三区在线观看| 久七久精品视频黄色的| 免费在线播放一区二区| 欧美整片精品日韩综合| 老熟女露脸一二三四区| 视频一区二区 国产精品| 在线观看日韩欧美综合黄片| 精品精品国产欧美在线| 婷婷一区二区三区四区| 99视频精品免费视频播放| 色哟哟哟在线观看视频| 91福利视频日本免费看看| 亚洲免费视频中文字幕在线观看| 超薄丝袜足一区二区三区| 不卡一区二区高清视频| 亚洲a码一区二区三区| 亚洲视频一区二区久久久| 日本高清不卡在线一区| 国产成人精品一区二三区在线观看 | 日韩成人中文字幕在线一区| 91一区国产中文字幕| 五月天综合网五月天综合网| 日韩三极片在线免费播放| 99久久婷婷国产亚洲综合精品| 欧美色欧美亚洲日在线| 国产一区二区三区丝袜不卡| 亚洲丁香婷婷久久一区| 色一情一伦一区二区三| 男人的天堂的视频东京热| 91欧美亚洲精品在线观看| 日韩精品一区二区不卡| 国产成人精品久久二区二区| 欧美美女视频在线免费看| 欧美日韩一区二区综合| 日本欧美一区二区三区在线播|