CListContainerElementUI 没有实现setpos。而是调用CContainerUI的SetPos(),从而导致了元素排版不正确。如果重写CListContainerElementUI的setpos则会导致CtreeUI的问题。解决方法:
Step One:
新建类CListContainerElementUIEx,来实现setpos。此时虽然排版正确了,但在拖动滚动条时,可能导致排版不正确。
- class UILIB_API CListContainerElementUIEx:public CListContainerElementUI
- {
- public:
- CListContainerElementUIEx();
- virtual void Invalidate();
- virtual void SetPos(RECT rc);
- };
成员实现:
- CListContainerElementUIEx::CListContainerElementUIEx()
- {
-
- }
- void CListContainerElementUIEx::SetPos(RECT rc)
- {
- CContainerUI::SetPos(rc);
-
- rc = m_rcItem;
- rc.left += m_rcInset.left;
- rc.top += m_rcInset.top;
- rc.right -= m_rcInset.right;
- rc.bottom -= m_rcInset.bottom;
-
- TListInfoUI *plistinfo = GetOwner()->GetListInfo();
- SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };
-
- for( int it2 = 0; it2 < m_items.GetSize(); it2++ )
- {
- CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
- if( !pControl->IsVisible() )
- continue;
- if( pControl->IsFloat() )
- {
- SetFloatPos(it2);
- continue;
- }
- RECT rcPadding = pControl->GetPadding();
- SIZE sz = pControl->EstimateSize(szAvailable);
- if( sz.cx == 0 )
- {
- if( sz.cx < pControl->GetMinWidth() )
- sz.cx = pControl->GetMinWidth();
- if( sz.cx > pControl->GetMaxWidth() )
- sz.cx = pControl->GetMaxWidth();
- }
- else
- {
- if( sz.cx < pControl->GetMinWidth() )
- sz.cx = pControl->GetMinWidth();
- if( sz.cx > pControl->GetMaxWidth() )
- sz.cx = pControl->GetMaxWidth();
- }
-
- sz.cy = pControl->GetFixedHeight();
- if( sz.cy == 0 )
- sz.cy = rc.bottom - rc.top - rcPadding.top - rcPadding.bottom;
- if( sz.cy < 0 )
- sz.cy = 0;
- if( sz.cy < pControl->GetMinHeight() )
- sz.cy = pControl->GetMinHeight();
- if( sz.cy > pControl->GetMaxHeight() )
- sz.cy = pControl->GetMaxHeight();
-
-
- RECT rcCtrl = { plistinfo->rcColumn[it2].left + rcPadding.left,
- rc.top + rcPadding.top,
- plistinfo->rcColumn[it2].right + rcPadding.left,
- rc.top + sz.cy + rcPadding.top + rcPadding.bottom };
- pControl->SetPos(rcCtrl);
- }
- }
-
- void CListContainerElementUIEx::Invalidate()
- {
- CListContainerElementUI::Invalidate();
- }
Step two:
在UIDefine.h文件中定义:
#define DUI_CTR_LISTCONTAINERELEMENTEX (_T("ListContainerElementEx"))
在CDialogBuilder的_Parse方法中添加以下代码:
- case 22:
- if( _tcscmp(pstrClass,DUI_CTR_LISTCONTAINERELEMENTEX) == 0 )
- pControl = new CListContainerElementUIEx;
- break;
Step three:
在实现DuiLib::WindowImplBase类中添加以下方法,目的修复滚动条导致的排版不正确:
- LRESULT XOnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT XOnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) ;
(例如CListWnd类):
- class CListWnd :public DuiLib::WindowImplBase, public DuiLib::IListCallbackUI,public DuiLib::IDialogBuilderCallback
- {
- public:
- virtual LPCTSTR GetItemText(DuiLib::CControlUI* pList, int iItem, int iSubItem);
- CListWnd();
- ~CListWnd(void);
- virtual void InitWindow();
- virtual void Notify(DuiLib::TNotifyUI& msg);
- virtual LPCTSTR GetWindowClassName() const;
- //
- virtual DuiLib::CDuiString GetSkinFolder();
- virtual DuiLib::CDuiString GetSkinFile();/**/
- virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
- virtual LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- virtual DuiLib::UILIB_RESOURCETYPE GetResourceType() const;
- DWORD GetBkColor();
- void SetBkColor(DWORD dwBackColor);
- virtual LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- DuiLib::CControlUI* FindControlByName(CString Name);
- DuiLib::CListUI* m_pListUi;
- void OnFinalMessage( HWND hWnd );
- void NeedUpdate();
- /****添加方法***/
- LRESULT XOnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT XOnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) ;
- protected:
- CString m_strSkinFolder;
- CString m_strSkinFile;
- DuiLib::CTreeNodeUI* m_pNodeNeedMove;
- DuiLib::CControlUI* m_pDragingCtrl;
-
- CString WndName;
- };
实现:
- #include "StdAfx.h"
- #include "ListWnd.h"
- #include <list>
-
- struct SkinChangedParam
- {
- DWORD bkcolor;
- DuiLib::CDuiString bgimage;
- };
- const TCHAR* const kBackgroundControlName = _T("bg");
- CListWnd::CListWnd()
- {
-
- }
-
- CListWnd::~CListWnd(void)
- {
- }
-
- LPCTSTR CListWnd::GetItemText(DuiLib::CControlUI* pList, int iItem, int iSubItem)
- {
- return "SSS";
- }
- void CListWnd::InitWindow(){
-
- };
-
-
- void CListWnd::Notify(DuiLib::TNotifyUI& msg){
-
- }
-
- LPCTSTR CListWnd::GetWindowClassName() const
- {
- return _T("CListWnd");
- }
-
- DuiLib::CDuiString CListWnd::GetSkinFolder()
- {
- return (DuiLib::CDuiString)m_strSkinFolder;
- }
-
-
- DuiLib::CDuiString CListWnd::GetSkinFile()
- {
- return m_strSkinFile;
- }
-
-
- LRESULT CListWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- LRESULT Ok=0;
- BOOL bHandled =true;
- if(uMsg ==WM_LBUTTONUP)
- Ok=XOnLButtonUp(uMsg, wParam, lParam, bHandled); /**/
-
- if(uMsg ==WM_MOUSEMOVE)
- Ok=XOnMouseMove(uMsg, wParam, lParam, bHandled); /**/
-
- return WindowImplBase::HandleMessage(uMsg,wParam, lParam);
-
- }
-
- //WM_LBUTTONUP消息处理函数
- LRESULT CListWnd::XOnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
-
- POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
-
- DuiLib::CControlUI* pNewHover =this->m_PaintManager.FindControl(pt);
-
- if(pNewHover!=NULL)
- {
- CString abcd=pNewHover->GetClass();
- if(abcd!=_T("ScrollBarUI"))
- return 0;
- DuiLib::CControlUI* pParent=pNewHover->GetParent();
- if(pParent!=NULL)
- {
- CString name=pParent->GetClass();
- pParent=pParent->GetParent();
- name=pParent->GetClass();
- if(name==_T("ListUI"))
- {
- m_pListUi->SetPos(m_pListUi->GetPos());
- }
- }
-
- }
-
- return 0;
- }
-
- //WM_MOUSEMOVE消息处理函数
- LRESULT CListWnd::XOnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- if(!(wParam&MK_LBUTTON))
- return 0;
- POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
-
- DuiLib::CControlUI* pNewHover =this->m_PaintManager.FindControl(pt);
-
- if(pNewHover!=NULL)
- {
- CString abcd=pNewHover->GetClass();
- if(abcd!=_T("ScrollBarUI"))
- return 0;
- DuiLib::CControlUI* pParent=pNewHover->GetParent();
- if(pParent!=NULL)
- {
- CString name=pParent->GetClass();
- pParent=pParent->GetParent();
- name=pParent->GetClass();
- if(name==_T("ListUI"))
- {
- m_pListUi->SetPos(m_pListUi->GetPos());
- }
- }
-
- }
- return 0;
- }
- LRESULT CListWnd::OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- #if defined(WIN32) && !defined(UNDER_CE)
- BOOL bZoomed = ::IsZoomed(m_hWnd);
- LRESULT lRes = CWindowWnd::HandleMessage(uMsg, wParam, lParam);
- if (::IsZoomed(m_hWnd) != bZoomed)
- {
-
- }
- #else
- return __super::OnSysCommand(uMsg, wParam, lParam, bHandled);
- #endif
-
- return 0;
- }
-
- DuiLib::UILIB_RESOURCETYPE CListWnd::GetResourceType() const
- {
- return DuiLib::UILIB_FILE;
- }
-
- DWORD CListWnd::GetBkColor()
- {
- DuiLib::CControlUI* background = m_PaintManager.FindControl(kBackgroundControlName);
- if (background != NULL)
- return background->GetBkColor();
-
- return 0;
- }
-
- void CListWnd::SetBkColor(DWORD dwBackColor)
- {
- DuiLib::CControlUI* background = m_PaintManager.FindControl(kBackgroundControlName);
- if (background != NULL)
- {
- background->SetBkImage(_T(""));
- background->SetBkColor(dwBackColor);
- background->NeedUpdate();
-
- SkinChangedParam param;
- param.bkcolor = background->GetBkColor();
- param.bgimage = background->GetBkImage();
- //skin_changed_observer_.Broadcast(param);
- }
- }
-
- LRESULT CListWnd::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- return 1;
- }
-
- void CListWnd::OnFinalMessage( HWND hWnd )
- {
- WindowImplBase::OnFinalMessage(hWnd);
- delete this;
- }
- DuiLib::CControlUI* CListWnd::FindControlByName(CString Name)
- {
- return this->m_PaintManager.FindControl(Name);
- }
-
- CString CListWnd::GetWndName()
- {
- return this->WndName;
- }
- void CListWnd::NeedUpdate(){
- /**用以刷新**/
- RECT rcClient;
- ::GetClientRect(GetHWND(), &rcClient);
- if( !::IsRectEmpty(&rcClient) )
- {
- this->m_PaintManager.GetRoot()->SetPos(rcClient);
- }
- }
效果图: