乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      duilib進階教程 -- 改進List控件 (轉)

       3D建模仿真 2014-01-17

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

      類似這樣的效果:


      1 首先改進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 要設置 float="true" pos="5,0,0,0" 兩個屬性


      2 改進CListContainerElementUI

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


      源碼中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>


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

      后來在以下三個方向進行了探索:

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

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

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

      2 重寫DoPaint函數(shù)

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

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

      3 重寫SetPos函數(shù)

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


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

      上代碼


      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)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多