#include "stdafx.h" #include "KUIControlList.h" #include "KUIWndManager.h" #include "KUIControlStatic.h" #include "KUIControlListItem.h" #include "KUIControlScroll.h" //#include "KUIControlButton.h" #include "wchar.h" #include //#include "Util.h" #include //#include "KResourceManager.h" #include //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControlList Implement //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// using namespace KUI_MESSAGE; namespace { const int c_nOverWinCutsizeX = 2; const int c_nOverWinCutsizeY = 2; const char* c_lpSelectControlID = "select"; const char* c_lpOverControlID = "over"; const char* c_lpItemControlID = "list_item_%02d"; const char* c_lpItemOutLineID = "out_line_%02d"; const char* c_lpItemDisableID = "disable_%02d"; const char* c_lpBaseBackGroundAni = "static_common_inframe00"; const char* c_lpSelectItemAni = "static_common_selectclick"; const char* c_lpOverItemAni = "static_common_selectover"; const char* c_lpScrollBackAni = "static_scrollbar_backgroundable"; const char* c_lpDisableBackAni = "static_common_disable"; } KUIControlList::KUIControlList() : m_nStartIndex(0) , m_nCrrIndex(-1) , m_nListSize(0) , m_nRenderCtrCnt(0) , m_bHorizon(true) , m_nItemGap(0) , m_bMouseDrag(false) , m_nOldClickIndex(0) , m_bResizeItem(false) , m_pScrollCtr(NULL) , m_bHasScroll(false) , m_bShowOutLine(true) , m_bMouseMsgHandling(true) , m_pSelect(NULL) , m_pOver(NULL) , m_pItemCtrBase(NULL) { } KUIControlList::~KUIControlList() { ClearItem(); } void KUIControlList::_initControl() { KUIWnd::_ClearChildList(); CreateOvercontrol(); CreateSelectcontrol(); CreateScrollcontrol(); KUIControl::_initControl(); } void KUIControlList::CreateScrollcontrol() { KUIWND_CREATE_ARG arg; arg.lpszSprName = m_sSprName.c_str(); arg.pWndManager = m_pManager; arg.lpszAniName = c_lpScrollBackAni; arg.lpszID = "scroll"; arg.pParent = this; arg.dwStyle = 0; arg.rcRect = m_rcRegion; arg.rcRect.top = arg.rcRect.top + 11; arg.rcRect.bottom = arg.rcRect.bottom - 11; if( m_bHorizon ) { arg.lpszClassName = "v_scroll"; arg.rcRect.left = arg.rcRect.right-11; } else { arg.lpszClassName = "h_scroll"; arg.rcRect.top = arg.rcRect.bottom-11; } m_pScrollCtr = (KUIControlScrollBase*)( m_pManager->CreateControl(arg) ); if( m_pScrollCtr ) m_pScrollCtr->SetShow(false); } void KUIControlList::CreateSelectcontrol() { KUIWND_CREATE_ARG arg; arg.lpszSprName = m_sSprName.c_str(); arg.pWndManager = m_pManager; arg.lpszAniName = c_lpSelectItemAni; arg.lpszClassName = "static"; arg.lpszID = c_lpSelectControlID; arg.pParent = this; arg.dwStyle = 0; arg.rcRect = m_rcRegion; m_pSelect = (KUIControl*)( m_pManager->CreateControl(arg) ); if( m_pSelect ) { m_pSelect->SetShow(false); // SetChildAsButtom(c_lpSelectControlID); } } void KUIControlList::CreateOvercontrol() { KUIWND_CREATE_ARG arg; arg.lpszSprName = m_sSprName.c_str(); arg.pWndManager = m_pManager; arg.lpszAniName = c_lpOverItemAni; arg.lpszClassName = "static"; arg.lpszID = c_lpOverControlID; arg.pParent = this; arg.dwStyle = 0; arg.rcRect = m_rcRegion; m_pOver = (KUIControl*)( m_pManager->CreateControl(arg) ); if( m_pOver ) { m_pOver->SetShow(false); // SetChildAsButtom(c_lpOverControlID); } } void KUIControlList::CreateBaseCtr() { std::string strClassName = GetClassNameA(); if( !strClassName.empty() ) { std::wstring wname = nsl::uni::conv( strClassName ); std::vector< std::wstring > toklist = nsl::split( wname.c_str(), L"^", false ); if( toklist.size() == 3 && nsl::uni::conv(toklist[0]) == "list" ) { m_strItemCtrID = nsl::uni::conv( toklist[1] ).c_str(); m_pItemCtrBase = (KUIControlListItem*)( KUIFactory::GetInstance()->CreateObject(m_strItemCtrID.c_str()) ); if( nsl::uni::conv( toklist[2] ) == "h" ) m_bHorizon = true; else m_bHorizon = false; } } if( m_pItemCtrBase ) { /// 2011.07.11 m_pItemCtrBase->m_pWndManager가 null이기 때문에, m_pWndManager를 직접 넣어 준다, - prodongi //if( m_pItemCtrBase->ItemCreate( (KUIControlList*)this, m_strItemCtrID.c_str(), CStringUtil::StringFormat(c_lpItemControlID, 0).c_str() ) ) if( m_pItemCtrBase->ItemCreate( (KUIControlList*)this, m_strItemCtrID.c_str(), CStringUtil::StringFormat(c_lpItemControlID, 0).c_str(), m_pManager ) ) { AddChild( (KUIWnd*)m_pItemCtrBase ); } else { _oprint( "Already created the item for the list control: %s", m_strItemCtrID.c_str() ); } } } bool KUIControlList::IsRenderCtrIndex( int nIndex ) { m_nListSize; nIndex -= m_nStartIndex; if( nIndex < 0 ) return false; if( nIndex >= m_nRenderCtrCnt ) return false; return true; } void KUIControlList::ClearItem() { for( int index(0); index= 0 && nIndex < m_nListSize ) return m_ItemPtList[nIndex]; return NULL; } bool KUIControlList::ResetItem( LPITEM pItem, int nIndex, const char* lpOutLine/*=NULL*/ ) { if( pItem == NULL ) return false; if( nIndex<0 || m_nListSize <= nIndex ) return false; if( RemoveItem(nIndex) ) { if( m_ItemPtList[nIndex] == NULL ) { m_ItemPtList[nIndex] = pItem; m_ItemOutLineList[nIndex] = lpOutLine; } } else return false; if( IsRenderCtrIndex(nIndex) ) UpdateListControl(); InvalidateWnd(); return true; } int KUIControlList::AddItem( LPITEM pItem, const char* lpOutLine/*NULL*/ ) { if( pItem == NULL ) return -1; m_ItemPtList.push_back(pItem); m_ItemOutLineList.push_back(lpOutLine); m_nListSize = m_ItemPtList.size(); if( IsRenderCtrIndex(m_nListSize-1) ) UpdateListControl(); SetScrollRange(); InvalidateWnd(); return m_nListSize; } int KUIControlList::InsertItem( LPITEM pItem, int nIndex, const char* lpOutLine/*NULL*/ ) { if( pItem == NULL ) return -1; if( nIndex < 0 || m_nListSize < nIndex ) return -1; if( m_nListSize == nIndex ) return AddItem(pItem, lpOutLine); std::vector::iterator it = m_ItemPtList.begin(); it += nIndex; m_ItemPtList.insert(it, pItem); std::vector::iterator it_out = m_ItemOutLineList.begin(); it_out += nIndex; m_ItemOutLineList.insert(it_out, lpOutLine); if( IsRenderCtrIndex(nIndex) ) UpdateListControl(); SetScrollRange(); InvalidateWnd(); return m_nListSize = m_ItemPtList.size(); } //★주의★ vector에서 완벽하게 제거하는 것이 아니다. 메모리는 delete하지만 vector에 NULL을 넣는다. bool KUIControlList::RemoveItem( int nIndex ) { if( nIndex < 0 || m_nListSize <= nIndex ) return false; SAFE_DELETE(m_ItemPtList[nIndex]); m_ItemPtList[nIndex] = NULL; m_ItemOutLineList[nIndex] = NULL; // RemoveItemCtr(nIndex); if( IsRenderCtrIndex(nIndex) ) UpdateListControl(); InvalidateWnd(); return true; } //vector에서 완벽하게 삭제하는 것 (메모리도 delete한다) bool KUIControlList::DeleteItem( int nIndex ) { if( nIndex < 0 || m_nListSize <= nIndex ) return false; SAFE_DELETE( m_ItemPtList[ nIndex ] ); std::vector< LPITEM >::iterator it = m_ItemPtList.begin(); it += nIndex; m_ItemPtList.erase( it ); std::vector::iterator it_out = m_ItemOutLineList.begin(); it_out += nIndex; m_ItemOutLineList.erase( it_out ); m_nListSize = m_ItemPtList.size(); if( m_nListSize <= m_nCrrIndex ) m_nCrrIndex = m_nListSize-1; if( m_nListSize < m_nStartIndex + m_nRenderCtrCnt ) m_nStartIndex = std::max( m_nListSize - m_nRenderCtrCnt, 0 ); if( IsRenderCtrIndex( m_nCrrIndex ) ) UpdateListControl( ); SetScrollRange( ); InvalidateWnd( ); return nIndex; } int KUIControlList::SetCrrIndex(int nIndex) { if(nIndex <= 0) nIndex = 0; else if(nIndex >= m_nListSize) nIndex = m_nListSize-1; if( m_nCrrIndex != nIndex ) { int oldIndex = m_nCrrIndex; m_nCrrIndex = nIndex; ClickControlUpdate(); InvalidateWnd(); PumpUpMessage( GetID( ), KUI_MESSAGE::KLIST_ITEM_CHANGE, static_cast< DWORD >( m_nCrrIndex ), static_cast< DWORD >( oldIndex ) ); } PumpUpMessage( GetID( ), KUI_MESSAGE::KLIST_ITEM_SELECT, static_cast< DWORD >( m_nCrrIndex ), 0 ); return m_nCrrIndex; } void KUIControlList::ClearItemControl( int nRenderIndex/*-1*/ ) { if( nRenderIndex == -1 ) { for( int index(0); indexGetRect().GetWidth(); } else { rt.right = rt.left + m_nItemGap; if( m_bHasScroll && m_pScrollCtr ) rt.bottom -= m_pScrollCtr->GetRect().GetHeight(); } CreateOutLinecontrol( CStringUtil::StringFormat(c_lpItemOutLineID, 0).c_str(), rt ); m_pItemCtrBase->Resize( rt ); std::string strDisableCtr = CStringUtil::StringFormat(c_lpItemDisableID, 0); CreateDisableControl( strDisableCtr.c_str(), rt ); SetChildShow(strDisableCtr.c_str(), false); KRect OffsetRT(0,0,0,0); if( m_bHorizon ) { OffsetRT.top = m_nItemGap; OffsetRT.bottom = m_nItemGap; } else { OffsetRT.left = m_nItemGap; OffsetRT.right = m_nItemGap; } for( int i(1); iGetDefaultGap(); if( m_bHorizon ) m_nRenderCtrCnt = m_rcRegion.GetHeight() / m_nItemGap; else m_nRenderCtrCnt = m_rcRegion.GetWidth() / m_nItemGap; // if(m_rcRegion.GetHeight() % m_nItemGap > m_nItemGap/2) // ++m_nRenderCtrCnt; //잘리는 부분도 랜더링 해주기 위해서 1개 추가 CreateItemControl(); InvalidateWnd(); } void KUIControlList::CreateOutLinecontrol( const char* lpID, KRect rt ) { KUIWND_CREATE_ARG arg; arg.lpszSprName = m_sSprName.c_str(); arg.pWndManager = m_pManager; arg.lpszAniName = c_lpBaseBackGroundAni; arg.lpszClassName = "static"; arg.lpszID = lpID; arg.pParent = this; arg.dwStyle = 0; arg.rcRect = rt; KUIControl*pControl = (KUIControl*)( m_pManager->CreateControl(arg) ); if( pControl ) SetChildAsButtom(lpID); } void KUIControlList::CreateDisableControl( const char* lpID, KRect rt ) { KUIWND_CREATE_ARG arg; arg.lpszSprName = m_sSprName.c_str(); arg.pWndManager = m_pManager; arg.lpszAniName = c_lpDisableBackAni; arg.lpszClassName = "static"; arg.lpszID = lpID; arg.pParent = this; arg.dwStyle = 0; arg.rcRect = rt; KUIControl*pControl = (KUIControl*)( m_pManager->CreateControl(arg) ); if( pControl ) { pControl->SetShow(false); // SetChildAsButtom(c_lpOverControlID); } } void KUIControlList::SetScrollRange() { if( m_pScrollCtr == NULL ) return; int nRange = m_nListSize - m_nRenderCtrCnt + 2; if( 0 <= nRange && nRange < m_nListSize ) m_pScrollCtr->SetMaxRange(nRange); else m_pScrollCtr->SetMaxRange(0); InvalidateWnd(); } void KUIControlList::SetScroll( bool bHas ) { if( m_bHasScroll == bHas ) return; m_bHasScroll = bHas; if( m_pScrollCtr == NULL ) CreateScrollcontrol(); KUIControlListItem* pItemCtr(NULL); KUIControl* pCtr(NULL); if( bHas ) { m_pScrollCtr->SetShow(true); for( int i(0); iGetRect(); if( m_pScrollCtr ) { if( m_bHorizon ) rt.right -= m_pScrollCtr->GetRect().GetWidth(); else rt.bottom -= m_pScrollCtr->GetRect().GetHeight(); } ResizeInItemctrset( rt, i ); } } SetScrollRange(); } else { m_pScrollCtr->SetShow(true); for( int i(0); iGetRect(); if( m_pScrollCtr ) { if( m_bHorizon ) rt.right = m_rcRegion.GetWidth(); else rt.bottom = m_rcRegion.GetHeight(); } ResizeInItemctrset( rt, i ); } } } InvalidateWnd(); } void KUIControlList::ResizeInItemctrset( KRect& rRc, int nIndex ) { KUIControlListItem* pItemCtr(NULL); KUIControl* pCtr(NULL); //아이템 컨트롤의 크기 pItemCtr = (KUIControlListItem*)GetChild( CStringUtil::StringFormat(c_lpItemControlID, nIndex).c_str() ); pItemCtr->ResizeListItemRect(rRc); //아이템 안의 아웃라인 크기 pCtr = (KUIControl*)GetChild( CStringUtil::StringFormat(c_lpItemOutLineID, nIndex).c_str() ); if( pCtr ) pCtr->Resize(rRc); //아이템 안의 disable 컨트롤 크기 pCtr = (KUIControl*)GetChild( CStringUtil::StringFormat(c_lpItemDisableID, nIndex).c_str() ); if( pCtr ) pCtr->Resize(rRc); //아이템 안의 셀렉트 컨트롤과 오버 컨트롤은 마우스를 올리거나 클릭시 실시간으로 크기를 체크해서 변경하기 때문에 필요없음 InvalidateWnd(); } void KUIControlList::ShowOutLine( bool bShow ) { for( int i(0); iSetShow(bShow); } InvalidateWnd(); } void KUIControlList::SetAbleItem( int nRealindex, bool bAble/*=true*/ ) { if( nRealindex<0 || m_nListSize <= nRealindex || m_ItemPtList[nRealindex] ==NULL ) return; m_ItemPtList[nRealindex]->SetAble(bAble); InvalidateWnd(); } void KUIControlList::AbleResizeItem( bool bAble ) { if( m_bResizeItem != bAble ) { m_bResizeItem = bAble; InvalidateWnd(); } } void KUIControlList::UpdateListControl() { for( int index( 0 ); index < m_nRenderCtrCnt; ++index ) { int nOriginIndex = m_nStartIndex + index; KUIControlListItem* pItemCtr = reinterpret_cast< KUIControlListItem* >( GetChild( CStringUtil::StringFormat( c_lpItemControlID, index ).c_str( ) ) ); if( pItemCtr ) { if( nOriginIndex >= 0 && nOriginIndex < m_nListSize && m_nListSize > index && m_ItemPtList[ nOriginIndex ] ) pItemCtr->SetItem( m_ItemPtList[ nOriginIndex ] ); else pItemCtr->SetItem( NULL ); } KUIWnd* pOutLine = GetChild( CStringUtil::StringFormat( c_lpItemOutLineID, index ).c_str( ) ); if( pOutLine && m_nRenderCtrCnt <= m_ItemOutLineList.size() ) { if( nOriginIndex >= 0 && nOriginIndex < m_nListSize && m_nListSize > index && m_ItemOutLineList[ nOriginIndex ] ) pOutLine->SetAniName( m_ItemOutLineList[ index ] ); else pOutLine->SetAniName( c_lpBaseBackGroundAni ); } KUIWnd* pDisableCtr = GetChild( CStringUtil::StringFormat( c_lpItemDisableID, index ).c_str( ) ); if( pDisableCtr ) { if( nOriginIndex >= 0 && nOriginIndex < m_nListSize && m_nListSize > index && m_ItemPtList[ nOriginIndex ] ) { bool bAble = m_ItemPtList[ nOriginIndex ]->IsAble( ); pDisableCtr->SetShow( !bAble ); } } } ClickControlUpdate(); InvalidateWnd(); } void KUIControlList::RemoveItemCtr( int nCnt ) { int nSuccess(0); for( int i(1); i<=nCnt; ++i ) { std::string strOutLineCtrName = CStringUtil::StringFormat(c_lpItemOutLineID, m_nRenderCtrCnt-i); std::string strItemCtrName = CStringUtil::StringFormat(c_lpItemControlID, m_nRenderCtrCnt-i); std::string strDisableCtrName = CStringUtil::StringFormat(c_lpItemDisableID, m_nRenderCtrCnt-i); KUIWnd* pOutLineWnd = GetChild( strOutLineCtrName.c_str() ); KUIWnd* pItemWnd = GetChild( strItemCtrName.c_str() ); KUIWnd* pDisableWnd = GetChild( strDisableCtrName.c_str() ); if( !pOutLineWnd && !pItemWnd && !pDisableWnd ) continue; if( RemoveChild(pOutLineWnd) && RemoveChild(pItemWnd) && RemoveChild(pDisableWnd) ) ++nSuccess; } m_nRenderCtrCnt -= nSuccess; InvalidateWnd(); } void KUIControlList::AddItemCtr( int nCnt ) { KRect OffsetRT(0,0,0,0); if( m_bHorizon ) { OffsetRT.top = m_nItemGap; OffsetRT.bottom = m_nItemGap; } else { OffsetRT.left = m_nItemGap; OffsetRT.right = m_nItemGap; } for( int i(m_nRenderCtrCnt); i( GetChild( CStringUtil::StringFormat(c_lpItemControlID, m_nRenderCtrCnt-1).c_str() ) ); if( pItemCtr ) OldRT = pItemCtr->GetRect(); if( nShowItemCnt ) { int nAddItemCtrCnt( nShowItemCnt-m_nRenderCtrCnt ); if( nAddItemCtrCnt > 0 ) AddItemCtr(nAddItemCtrCnt); else if( nAddItemCtrCnt < 0 ) RemoveItemCtr(nAddItemCtrCnt*-1); } else if( nItemGap && nItemGap != m_nItemGap ) SetItemGap(nItemGap); KRect NewRT(0,0,0,0); pItemCtr = reinterpret_cast( GetChild( CStringUtil::StringFormat(c_lpItemControlID, m_nRenderCtrCnt-1).c_str() ) ); if( pItemCtr ) NewRT = pItemCtr->GetRect(); KRect ResultRT(0, 0, NewRT.right - OldRT.right, NewRT.bottom - OldRT.bottom); KRect ChangeRT( m_rcRegion ); ChangeRT = ChangeRT + ResultRT; SetRect(ChangeRT); UpdateListControl(); InvalidateWnd(); return ResultRT; } DWORD KUIControlList::OnKeyMessage(DWORD dwMessage, DWORD dwKeyCode) { DWORD dwRet = KUIControl::OnKeyMessage(dwMessage, dwKeyCode); if(KMR_NO_GET & dwRet) return dwRet; if( IsDisable() ) return dwRet; return dwRet; } void KUIControlList::PumpUpMessage(LPCSTR lpszControlID, DWORD dwMessage, DWORD lParam, DWORD wParam) { if( IsDisable() ) return; switch(dwMessage) { case KUI_MESSAGE::KSCROLL_SELECT: // 스크롤 선택 { int nPos = int(lParam); nPos = max( nPos, 0 ); nPos = min( nPos, m_nListSize-1 ); m_nStartIndex = nPos; UpdateListControl(); InvalidateWnd(); } break; } KUIControl::PumpUpMessage( lpszControlID, dwMessage, lParam, wParam); } DWORD KUIControlList::OnMouseMessage( DWORD dwMessage, int x, int y ) { DWORD dwRet = KUIControl::OnMouseMessage(dwMessage,x,y); if(KMR_NO_GET & dwRet) return dwRet; if( IsDisable() ) return dwRet; if(KMR_NO_GET & dwRet) return dwRet; if( !m_bMouseMsgHandling ) return dwRet; int nOldIndex = m_nCrrIndex; if(IsInRect(x,y) ) { switch(dwMessage) { case KLBUTTON_DOWN: { int nIndex = GetMouseOverIndex(x, y); if( nIndex != -1 && m_pScrollCtr && !m_pScrollCtr->IsInRect(x, y) ) { PumpUpMessage( GetID( ), KUI_MESSAGE::KLIST_ITEM_CLICK, static_cast< DWORD >( nIndex ), 0 ); SetCrrIndex( nIndex + m_nStartIndex ); } //else //{ // if(m_pSelect) m_pSelect->SetShow(false); //} } break; case KLBUTTON_DBLCLK: { int nIndex = GetMouseOverIndex( x, y ); if( nIndex != -1 && m_pScrollCtr && !m_pScrollCtr->IsInRect( x, y ) ) { PumpUpMessage( GetID( ), KUI_MESSAGE::KLIST_ITEM_LDBLCLK, static_cast< DWORD >( nIndex ), 0 ); // 2010.08.13 - prodongi PumpUpMessage( GetID( ), KUI_MESSAGE::KLIST_ITEM_DBSELECT, static_cast< DWORD >( m_nCrrIndex ), 0 ); } } break; case KMOUSE_MOVE: { int nIndex = GetMouseOverIndex(x, y); if( nIndex != -1 ) OverControlUpdate(nIndex); else { if(m_pOver) m_pOver->SetShow(false); } } break; default: break; } } /*if(nOldIndex != m_nCrrIndex ) { PumpUpMessage(GetID(), SLIDER_CHANGE, nOldIndex, 0); PumpUpMessage(GetID(), SLIDER_SELECT, m_nCrrIndex, 0); }*/ return dwRet; } int KUIControlList::GetMouseOverIndex( int x, int y ) { for( int index(0); indexIsInRect(x, y) ) return index; } return -1; } int KUIControlList::GetRenderIndex( int nIndex ) { if( nIndex == -1 ) return -1; int nRenderIndex = nIndex - m_nStartIndex; if( nRenderIndex < 0 ) return -1; if( nRenderIndex >= m_nRenderCtrCnt ) return -1; return nRenderIndex; } void KUIControlList::ClickControlUpdate() { int nIndex = GetRenderIndex( m_nCrrIndex ); if( nIndex != -1 ) { KUIWnd* pWnd = GetChild( CStringUtil::StringFormat(c_lpItemControlID, nIndex).c_str() ); if( m_pSelect && pWnd ) { m_pSelect->Resize( pWnd->GetRect() ); m_pSelect->SetShow(true); } } else m_pSelect->SetShow(false); InvalidateWnd(); } void KUIControlList::OverControlUpdate( int nRenderIndex ) { if( nRenderIndex != -1 ) { KUIWnd* pWnd = GetChild( CStringUtil::StringFormat(c_lpItemControlID, nRenderIndex).c_str() ); if( m_pOver && pWnd ) { KRect rt = pWnd->GetRect(); m_pOver->Resize( ZoomInOutRect(rt, c_nOverWinCutsizeX, c_nOverWinCutsizeY) ); m_pOver->SetShow(true); } } else m_pOver->SetShow(false); InvalidateWnd(); } KRect KUIControlList::ZoomInOutRect( KRect& rRt, int x, int y ) { rRt.left += x; rRt.top += y; rRt.right -= x; rRt.bottom -= y; return rRt; } //int nDataIndex 현재 랜더링되고있는 아이템들의 인덱스가 아닌, 데이터 리스트에 들어있는 인덱스에 관한 인댁스 void KUIControlList::ChangeOutLine( const char* lpAniName, int nDataIndex/*-1*/ ) { if( nDataIndex == -1 ) { for( int i(0); i=0 && nDataIndexRegisterCreator( StringListCreator, "list^item_string^h"); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace { KUIWnd* IconStringListCreator() { return new KUIControIIconStringList; } bool bIconStringListRegister = KUIFactory::GetInstance()->RegisterCreator( IconStringListCreator, "list^item_icon_string^h"); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace { KUIWnd* CommunityListCreator() { return new KUIControICommunityList; } bool bCommunityListRegister = KUIFactory::GetInstance()->RegisterCreator( CommunityListCreator, "list^item_community^h"); }