📄 mrucombo.cpp
字号:
// This function always reallocates a CRecentFileList so that the size
// change (and registry string changes, if any) takes place immediately.
//
//////////////////////////////////////////////////////////////////////////
int CMRUComboBox::SetMaxMRUSize ( int nMaxSize )
{
int nRetVal = m_nMaxMRUSize;
// New size needs to be a positive
// number.
ASSERT ( nMaxSize >= 1 );
if ( nMaxSize <= 0 )
return -1;
m_nMaxMRUSize = nMaxSize;
if ( NULL == m_pMRU )
{
nRetVal = 0; // no previous size
}
if ( !AllocNewMRU() )
{
nRetVal = -1; // error!!
TRACE0("CMRUComboBox -- SetMaxMRUSize() failed - couldn't allocate new CRecentFileList.\n");
}
return nRetVal;
}
//////////////////////////////////////////////////////////////////////////
//
// Function: GetMaxMRUSize
//
// Description:
// Returns the current max MRU size.
//
// Input:
// Nothing.
//
// Returns:
// The current max size.
//
//////////////////////////////////////////////////////////////////////////
int CMRUComboBox::GetMaxMRUSize() const
{
return m_nMaxMRUSize;
}
//////////////////////////////////////////////////////////////////////////
//
// Function: SetAutoSaveOnDestroy()
//
// Description:
// Sets whether the CMRUComboBox will automatically save the MRU when
// the object is destroyed.
//
// Input:
// bAutoSave: [in] Flag: enable auto-saving?
//
// Returns:
// The previous value of this setting.
//
//////////////////////////////////////////////////////////////////////////
BOOL CMRUComboBox::SetAutoSaveOnDestroy ( BOOL bAutoSave )
{
BOOL bRetVal = m_bSaveOnDestroy;
m_bSaveOnDestroy = bAutoSave;
return bRetVal;
}
//////////////////////////////////////////////////////////////////////////
//
// Function: SetAutoSaveAfterAdd()
//
// Description:
// Sets whether the CMRUComboBox will automatically save the MRU after
// an item is added successfully.
//
// Input:
// bAutoSave: [in] Flag: enable auto-saving?
//
// Returns:
// The previous value of this setting.
//
//////////////////////////////////////////////////////////////////////////
BOOL CMRUComboBox::SetAutoSaveAfterAdd ( BOOL bAutoSave )
{
BOOL bRetVal = m_bSaveAfterAdd;
m_bSaveAfterAdd = bAutoSave;
return bRetVal;
}
//////////////////////////////////////////////////////////////////////////
//
// Function: SetAutoRefreshAfterAdd()
//
// Description:
// Sets whether the CMRUComboBox will automatically refresh the combobox
// control after an item is added successfully.
//
// Input:
// bAutoSave: [in] Flag: enable auto-refresh?
//
// Returns:
// The previous value of this setting.
//
//////////////////////////////////////////////////////////////////////////
BOOL CMRUComboBox::SetAutoRefreshAfterAdd ( BOOL bAutoSave )
{
BOOL bRetVal = m_bRefreshAfterAdd;
m_bRefreshAfterAdd = bAutoSave;
return bRetVal;
}
/////////////////////////////////////////////////////////////////////////////
// CMRUComboBox misc. functions
//////////////////////////////////////////////////////////////////////////
//
// Function: VerifyMRUParams()
//
// Description:
// Checks the registry and size parameters and makes sure they're valid
// for CRecentFileList.
//
// Input:
// Nothing. (uses member variables)
//
// Returns:
// TRUE if the params are OK, FALSE if not.
//
//////////////////////////////////////////////////////////////////////////
BOOL CMRUComboBox::VerifyMRUParams() const
{
BOOL bRetVal = TRUE;
// 1. The registry key string must be
// non-empty.
if ( m_cstrRegKey.IsEmpty() || 0 == m_cstrRegKey.GetLength() )
{
TRACE0("CMRUComboBox -- VerifyMRUParams() - registry key name not set.\n");
bRetVal = FALSE;
}
// 2. The reg value must be non-empty
// and contain "%d"
if ( m_cstrRegValueFormat.IsEmpty() ||
0 == m_cstrRegValueFormat.GetLength() )
{
TRACE0("CMRUComboBox -- VerifyMRUParams() - registry value format not set.\n");
bRetVal = FALSE;
}
else if ( -1 == m_cstrRegValueFormat.Find ( _T("%d") ) )
{
TRACE0("CMRUComboBox -- VerifyMRUParams() - registry value format doesn't contain \"%d\"\n");
bRetVal = FALSE;
}
// 3. The Max MRU size must be > 0.
if ( m_nMaxMRUSize <= 0 )
{
TRACE0("CMRUComboBox -- VerifyMRUParams() - max MRU size is set to <= 0\n");
bRetVal = FALSE;
}
return bRetVal;
}
//////////////////////////////////////////////////////////////////////////
//
// Function: AllocNewMRU()
//
// Description:
// Allocates a new CRecentFileList, and copies the contents of the previous
// MRU (if any) to the new one.
//
// Input:
// Nothing.
//
// Returns:
// TRUE if successful, FALSE if not.
//
//////////////////////////////////////////////////////////////////////////
BOOL CMRUComboBox::AllocNewMRU()
{
CString* acstrOldList = NULL;
int nItemsToCopy;
int i;
// Make sure the MRU params are OK.
if ( !VerifyMRUParams() )
{
TRACE0("CMRUComboBox -- AllocNewMRU() returning FALSE - MRU list params invalid or not set.\n");
return FALSE;
}
try
{
// Figuring out how many strings to
// copy: The lesser of the new MRU
// size and the previous MRU's size.
// Of course, if there was no previous
// MRU, then nothing will be copied.
nItemsToCopy = m_nMaxMRUSize;
if ( NULL != m_pMRU )
{
nItemsToCopy = __min ( m_nMaxMRUSize, m_pMRU->GetSize() );
// Save the contents of the old MRU list.
acstrOldList = new CString [ nItemsToCopy ];
for ( i = 0; i < nItemsToCopy; i++ )
{
acstrOldList[i] = (*m_pMRU)[i];
}
// Nuke the old CRecentFileList object...
delete m_pMRU;
m_pMRU = NULL;
}
// and make a new one!
m_pMRU = new CRecentFileList ( 1, m_cstrRegKey,
m_cstrRegValueFormat, m_nMaxMRUSize );
// Copy the MRU strings if there was a previous MRU. We add
// the strings in reverse numerical order so they end up in the same
// order as they were in the old MRU.
if ( NULL != acstrOldList )
{
for ( i = nItemsToCopy - 1; i >= 0; i-- )
{
m_pMRU->Add ( acstrOldList[i] );
}
delete [] acstrOldList;
}
}
catch ( CMemoryException )
{
TRACE0("CMRUComboBox -- Memory exception in AllocNewMRU()!\n");
if ( NULL != m_pMRU )
{
delete m_pMRU;
m_pMRU = NULL;
}
throw;
}
// Reset the changed flag.
m_bParamsChanged = FALSE;
return TRUE;
}
void CMRUComboBox::OnDropdown()
{
if(!m_bShowAutoWidth)
return;
// Reset the dropped width
int nNumEntries = GetCount();
int nWidth = 0;
CString str;
CClientDC dc(this);
int nSave = dc.SaveDC();
dc.SelectObject(GetFont());
int nScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);
for (int i = 0; i < nNumEntries; i++)
{
GetLBText(i, str);
int nLength = dc.GetTextExtent(str).cx + nScrollWidth;
nWidth = max(nWidth, nLength);
}
// Add margin space to the calculations
nWidth += dc.GetTextExtent("0").cx;
dc.RestoreDC(nSave);
SetDroppedWidth(nWidth);
}
void CMRUComboBox::OnMouseMove(UINT nFlags, CPoint point)
{
SetTimer(1,10,NULL);
CComboBox::OnMouseMove(nFlags, point);
}
void CMRUComboBox::OnLButtonDown(UINT nFlags, CPoint point)
{
m_bLBtnDown = TRUE;
CComboBox::OnLButtonDown(nFlags, point);
}
void CMRUComboBox::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bLBtnDown = FALSE;
Invalidate();
CComboBox::OnLButtonUp(nFlags, point);
}
void CMRUComboBox::OnTimer(UINT nIDEvent)
{
POINT pt;
GetCursorPos(&pt);
CRect rcItem;
GetWindowRect(&rcItem);
static BOOL bPainted = FALSE;
// OnLButtonDown, show pressed.
if (m_bLBtnDown==TRUE) {
KillTimer (1);
if (bPainted == TRUE) {
DrawCombo(FC_DRAWPRESSD, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
bPainted = FALSE;
}
return;
}
// If mouse leaves, show flat.
if (!rcItem.PtInRect(pt)) {
KillTimer (1);
if (bPainted == TRUE) {
DrawCombo(FC_DRAWNORMAL, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNFACE));
bPainted = FALSE;
}
return;
}
// On mouse over, show raised.
else {
if (bPainted == TRUE)
return;
else {
bPainted = TRUE;
DrawCombo(FC_DRAWRAISED, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
}
}
CComboBox::OnTimer(nIDEvent);
}
void CMRUComboBox::OnPaint()
{
Default();
DrawCombo(FC_DRAWNORMAL, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNFACE));
}
void CMRUComboBox::DrawCombo(DWORD dwStyle, COLORREF clrTopLeft, COLORREF clrBottomRight)
{
CRect rcItem;
GetClientRect(&rcItem);
CDC* pDC = GetDC();
// Cover up dark 3D shadow.
pDC->Draw3dRect(rcItem, clrTopLeft, clrBottomRight);
rcItem.DeflateRect(1,1);
if (!IsWindowEnabled()) {
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNHIGHLIGHT));
}
else {
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNFACE));
}
// Cover up dark 3D shadow on drop arrow.
rcItem.DeflateRect(1,1);
rcItem.left = rcItem.right-Offset();
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNFACE));
// Cover up normal 3D shadow on drop arrow.
rcItem.DeflateRect(1,1);
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNFACE),
::GetSysColor(COLOR_BTNFACE));
if (!IsWindowEnabled()) {
ReleaseDC(pDC);
return;
}
switch (dwStyle)
{
case FC_DRAWNORMAL:
rcItem.top -= 1;
rcItem.bottom += 1;
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNHIGHLIGHT));
rcItem.left -= 1;
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNHIGHLIGHT));
break;
case FC_DRAWRAISED:
rcItem.top -= 1;
rcItem.bottom += 1;
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
break;
case FC_DRAWPRESSD:
rcItem.top -= 1;
rcItem.bottom += 1;
rcItem.OffsetRect(1,1);
pDC->Draw3dRect(rcItem, ::GetSysColor(COLOR_BTNSHADOW),
::GetSysColor(COLOR_BTNHIGHLIGHT));
break;
}
ReleaseDC(pDC);
}
int CMRUComboBox::Offset()
{
// Thanks to Todd Brannam for this suggestion...
return ::GetSystemMetrics(SM_CXHTHUMB);
}
void CMRUComboBox::ShowAutoWidth(BOOL bShowAutoWidth)
{
m_bShowAutoWidth = bShowAutoWidth;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -