catlistbox.cpp
来自「vc++的部分比较经典的源码」· C++ 代码 · 共 996 行 · 第 1/3 页
CPP
996 行
CatListBoxStlMapIter iter;
CatListBoxCatInfo* pInfo;
// Find category name.
if (bIsListIndex) {
// Get category name by listbox index.
pInfo = (CatListBoxCatInfo*)GetItemData( iIndex );
if (pInfo && (LB_ERR != (int)pInfo)) {
for (iter = m_mapCat.begin(); iter != m_mapCat.end(); iter++) {
if (pInfo == (*iter).second) {
return (LPCTSTR)((*iter).first);
}
}
}
}
else {
// Get category name by category index.
if ((iIndex >= 0) && (iIndex < m_mapCat.size())) {
for (iter = m_mapCat.begin(); iter != m_mapCat.end(); iter++) {
if (iIndex <= 0)
return (LPCTSTR)((*iter).first);
iIndex--;
}
}
}
return NULL;
}
// Returns the number of items under the specified category.
int CCatListBox::GetCategoryItemCount( LPCTSTR pCategory )
{
CatListBoxCatInfo* pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return -1;
return pCatInfo->lstItems.size();
}
// Returns data stored with the specified category's item. Returns LB_ERR if not found.
DWORD CCatListBox::GetCategoryItemData( LPCTSTR pCategory, int iItemIndex )
{
CatListBoxCatInfo* pCatInfo;
CatListBoxStlListIter iter;
// Validate arguments.
if (!pCategory || (iItemIndex < 0))
return LB_ERR;
// Get category's structure.
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return LB_ERR;
// Get DWORD at specified index.
for (iter = pCatInfo->lstItems.begin(); iter != pCatInfo->lstItems.end(); iter++) {
if (iItemIndex <= 0)
return (*iter).dwValue;
iItemIndex--;
}
return LB_ERR;
}
// Overloaded and made protected to prevent this function from being called from outside.
// Must use GetCategoryItemData(pCategory,iItemIndex) instead.
DWORD CCatListBox::GetItemData( int iListIndex )
{
return CListBox::GetItemData( iListIndex );
}
// Returns the category item index matching the specified listbox index.
int CCatListBox::GetCategoryItemIndex( int iListIndex )
{
CatListBoxCatInfo* pInfo = (CatListBoxCatInfo*)GetItemData( iListIndex );
if (pInfo && (LB_ERR != (int)pInfo))
return (iListIndex - pInfo->iListIndex) - 1;
return -1;
}
// Returns the category item name by category item index. Returns NULL if not found.
// This is the only way to retrieve an item name while its category is closed.
LPCTSTR CCatListBox::GetCategoryItemName( LPCTSTR pCategory, int iItemIndex )
{
CatListBoxCatInfo* pInfo;
CatListBoxStlListIter iter;
// Get category info.
pInfo = GetCategoryInfo( pCategory );
if (!pInfo)
return NULL;
// Get item name.
for (iter = pInfo->lstItems.begin(); iter != pInfo->lstItems.end(); iter++) {
if (iItemIndex <= 0)
return (LPCTSTR)((*iter).sItem);
iItemIndex--;
}
return NULL;
}
// Returns the state value stored by the specified category's item. Returns LB_ERR on error.
// State 0 means unchecked. State 1 means checked. State 2 means has no check state.
int CCatListBox::GetCategoryItemState( LPCTSTR pCategory, int iItemIndex )
{
CatListBoxCatInfo* pInfo;
CatListBoxStlListIter iter;
// Get category info.
pInfo = GetCategoryInfo( pCategory );
if (!pInfo)
return LB_ERR;
// Validate "iItemIndex" bounds.
if ((iItemIndex < 0) || (iItemIndex >= pInfo->lstItems.size()))
return E_INVALIDARG;
// Get item name.
for (iter = pInfo->lstItems.begin(); iter != pInfo->lstItems.end(); iter++) {
if (iItemIndex <= 0)
return (*iter).iState;
iItemIndex--;
}
return LB_ERR;
}
// Returns info structure owned by the specified category or NULL if category was not found.
CatListBoxCatInfo* CCatListBox::GetCategoryInfo( LPCTSTR pCategory )
{
CatListBoxStlMapIter iter;
// Validate argument.
if (!pCategory)
return NULL;
// Get category's STL list.
iter = m_mapCat.find( CString((LPCSTR)pCategory) );
if (iter == m_mapCat.end())
return NULL;
return (*iter).second;
}
//////////////////////////////////////////////////////////////////////
// Set functions.
//////////////////////////////////////////////////////////////////////
// Stores "dwValue" with the specified category item.
HRESULT CCatListBox::SetCategoryItemData( LPCTSTR pCategory, int iItemIndex, DWORD dwValue )
{
CatListBoxCatInfo* pCatInfo;
CatListBoxStlListIter iter;
// Validate arguments.
if (!pCategory)
return E_POINTER;
// Get category info.
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return E_INVALIDARG;
// Validate "iItemIndex" bounds.
if ((iItemIndex < 0) || (iItemIndex >= pCatInfo->lstItems.size()))
return E_INVALIDARG;
// Store "dwValue".
for (iter = pCatInfo->lstItems.begin(); iter != pCatInfo->lstItems.end(); iter++) {
if (iItemIndex <= 0) {
(*iter).dwValue = dwValue;
break;
}
iItemIndex--;
}
return S_OK;
}
// Overloaded and made protected to prevent this function from being called from outside.
// Must use SetCategoryItemData(pCategory,iItemIndex,dwValue) instead.
int CCatListBox::SetItemData( int iListIndex, DWORD dwValue )
{
return CListBox::SetItemData( iListIndex, dwValue );
}
// Selects item under the specified category. Expands category if currently closed.
HRESULT CCatListBox::SetCurSel( LPCTSTR pCategory, int iItemIndex )
{
CatListBoxCatInfo* pCatInfo;
// Validate.
if (!pCategory)
return E_POINTER;
// Get category info.
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return E_INVALIDARG;
// Validate "iItemIndex" bounds.
if ((iItemIndex < 0) || (iItemIndex >= pCatInfo->lstItems.size()))
return E_INVALIDARG;
// Expand category if it is currently closed.
if (!pCatInfo->bIsOpen)
SetCategoryState( pCategory, true );
// Select string.
SetCurSel( pCatInfo->iListIndex + iItemIndex + 1 );
return S_OK;
}
// Selects the specified listbox item by listbox index.
int CCatListBox::SetCurSel( int iListIndex )
{
return CListBox::SetCurSel( iListIndex );
}
// Sets the category's state in the listbox.
// "bOpen" = TRUE expands the category and displays its strings in listbox.
// "bOpen" = FALSE closes category and hides its strings in listbox.
HRESULT CCatListBox::SetCategoryState( LPCTSTR pCategory, bool bOpen )
{
CatListBoxCatInfo* pCatInfo;
CatListBoxStlListIter iter;
CString sBuf;
int iListIndex;
// Get category info.
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return E_INVALIDARG;
// Do not continue if state hasn't changed.
if (pCatInfo->bIsOpen == bOpen)
return S_OK;
// Change state.
pCatInfo->bIsOpen = bOpen;
iListIndex = pCatInfo->iListIndex;
m_bDoDraw = false; // Disables listbox drawing.
if (bOpen) {
// Open category. Insert its items into listbox.
for (iter = pCatInfo->lstItems.begin(); iter != pCatInfo->lstItems.end(); iter++) {
iListIndex = (iListIndex >= (GetCount() - 1)) ? -1 : iListIndex + 1;
iListIndex = InsertString( iListIndex, (*iter).sItem );
SetItemData( iListIndex, (DWORD)pCatInfo );
}
UpdateCategoryIndexes( pCatInfo->iListIndex, iListIndex - pCatInfo->iListIndex );
}
else {
// Close category. Delete its items from listbox.
iListIndex++;
while ((CatListBoxCatInfo*)GetItemData( iListIndex ) == pCatInfo)
DeleteString( iListIndex );
UpdateCategoryIndexes( pCatInfo->iListIndex, 0 - pCatInfo->lstItems.size() );
}
m_bDoDraw = true; // Enables listbox drawing. Shows/hides new strings all at once.
Invalidate();
return S_OK;
}
// Sets the category item's state in the listbox.
// "iState" = 0 unchecks its checkbox.
// "iState" = 1 checks its checkbox.
// "iState" = 2 shows no checkbox. (Has no check state.)
HRESULT CCatListBox::SetCategoryItemState( LPCTSTR pCategory, int iItemIndex, int iState )
{
CatListBoxCatInfo* pCatInfo;
CatListBoxStlListIter iter;
// Get category info.
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return E_INVALIDARG;
// Validate "iItemIndex" bounds.
if ((iItemIndex < 0) || (iItemIndex >= pCatInfo->lstItems.size()))
return E_INVALIDARG;
// Find item in category's list.
for (iter = pCatInfo->lstItems.begin(); iter != pCatInfo->lstItems.end(); iter++) {
if (iItemIndex <= 0) {
// Found it. Set item's state.
(*iter).iState = iState;
if (m_bShowStates)
Invalidate();
return S_OK;
}
iItemIndex--;
}
return E_FAIL;
}
//////////////////////////////////////////////////////////////////////
// Show functions.
//////////////////////////////////////////////////////////////////////
// Shows/hides all category item checkboxes. Returns the last show state.
// (Hiding will shift all category item text to the left near the listbox border.)
bool CCatListBox::ShowCategoryItemStates( bool bShow /*=true*/ )
{
bool bValue = m_bShowStates;
m_bShowStates = bShow;
Invalidate();
return bValue;
}
//////////////////////////////////////////////////////////////////////
// Update functions.
//////////////////////////////////////////////////////////////////////
// Changes all category listbox indexes by "iOffset", starting after listbox index "iStartAfter".
// This function should be called after inserts, deletes, and category open/close.
void CCatListBox::UpdateCategoryIndexes( int iStartAfter, int iOffset )
{
CatListBoxStlMapIter iter;
CatListBoxCatInfo* pCatInfo;
// Do not continue if offset is zero. Wouldn't change anything.
if (!iOffset)
return;
// Update category listbox indexes.
for (iter = m_mapCat.begin(); iter != m_mapCat.end(); iter++) {
pCatInfo = (*iter).second;
if (!pCatInfo)
continue;
if (pCatInfo->iListIndex <= iStartAfter)
continue;
pCatInfo->iListIndex += iOffset;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?