catlistbox.cpp
来自「vc++的部分比较经典的源码」· C++ 代码 · 共 996 行 · 第 1/3 页
CPP
996 行
if ((*iter).first.CompareNoCase( pCategory ) > 0) {
if ((UINT)pCatInfo->iListIndex > (UINT)pTempInfo->iListIndex)
pCatInfo->iListIndex = pTempInfo->iListIndex;
pTempInfo->iListIndex++; // Increment index of all following categories.
}
}
}
m_bDoDraw = false; // Disables listbox drawing.
pCatInfo->iListIndex = InsertString( pCatInfo->iListIndex, pCategory );
SetItemData( pCatInfo->iListIndex, (DWORD)pCatInfo );
m_bDoDraw = true; // Enables listbox drawing. Must wait for SetItemData() to be called.
Invalidate();
return S_OK;
}
// Adds an item under the specified category. Creates category if it hasn't already been added.
// Also sets the item's state. 0 = Unchecked checkbox. 1 = Checked checkbox. 2 = No checkbox.
// Returns the category item index to the new string or LB_ERR if the add failed.
int CCatListBox::AddCategoryItem( LPCTSTR pCategory, LPCTSTR pItem, int iState /*=2*/ )
{
CatListBoxCatInfo* pCatInfo;
CatListBoxItemInfo ItemInfo;
CatListBoxStlListIter iter;
int iItemIndex = 0;
int iListIndex;
// Validate argument.
if (!pCategory)
return LB_ERR;
// Get category
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo) {
// Category not found. Add it to map.
if (S_OK != AddCategory( pCategory ))
return LB_ERR;
pCatInfo = GetCategoryInfo( pCategory );
if (!pCatInfo)
return LB_ERR;
}
// Add string to category's STL list.
if (LBS_SORT & GetStyle()) {
iItemIndex = 0;
for (iter = pCatInfo->lstItems.begin(); iter != pCatInfo->lstItems.end(); iter++) {
if ((*iter).sItem.CompareNoCase( pItem ) > 0)
break;
iItemIndex++;
}
}
else {
iter = pCatInfo->lstItems.end();
iItemIndex = pCatInfo->lstItems.size();
}
ItemInfo.dwValue = 0;
ItemInfo.iState = iState;
ItemInfo.sItem = pItem;
pCatInfo->lstItems.insert( iter, ItemInfo );
// Add string to listbox if its category is open.
if (pCatInfo->bIsOpen) {
// Add string.
m_bDoDraw = false; // Disables listbox drawing.
iListIndex = pCatInfo->iListIndex + iItemIndex + 1;
iListIndex = InsertString( iListIndex, pItem );
if (iListIndex >= 0) {
SetItemData( iListIndex, (DWORD)pCatInfo );
UpdateCategoryIndexes( pCatInfo->iListIndex, 1 );
}
m_bDoDraw = true; // Enables listbox drawing. Wait for SetItemData() to be called.
Invalidate();
}
return iItemIndex;
}
// Overloaded and made protected to prevent this function from being called from outside.
// Must use AddCategoryItem(pCategory,pItem) instead.
int CCatListBox::AddString( LPCTSTR pString )
{
return CListBox::AddString( pString );
}
// Overloaded and made protected to prevent this function from being called from outside.
int CCatListBox::InsertString( int iListIndex, LPCTSTR pString )
{
return CListBox::InsertString( iListIndex, pString );
}
//////////////////////////////////////////////////////////////////////
// Delete functions.
//////////////////////////////////////////////////////////////////////
// Deletes the indexed listbox item.
// If the index points to a category's item, then only that item is deleted.
// If the index points to a category, then that category and all of its items are deleted.
HRESULT CCatListBox::Delete( int iListIndex )
{
CatListBoxCatInfo* pInfo;
CString sCategory;
HRESULT hr = E_FAIL;
// Validate argument.
if ((iListIndex < 0) || (iListIndex >= GetCount()))
return E_INVALIDARG;
// Get category's info.
pInfo = (CatListBoxCatInfo*)GetItemData( iListIndex );
if (!pInfo)
return E_FAIL;
// Delete indexed listbox item.
GetText( pInfo->iListIndex, sCategory );
if (iListIndex == pInfo->iListIndex)
hr = DeleteCategory( (LPCTSTR)sCategory );
else
hr = DeleteCategoryItem( (LPCTSTR)sCategory, (iListIndex - pInfo->iListIndex) - 1 );
return hr;
}
// Deletes specified category and all of its items.
HRESULT CCatListBox::DeleteCategory( LPCTSTR pCategory )
{
CatListBoxCatInfo* pInfo;
CatListBoxStlMapIter iter;
int iCount = 0;
// Validate argument.
if (!pCategory)
return E_POINTER;
// Get category's info.
iter = m_mapCat.find( CString( pCategory ) );
if (iter == m_mapCat.end())
return E_INVALIDARG;
pInfo = (*iter).second;
if (!pInfo)
return E_INVALIDARG;
// Delete category and its items from listbox.
m_bDoDraw = false; // Disables listbox drawing.
while ((CatListBoxCatInfo*)GetItemData( pInfo->iListIndex ) == pInfo) {
DeleteString( pInfo->iListIndex );
iCount++;
}
UpdateCategoryIndexes( pInfo->iListIndex, 0 - iCount );
m_bDoDraw = true; // Enables listbox drawing. Clears listbox strings all at once.
Invalidate();
// Delete category from STL map.
delete pInfo;
(*iter).second = NULL;
m_mapCat.erase( iter );
return S_OK;
}
// Deletes indexed category item.
HRESULT CCatListBox::DeleteCategoryItem( LPCTSTR pCategory, int iItemIndex )
{
CatListBoxCatInfo* pInfo;
CatListBoxStlListIter iter;
int iValue;
// Validate argument.
if (!pCategory)
return E_POINTER;
// Get category's info.
pInfo = GetCategoryInfo( pCategory );
if (!pInfo)
return E_INVALIDARG;
// Do not continue if "iItemIndex" exceeds list's bounds.
if ((iItemIndex < 0) || (iItemIndex >= pInfo->lstItems.size()))
return E_INVALIDARG;
// Delete string in listbox if its category is open.
if (pInfo->bIsOpen) {
m_bDoDraw = false; // Disables listbox drawing.
iValue = pInfo->iListIndex + iItemIndex + 1;
DeleteString( iValue );
UpdateCategoryIndexes( iValue, -1 );
m_bDoDraw = true; // Enables listbox drawing. Wait for category index update.
Invalidate();
}
// Find item in category's list.
// Delete item from category's list.
iValue = 0;
for (iter = pInfo->lstItems.begin(); iter != pInfo->lstItems.end(); iter++) {
if (iValue == iItemIndex)
break;
iValue++;
}
pInfo->lstItems.erase( iter );
return S_OK;
}
// Overloaded and made protected to prevent this function from being called from outside.
// Must use DeleteCategoryItem(pCategory,pItem) instead.
int CCatListBox::DeleteString( UINT iListIndex )
{
return CListBox::DeleteString( iListIndex );
}
//////////////////////////////////////////////////////////////////////
// Reset functions.
//////////////////////////////////////////////////////////////////////
// Empties listbox.
void CCatListBox::ResetContent()
{
// Empty listbox.
CListBox::ResetContent();
// Empty STL map.
ResetCategoryInfo();
}
// Empties category STL map.
void CCatListBox::ResetCategoryInfo()
{
CatListBoxStlMapIter iter;
CatListBoxCatInfo* pCatInfo;
for (iter = m_mapCat.begin(); iter != m_mapCat.end(); iter++) {
if (pCatInfo = (*iter).second) {
delete pCatInfo;
(*iter).second = NULL;
}
}
m_mapCat.clear();
}
//////////////////////////////////////////////////////////////////////
// Find functions.
//////////////////////////////////////////////////////////////////////
// Returns specified category's listbox index or -1 if not found.
int CCatListBox::FindCategory( LPCTSTR pCategory )
{
CatListBoxCatInfo* pInfo = GetCategoryInfo( pCategory );
return (pInfo) ? pInfo->iListIndex : -1;
}
// Finds the first item string exactly matching "pItem" in the category's list.
// Will search after index "iStartAfter" in list. Set "iStartAfter" to -1 to search entire list.
// Returns the category item's index or -1 if not found. (Does not return listbox index!)
int CCatListBox::FindCategoryItem( LPCTSTR pCategory, int iStartAfter, LPCTSTR pItem )
{
CatListBoxCatInfo* pInfo;
CatListBoxStlListIter iter;
int iCount = 0;
// Validate arguments.
if (!pCategory || !pItem)
return -1;
// Get category's info.
pInfo = GetCategoryInfo( pCategory );
if (!pInfo)
return -1;
// Find item in category's list.
for (iter = pInfo->lstItems.begin(); iter != pInfo->lstItems.end(); iter++) {
if (iCount > iStartAfter) {
if (0 == (*iter).sItem.Compare( pItem )) {
return iCount;
}
}
iCount++;
}
return -1;
}
//////////////////////////////////////////////////////////////////////
// Is functions.
//////////////////////////////////////////////////////////////////////
// Returns TRUE if listbox index references a category.
bool CCatListBox::IsCategory( int iListIndex )
{
CatListBoxCatInfo* pInfo = (CatListBoxCatInfo*)GetItemData( iListIndex );
if (pInfo && (LB_ERR != (int)pInfo)) {
if (iListIndex == pInfo->iListIndex) {
return true;
}
}
return false;
}
// Returns TRUE if specified string is a category name.
bool CCatListBox::IsCategory( LPCTSTR pString )
{
return (FindCategory( pString ) >= 0) ? true : false;
}
// Returns TRUE if the specified category is open.
// Returns FALSE if closed or if category does not exist.
bool CCatListBox::IsCategoryOpen( LPCTSTR pCategory )
{
CatListBoxCatInfo* pInfo = GetCategoryInfo( pCategory );
if (pInfo) {
if (pInfo->bIsOpen) {
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////
// Get functions.
//////////////////////////////////////////////////////////////////////
// Returns the number of categories stored in this listbox.
int CCatListBox::GetCategoryCount()
{
return m_mapCat.size();
}
// Returns the category's name specified by the given index.
// If "bIsListIndex" = TRUE, then "iIndex" references the listbox.
// If "bIsListIndex" = FALSE, then "iIndex" references the category list.
// (The total number of categories can be retrieved via GetCategoryCount().)
LPCTSTR CCatListBox::GetCategoryName( int iIndex, bool bIsListIndex /*=true*/ )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?