📄 qcombobox.cpp
字号:
// Description :
// Return type : int
int CQComboBox::GetCountItem()
{
return m_nCountItems;
}
// Function name : CQComboBox::SetCountItems
// Description : Set the count of items list box.
// Return type : void
// Argument : int nCount
void CQComboBox::SetCountItems(int nCount)
{
// Already, you must call GetVisibleCount()
ASSERT (m_nCountVisible != 0);
m_nCountItems = nCount;
// If this need vertical scroll bar, I will put WS_VSCROLL style
if ( m_nCountItems >= m_nCountVisible)
{
CWnd* pWnd = GetListBox();
// Already you must call OnInit, in fact, you must call SubclassDlgItem , or Create function
ASSERT (pWnd != NULL);
pWnd->ModifyStyle(0, WS_VSCROLL);
SCROLLINFO sInfo;
sInfo.cbSize = sizeof(sInfo);
sInfo.fMask = SIF_ALL;
sInfo.nMin = 0;
sInfo.nMax = m_nCountItems - 1;
sInfo.nPage = m_nCountVisible - 1;
sInfo.nPos = 0;
sInfo.nTrackPos = 0;
pWnd->SetScrollInfo(SB_VERT, &sInfo);
}
}
// Function name : CQComboBox::GetVisibleCount
// Description : Get count of visible items.
// Return type : int
int CQComboBox::GetVisibleCount()
{
CListBox* pListBox = GetListBox();
ASSERT( pListBox );
CRect r;
if (pListBox->GetItemRect(0, r) == LB_ERR)
{
int nItem = pListBox->AddString(_T(""));
pListBox->GetItemRect(0, r);
pListBox->DeleteString(nItem);
}
CRect rClient; pListBox->GetClientRect(rClient);
return rClient.Height() / r.Height() + 1;
}
// Function name : CQComboBox::AlreadyLoadPartialListBox
// Description :
// Return type : void
// Argument : int nLineFrom
// Argument : int nHowMany
int CQComboBox::AlreadyLoadPartialListBox(int nLineFrom, int nHowMany)
{
//Already the load was made
return nLineFrom;
}
// Function name : CQComboBox::GetFirstQComboBox
// Description : Statical function. Return first element as QComboBox
// Return type : CQComboBox*
CQComboBox* CQComboBox::GetFirstQComboBox()
{
if (POSITION position = m_mapUnloadedQCombos.GetStartPosition())
{
CQComboBox* pCombo = NULL;
BOOL bLoaded = TRUE;
m_mapUnloadedQCombos.GetNextAssoc(position, pCombo, bLoaded);
return pCombo;
}
return NULL;
}
// Function name : CQComboBox::OnTimer
// Description :
// Return type : void
// Argument : UINT nIDEvent
void CQComboBox::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case QIDTIMERSTARTLOADITEMS:
{
KillTimer(QIDTIMERSTARTLOADITEMS);
SetTimer(QIDTIMERLOADITEMS, QTIMELOADITEMS, NULL);
}
case QIDTIMERLOADITEMS:
{
POSITION position = m_mapUnloadedQCombos.GetStartPosition();
while (position)
{
CQComboBox* pCombo = NULL;
BOOL bLoaded = TRUE;
m_mapUnloadedQCombos.GetNextAssoc(position, pCombo, bLoaded);
if (pCombo->IsAlreadyLoad())
m_mapUnloadedQCombos.RemoveKey(pCombo);
else
{
pCombo->LoadPartial(0, GetVisibleCount());
}
}
break;
}
}
CWnd::OnTimer(nIDEvent);
}
// Function name : CQComboBox::IsAlreadyLoad
// Description : Return TRUE if listvox is already loaded.
// Return type : BOOL
BOOL CQComboBox::IsAlreadyLoad()
{
return m_fctLoadFunction == AlreadyLoadPartialListBox;
}
// Function name : CQComboBox::LoadPartial
// Description :
// Return type : void
// Argument : int nLineFrom
// Argument : int nHowMany
int CQComboBox::LoadPartial(int nLineFrom, int nHowMany)
{
return (this->*m_fctLoadFunction)(nLineFrom, nHowMany);
}
// Function name : CQComboBox::LoadPartialListBox
// Description :
// Return type : void
int CQComboBox::LoadPartialListBox(int nLineFrom, int nHowMany)
{
return m_QuickLoader.Load(nLineFrom, nHowMany);
}
// Function name : CQComboBox::Line
// Description : Return line nLine, by calling own statical function
// Return type : LPCTSTR
// Argument : int nLine
// Argument : LPARAM & lParam
LPCTSTR CQComboBox::Line(int nLine, LPARAM& lParamItem)
{
return m_fctLine(nLine, lParamItem, m_lParam);
}
// Function name : CQComboBox::LinePartial
// Description : return the index of real line, which has string equal with lpszItemPartial
// Return type : int
// Argument : LPCTSTR lpszItemPartial
int CQComboBox::LinePartial(LPCTSTR lpszItemPartial)
{
if (m_fctLinePartial)
return m_fctLinePartial(lpszItemPartial, m_lParam);
return 0;
}
//QSnapLoader implementation
int CQComboBox::QSnapLoader::SNodeItemsInfo::m_nCountRef = 0;
// Function name : CQComboBox::QSnapLoader::~QSnapLoader
// Description : virtual destructor
// Return type :
CQComboBox::QSnapLoader::~QSnapLoader()
{
SNodeItemsInfo* pNodeNext = m_pFirstNode;
while (pNodeNext)
{
SNodeItemsInfo* pNodeDelete = pNodeNext;
pNodeNext = pNodeNext->m_pNextNode;
delete pNodeDelete;
};
}
// Function name : CQComboBox::QSnapLoader::QSnapLoader
// Description : default constructor
// Return type :
CQComboBox::QSnapLoader::QSnapLoader()
{
m_pFirstNode = new SNodeItemsInfo(0,0,0);
}
// Function name : CQComboBox::QSnapLoader::SetParent
// Description : Set the parent of this structure
// Return type : void
// Argument : CQComboBox * pParent
void CQComboBox::QSnapLoader::SetParent(CQComboBox * pParent)
{
m_pParent = pParent;
}
// Function name : CQComboBox::QSnapLoader::GetListNodes
// Description :
// Return type : CString
CString CQComboBox::QSnapLoader::GetListNodes()
{
CString text;
SNodeItemsInfo* pIncreaseNode = m_pFirstNode;
int s = 0;
while (pIncreaseNode)
{
CString t;
t.Format(_T("(%i,%i,%i, [%i,%i])\r\n"), pIncreaseNode->m_nItemLine, pIncreaseNode->m_nCount, pIncreaseNode->m_nItemLB, pIncreaseNode->GetLastLine(), pIncreaseNode->GetLastItem());
text += t;
s += pIncreaseNode->m_nCount;
pIncreaseNode = pIncreaseNode->m_pNextNode;
}
CString t;
t.Format(_T("Count loaded: %i, Count items. listbox() %i"), s, m_pParent->GetListBox()->GetCount());
text += t;
return text;
}
// Function name : CQComboBox::QSnapLoader::Load
// Description :
// Return type : void
// Argument : int nItemFrom
// Argument : int nHowMany
// This function will return the real position into listbox.
int CQComboBox::QSnapLoader::Load(int nItemFrom, int nHowMany)
{
int nIF = abs(nItemFrom + (nHowMany < 0 ? nHowMany : 0));
int nHM = abs(nHowMany), nResult = nItemFrom;
CWnd* pWndParentWindowOfCombo = m_pParent->GetParent();
if (nHM = min(nHM, max(0,m_pParent->GetCountItem() - nIF)))
{
//Something must load
ASSERT (nHM != NULL);
SNodeItemsInfo* pNodeNext = m_pFirstNode;
SNodeItemsInfo* pNodePrev = NULL;
// Already the constructor was called
ASSERT (pNodeNext);
//Find the nodes ie pPrevNext->m_nItemLine <= nIF < pPrevNext->m_nItemLine
while (pNodeNext && (nIF >= pNodeNext->m_nItemLine))
{
pNodePrev = pNodeNext;
pNodeNext = pNodeNext->m_pNextNode;
}
// If in the first block , number of items count is equal with total number of items,
// then this function will not be called again. The next function that will
//be called will be AlreadyLoadPartialListBox.
if (m_pFirstNode->m_nCount == m_pParent->GetCountItem())
{
m_pParent->m_fctLoadFunction = m_pParent->AlreadyLoadPartialListBox;
return nItemFrom;
}
LPCTSTR lpszItemLB = NULL;
LPARAM lParam = NULL;
int nFirst = pNodePrev->GetLastLine(), nItem = pNodePrev->GetLastItem();
CListBox* pListBox = m_pParent->GetListBox();
nResult = pNodePrev->GetLastItem();
if (pNodeNext == NULL)
{
// After the prev node do not exist another node.
BOOL bEnd = TRUE;
if (nIF > nFirst)
{
SNodeItemsInfo* sThis = pNodePrev;
pNodePrev = new SNodeItemsInfo(nIF,0, nResult );
sThis->m_pNextNode = pNodePrev;
pNodePrev->m_pPrevNode = sThis;
nFirst = nIF;
bEnd = FALSE;
}
else
{
nResult = pNodePrev->m_nItemLB + nIF - pNodePrev->m_nItemLine;
}
NotifyWindow(pWndParentWindowOfCombo, m_nLoading, m_pParent->m_hWnd, nFirst);
int i = 0;
for (i = 0; (lpszItemLB = m_pParent->Line(nFirst + i, lParam)) && (i < nHM); i++)
{
pListBox->SetItemData(nItem = pListBox->InsertString(nItem, lpszItemLB), lParam);
pNodePrev->m_nCount++;
nItem++;
}
NotifyWindow(pWndParentWindowOfCombo, m_nLoaded, m_pParent->m_hWnd, i);
}
else
{
SNodeItemsInfo* pIncreaseNode = pNodeNext->m_pNextNode;
int nDiff = pNodeNext->m_nItemLine - nFirst;
ASSERT ( nDiff >= 0 );
nItem = nResult; // first item that will be inserted
// {...+..} ___ {...+..}
if (nDiff <= nHM)
{
// The real nHM will be the diference between nHowMany - nDiff
nHM = nDiff;
// Try to restrict these node in only one.
pNodePrev->m_nCount += pNodeNext->m_nCount + nHM;
pNodePrev->m_pNextNode = pNodeNext->m_pNextNode;
delete pNodeNext;
nResult = pNodePrev->m_nItemLB + nIF - pNodePrev->m_nItemLine;
}
else
{
// nFirst
// /--- > nHM --\
// {...+..} __+________{......}
if (nIF < nFirst)
{
nResult = pNodePrev->m_nItemLB + nIF - pNodePrev->m_nItemLine;
nFirst = pNodePrev->GetLastLine();
pNodePrev->m_nCount += nHM;
pIncreaseNode = pNodeNext;
}
// {......} ______+___ {...+...}
else
if (nIF + nHM >= pNodeNext->m_nItemLine)
{
nHM = pNodeNext->m_nItemLine - nIF;
pNodeNext->m_nItemLine = nIF;
pNodeNext->m_nCount += nHM;
//pNodeNext->m_nItemLB remains constant
nItem = pNodeNext->m_nItemLB;
nFirst = nIF;
nResult = pNodeNext->m_nItemLB;
}
// {......} __+____+___ {......}
else
{
SNodeItemsInfo* sThis = new SNodeItemsInfo(nIF, nHM, nResult );
sThis->m_pPrevNode = pNodePrev;
sThis->m_pNextNode = pNodeNext;
pNodePrev->m_pNextNode = sThis;
pNodeNext->m_pPrevNode = sThis;
nFirst = nIF;
pIncreaseNode = pNodeNext;
}
}
// if some items must insert, do it
if (nHM > 0)
{
NotifyWindow(pWndParentWindowOfCombo, m_nLoading, m_pParent->m_hWnd, nFirst);
for (int i = 0; i < nHM; i++)
{
lpszItemLB = m_pParent->Line(nFirst + i, lParam);
// while pNodePrev and pNodeNext exist !
ASSERT (lpszItemLB);
pListBox->SetItemData(nItem = pListBox->InsertString(nItem, lpszItemLB), lParam);
nItem++;
}
while (pIncreaseNode)
{
pIncreaseNode->m_nItemLB += nHM;
pIncreaseNode = pIncreaseNode->m_pNextNode;
}
NotifyWindow(pWndParentWindowOfCombo, m_nLoaded, m_pParent->m_hWnd, nHM);
}
}
}
return nResult;
}
// Function name : CQComboBox::QSnapLoader::GetItemLine
// Description : return the real line, converts from nItemLB
// Return type : int
// Argument : int nItemLB
int CQComboBox::QSnapLoader::GetItemLine(int nItemLB)
{
nItemLB = max(0,nItemLB);
SNodeItemsInfo* pNodeNext = m_pFirstNode;
while (pNodeNext && ( pNodeNext->m_nItemLB > nItemLB ))
pNodeNext = pNodeNext->m_pNextNode;
return pNodeNext->m_nItemLine + nItemLB - pNodeNext->m_nItemLB;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -