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 + -
显示快捷键?