DuiLib : 解决CListUI先建立,然后隐藏, 需要的时候再显示填充内容时,不显示或显示为灰的问题.

在项目中遇到一个 CListUI的显示问题.

* 先建立一个CListUI, 因为暂时符合显示条件,不允许显示, 先隐藏.

        /// create dlg have a LitUI
        if (NULL == m_pDlgHaveListUI)
        {
            m_pDlgHaveListUI = new CDlgHaveListUI(XML_FILE_NAME_DlgHaveListUI, WND_CLASS_NAME_DlgHaveListUI);
            if (NULL == m_pDlgHaveListUI)
                break;

            m_pDlgHaveListUI->SetOwner(this);
            m_pDlgHaveListUI->Create(this->GetHWND(), WND_DISP_NAME_DlgHaveListUI, UI_WNDSTYLE_CHILD, WS_EX_WINDOWEDGE);
            UiInit_List(); ///< initial m_pDlgHaveListUI's ListUI
            m_pDlgHaveListUI->ShowWindow(false, false); ///< 不符合显示条件,先隐藏.
            AddSubDlgOnMainDlg(m_pDlgHaveListUI); ///< 将new出来的DuiLib对象放入List, delete时用
        }
        

等用到时,将LitUI显示出来, 再填充数据, 发现有的时候显示为灰色, 需要变化一下ListUI's size, 才能显示LitUI内容才能出来.

就等于是 : 必须要使ListUI抖一下, size变了才刷新成正常显示.


最后,我改了DuiLib库来解决这个问题. 在 CListUI::SetPos 中调用 NeedUpdate(), 就能达到不变化size, 进行刷新ListUI的目的.

修改后的UIList.h

class UILIB_API CListUI : public CVerticalLayoutUI, public IListUI
{
public:
    CListUI();

    LPCTSTR GetClassName() const;
    UINT GetControlFlags() const;
    LPVOID GetInterface(LPCTSTR pstrName);

    bool GetScrollSelect();
    void SetScrollSelect(bool bScrollSelect);
    
    int GetCurSel() const;
    void SetCurSel(int iSel);

    bool SelectItem(int iIndex, bool bTakeFocus = false);

    CListHeaderUI* GetHeader() const;  
    CContainerUI* GetList() const;
    TListInfoUI* GetListInfo();

    CControlUI* GetItemAt(int iIndex) const;
    int GetItemIndex(CControlUI* pControl) const;
    bool SetItemIndex(CControlUI* pControl, int iIndex);
    int GetCount() const;
    bool Add(CControlUI* pControl);
    bool AddAt(CControlUI* pControl, int iIndex);
    bool Remove(CControlUI* pControl);
    bool RemoveAt(int iIndex);
    void RemoveAll();

    void EnsureVisible(int iIndex);
    void Scroll(int dx, int dy);

    int GetChildPadding() const;
    void SetChildPadding(int iPadding);

    void SetItemFont(int index);
    void SetItemTextStyle(UINT uStyle);
    void SetItemTextPadding(RECT rc);
    void SetItemTextColor(DWORD dwTextColor);
    void SetItemBkColor(DWORD dwBkColor);
    void SetItemBkImage(LPCTSTR pStrImage);
    void SetAlternateBk(bool bAlternateBk);
    void SetSelectedItemTextColor(DWORD dwTextColor);
    void SetSelectedItemBkColor(DWORD dwBkColor);
    void SetSelectedItemImage(LPCTSTR pStrImage); 
    void SetHotItemTextColor(DWORD dwTextColor);
    void SetHotItemBkColor(DWORD dwBkColor);
    void SetHotItemImage(LPCTSTR pStrImage);
    void SetDisabledItemTextColor(DWORD dwTextColor);
    void SetDisabledItemBkColor(DWORD dwBkColor);
    void SetDisabledItemImage(LPCTSTR pStrImage);
    void SetItemLineColor(DWORD dwLineColor);
    bool IsItemShowHtml();
    void SetItemShowHtml(bool bShowHtml = true);
	RECT GetItemTextPadding() const;
	DWORD GetItemTextColor() const;
	DWORD GetItemBkColor() const;
	LPCTSTR GetItemBkImage() const;
    bool IsAlternateBk() const;
	DWORD GetSelectedItemTextColor() const;
	DWORD GetSelectedItemBkColor() const;
	LPCTSTR GetSelectedItemImage() const;
	DWORD GetHotItemTextColor() const;
	DWORD GetHotItemBkColor() const;
	LPCTSTR GetHotItemImage() const;
	DWORD GetDisabledItemTextColor() const;
	DWORD GetDisabledItemBkColor() const;
	LPCTSTR GetDisabledItemImage() const;
	DWORD GetItemLineColor() const;

    void SetMultiExpanding(bool bMultiExpandable); 
    int GetExpandedItem() const;
    bool ExpandItem(int iIndex, bool bExpand = true);

    void SetPos(RECT rc);

    BOOL rect_compare(const RECT& rtDst, const RECT& rtSrc);
    void rect_copy(RECT& rtDst, const RECT& rtSrc);

    virtual BOOL DoEvent(TEventUI& event);
    void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);

    IListCallbackUI* GetTextCallback() const;
    void SetTextCallback(IListCallbackUI* pCallback);

    SIZE GetScrollPos() const;
    SIZE GetScrollRange() const;
    void SetScrollPos(SIZE szPos);
    void LineUp();
    void LineDown();
    void PageUp();
    void PageDown();
    void HomeUp();
    void EndDown();
    void LineLeft();
    void LineRight();
    void PageLeft();
    void PageRight();
    void HomeLeft();
    void EndRight();
    void EnableScrollBar(bool bEnableVertical = true, bool bEnableHorizontal = false);
    virtual CScrollBarUI* GetVerticalScrollBar() const;
    virtual CScrollBarUI* GetHorizontalScrollBar() const;
    BOOL SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData);
protected:
    bool m_bScrollSelect;
    int m_iCurSelect;
    int m_iExpandedItem;
    IListCallbackUI* m_pCallback;
    CListBodyUI* m_pList;
    CListHeaderUI* m_pHeader;
    TListInfoUI m_ListInfo;

    /// 我们会在SetPos中, 调用NeedUpdate
    /// 为了防止递归调用, 如果 SetPos's rc != m_rcLastSetPos, 就调用一次NeedUpdate来刷新UI
    /// 用来解决ListUI由隐藏变到显示时,设置了UI行元素,不显示或显示为灰的问题.
    RECT        m_rcLastSetPos; ///< 最后一次设置的Pos
};

修改后的UIList.cpp

namespace DuiLib
{
    CListUI::CListUI() : 
    m_pCallback(NULL), 
    m_bScrollSelect(false), 
    m_iCurSelect(-1), 
    m_iExpandedItem(-1)
{
    ::ZeroMemory(&m_rcLastSetPos, sizeof(RECT));

BOOL CListUI::rect_compare(const RECT& rtDst, const RECT& rtSrc)
{
    BOOL        bRc = FALSE;

    do 
    {
        if (rtSrc.left != rtDst.left)
            break;

        if (rtSrc.top != rtDst.top)
            break;

        if (rtSrc.right != rtDst.right)
            break;

        if (rtSrc.bottom != rtDst.bottom)
            break;

        bRc = TRUE;
    } while (0);

    return bRc;
}

void CListUI::rect_copy(RECT& rtDst, const RECT& rtSrc)
{
    rtDst.left      = rtSrc.left;
    rtDst.top       = rtSrc.top;
    rtDst.right     = rtSrc.right;
    rtDst.bottom    = rtSrc.bottom;
}

void CListUI::SetPos(RECT rc)
{
    CVerticalLayoutUI::SetPos(rc);
    if( m_pHeader == NULL )
        return;

    if (rect_compare(m_rcLastSetPos, rc))
        return;
    else
    {
        rect_copy(m_rcLastSetPos, rc);
    }

    // Determine general list information and the size of header columns
    m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
    // The header/columns may or may not be visible at runtime. In either case
    // we should determine the correct dimensions...

    if( !m_pHeader->IsVisible() ) 
    {
        for( int it = 0; it < m_pHeader->GetCount(); it++ ) 
        {
            static_cast(m_pHeader->GetItemAt(it))->SetInternVisible(true);
        }

        m_pHeader->SetPos(CDuiRect(rc.left, 0, rc.right, 0));
    }

    int iOffset = m_pList->GetScrollPos().cx;
    for( int i = 0; i < m_ListInfo.nColumns; i++ ) 
    {
        CControlUI* pControl = static_cast(m_pHeader->GetItemAt(i));
        if( !pControl->IsVisible() )
            continue;

        if( pControl->IsFloat() ) 
            continue;

        RECT rcPos = pControl->GetPos();
        if( iOffset > 0 ) 
        {
            rcPos.left -= iOffset;
            rcPos.right -= iOffset;
            pControl->SetPos(rcPos);
        }
        m_ListInfo.rcColumn[i] = pControl->GetPos();
    }

    if( !m_pHeader->IsVisible() ) 
    {
        for( int it = 0; it < m_pHeader->GetCount(); it++ ) 
        {
            static_cast(m_pHeader->GetItemAt(it))->SetInternVisible(false);
        }
    }

    NeedUpdate();
}

<2015-0311>

这几天发现,上述的修改导致拖动ListUI题头时, List's Body不随动.

想了一下, NeedUpdate()的条件判断应放在函数最后面。修改后好了.

void CListUI::SetPos(RECT rc)
{
    CVerticalLayoutUI::SetPos(rc);
    if( m_pHeader == NULL )
        return;

    // Determine general list information and the size of header columns
    m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
    // The header/columns may or may not be visible at runtime. In either case
    // we should determine the correct dimensions...

    if( !m_pHeader->IsVisible() ) 
    {
        for( int it = 0; it < m_pHeader->GetCount(); it++ ) 
        {
            static_cast(m_pHeader->GetItemAt(it))->SetInternVisible(true);
        }

        m_pHeader->SetPos(CDuiRect(rc.left, 0, rc.right, 0));
    }

    int iOffset = m_pList->GetScrollPos().cx;
    for( int i = 0; i < m_ListInfo.nColumns; i++ ) 
    {
        CControlUI* pControl = static_cast(m_pHeader->GetItemAt(i));
        if( !pControl->IsVisible() )
            continue;

        if( pControl->IsFloat() ) 
            continue;

        RECT rcPos = pControl->GetPos();
        if( iOffset > 0 ) 
        {
            rcPos.left -= iOffset;
            rcPos.right -= iOffset;
            pControl->SetPos(rcPos);
        }
        m_ListInfo.rcColumn[i] = pControl->GetPos();
    }

    if( !m_pHeader->IsVisible() ) 
    {
        for( int it = 0; it < m_pHeader->GetCount(); it++ ) 
        {
            static_cast(m_pHeader->GetItemAt(it))->SetInternVisible(false);
        }
    }

    /// 如果size变了, 刷一下
    /// 用来解决 hide => show 时, ListUI不显示或为灰色
    if (!rect_compare(m_rcLastSetPos, rc))
    {
        rect_copy(m_rcLastSetPos, rc);
        NeedUpdate();
    }
}




你可能感兴趣的:(DuiLib : 解决CListUI先建立,然后隐藏, 需要的时候再显示填充内容时,不显示或显示为灰的问题.)