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);
}
}
效果图: