⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uistatusbar.cpp

📁 vc座的资源管理器源代码
💻 CPP
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// You may use this source code, compile or redistribute it as part of your application 
// for free. You cannot redistribute it as a part of a software development 
// library without the agreement of the author. If the sources are 
// distributed along with the application, you should leave the original 
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES at your own risk.
// 
// For the latest updates to this code, check this site:
// http://www.masmex.com 
// after Sept 2000
// 
// Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
//*******************************************************************************

#include "stdafx.h"
#include "UIStatusBar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////
//
// IMStatusBar
//
///////////////////////////////////
IMPLEMENT_SERIAL(CUIStatusBar, CStatusBar, 0)
IMPLEMENT_SERIAL(CStatusBarPane, CObject, 0)

BEGIN_MESSAGE_MAP(CUIStatusBar, CStatusBar)
	//{{AFX_MSG_MAP(CUIStatusBar)
	ON_WM_CONTEXTMENU()
	ON_WM_LBUTTONDOWN()
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

LPCTSTR CUIStatusBar::szSection = _T("Settings\\StatusBar");
LPCTSTR CUIStatusBar::szPaneEntry = _T("Pane");

CStatusBarPane::CStatusBarPane(const CStatusBarPane &rOther)
{
	DoCopy(rOther);
}

CStatusBarPane &CStatusBarPane::operator=(const CStatusBarPane &rOther)
{
	if (this == &rOther)
		return *this;
	DoCopy(rOther);
	return *this;
}

void CStatusBarPane::DoCopy(const CStatusBarPane &rOther)
{
	m_nID = rOther.m_nID;
	m_nStyle = rOther.m_nStyle;
	m_bActive = rOther.m_bActive;
//	m_listImageIndex = rOther.m_listImageIndex;
}

void CStatusBarPane::Serialize(CArchive &ar)
{
	if (ar.IsStoring())
	{
		ar << m_nID;
		ar << m_nStyle;
		ar << m_bActive;
	}
	else
	{
		ar >> m_nID;
		ar >> m_nStyle;
		ar >> m_bActive;
	}
}

void CUIStatusBar::OnContextMenu(CWnd *pWnd, CPoint point)
{
/* 	CMenu Menu;

	// Build the popup menu
	Menu.CreatePopupMenu();
	CStatusBarPane *pPane = NULL;
	CString strText;
	for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;) 
	{
		pPane = m_PaneList.GetPrev(pos);
		if (pPane->GetCommandID() != ID_SEPARATOR && pPane->GetCommandID() != ID_INDICATOR_MAIN) 
		{
			strText.LoadString(pPane->GetCommandID());
			Menu.AppendMenu(MF_STRING,pPane->GetCommandID(),strText);
		}
	}
	// and display using main frame as message window
	Menu.TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,point.x,point.y,theApp.m_pMainWnd);
	theApp.m_pMainWnd->SetFocus();
*/
}
////////////////////////////////////////////////////////////

CUIStatusBar::CUIStatusBar()
{
	Init();
}

CUIStatusBar::~CUIStatusBar()
{
	Clear();
}

void CUIStatusBar::Reset()
{
	Clear();
	Init();
}

void CUIStatusBar::Init()
{
	m_nStatusPane1Width = -1;
	m_nStatusPane1Style = SBPS_STRETCH;
	m_bMenuSelect = FALSE;
	m_nMinHeight = GetSystemMetrics(SM_CYSMICON)+4;
	m_pImageList = new CImageList;
}

void CUIStatusBar::Clear()
{
	CStatusBarPane *pPane;	
	while (!m_PaneList.IsEmpty()) 
	{
			pPane = m_PaneList.RemoveTail();
			delete pPane;
	}
	delete m_pImageList;
	m_pImageList = NULL;
}

CUIStatusBar &CUIStatusBar::operator=(const CUIStatusBar &rOther)
{
	if (this == &rOther)
		return *this;
	for(POSITION pos=rOther.m_PaneList.GetHeadPosition();pos != NULL;) 
	{
		CStatusBarPane *pPane = new CStatusBarPane;
		*pPane = *rOther.m_PaneList.GetNext(pos);
		m_PaneList.AddTail(pPane);
	}
	m_nStatusPane1ID = rOther.m_nStatusPane1ID;
	m_nStatusPane1Style = rOther.m_nStatusPane1Style;
	m_nStatusPane1Width = rOther.m_nStatusPane1Width;
	m_bMenuSelect =	rOther.m_bMenuSelect;
	return *this;
}

void CUIStatusBar::UpdatePane(int nIndex)
{
	CRect rect;
	GetStatusBarCtrl().GetRect(nIndex,&rect);
	InvalidateRect(rect);
	UpdateWindow();
}

CStatusBarPane *CUIStatusBar::GetPane(UINT nPaneID) const
{
	if (nPaneID == 0)
	{
		nPaneID = ((CUIStatusBar*)this)->GetPaneID(0);
	}
	CStatusBarPane *pPane = NULL;
	for (POSITION pos=m_PaneList.GetHeadPosition();pos != NULL;) 
	{
		pPane = m_PaneList.GetNext(pos);
		if (pPane->GetCommandID() == nPaneID)
			break;
	}
	return((pPane && nPaneID == pPane->GetCommandID()) ? pPane : NULL);
}

void CUIStatusBar::RemoveAllIcons(UINT nPaneID)
{
	CStatusBarPane *pPane = GetPane(nPaneID);
	ASSERT(pPane);
	pPane->RemoveAllImages();
	UpdatePane(GetPaneIndex(nPaneID));
}

void CUIStatusBar::RemoveIcon(UINT nPaneID,UINT nImageID,bool bUpdate)
{	
	if (nPaneID == 0)
	{
		nPaneID = GetPaneID(0);
	}
	CStatusBarPane *pPane = GetPane(nPaneID);
	ASSERT(pPane);
	RemoveIcon(nImageID,pPane,bUpdate);
}

void CUIStatusBar::RemoveIcon(UINT nImageID,CStatusBarPane *pPane,bool bUpdate)
{	
	int nImageIndex=-1;
	if (m_mapImageIndex.Lookup(nImageID,nImageIndex))
		pPane->RemoveImage(nImageIndex);
	if (bUpdate)
		UpdatePane(nImageIndex);
}

void CUIStatusBar::AddIcon(UINT nPaneID,UINT nImageID,bool bUpdate)
{
	int nIndex = -1;
	if (!m_mapImageIndex.Lookup(nImageID,nIndex))
		nIndex = AddIcon(nImageID);
	// Possibly wrong id using pane index 0
	if (nPaneID == 0)
	{
		nPaneID = GetPaneID(0);
	}
	AddImageIndex(nPaneID,nIndex,bUpdate);
}

// add an image to list of images that will be displayed
// nIndex into the image list
void CUIStatusBar::AddImageIndex(UINT nPaneID,int nImageIndex,bool bUpdate)
{
	CStatusBarPane *pPane = GetPane(nPaneID);
	ASSERT(pPane);
	int nPaneIndex = GetPaneIndex(nPaneID);
	// Pane 0 can have only one icon
	if (nPaneIndex == 0)
	{
		pPane->RemoveAllImages();
	}
	if (!pPane->FindImage(nImageIndex))
	{
		pPane->AddImage(nImageIndex);
	}
	UINT nStyle;
	int nWidth;
	GetPaneInfo(nPaneIndex,nPaneID,nStyle,nWidth);
	// Make sure it's owner draw
	if (!(nStyle & SBT_OWNERDRAW))
	{
		nStyle |= SBT_OWNERDRAW;
		SetPaneInfo(nPaneIndex,nPaneID,nStyle,nWidth);
		pPane->SetStyle(nStyle);
	}
	if (bUpdate)
		UpdatePane(GetPaneIndex(nPaneID));
}

int CUIStatusBar::AddIcon(UINT nID)
{
	if (m_pImageList->m_hImageList == NULL)
		CreateImageList();
	ASSERT(m_pImageList->m_hImageList);
	HICON hIcon = (HICON)::LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(nID),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
	if (hIcon)
	{
		int nIndex = m_pImageList->Add(hIcon);
		m_mapImageIndex[nID] = nIndex;
		return nIndex;
	}
	return -1;
}

// set image list from a bitmap id
void CUIStatusBar::SetImageList(UINT nBitmapID)
{
	delete m_pImageList;
	m_pImageList = NULL;
	m_pImageList = new CImageList;
	m_pImageList->Create(nBitmapID,::GetSystemMetrics(SM_CXSMICON),0,::GetSysColor(COLOR_BTNFACE));
}

void CUIStatusBar::CreateImageList()
{
	delete m_pImageList;
	m_pImageList = new CImageList;
	m_pImageList->Create(::GetSystemMetrics(SM_CXSMICON),::GetSystemMetrics(SM_CYSMICON),ILC_MASK | ILC_COLOR16,0,1);
	m_pImageList->SetBkColor(CLR_NONE);
}

void CUIStatusBar::SetImageList(CImageList *pImageList)
{
	CreateImageList();
	// if one passed in copy it
	if (pImageList)
	{
		int count = pImageList->GetImageCount();
		for(int i=0;i < count;i++)
		{
			HICON hIcon = pImageList->ExtractIcon(i);
			m_pImageList->Add(hIcon);
		}
	}
}

void CUIStatusBar::AddPane(UINT nID,BOOL bActive)
{
	CStatusBarPane *pPane = new CStatusBarPane(nID,bActive);
	pPane->SetStyle(SBT_OWNERDRAW);
	m_PaneList.AddTail(pPane);
}

BOOL CUIStatusBar::SetPanes(BOOL bSave)
{
	int nSize = 0;
	CStatusBarPane *pPane = NULL;
	for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;) 
	{
		pPane = m_PaneList.GetPrev(pos);
		nSize += pPane->IsPaneActive();
	}
	UINT *pIndicators = new UINT[nSize];

	int nIndex = 0;
	for(pos = m_PaneList.GetHeadPosition();pos != NULL;) 
	{
		pPane = m_PaneList.GetNext(pos);
		if (pPane->IsPaneActive()) 
		{
			pIndicators[nIndex++] = pPane->GetCommandID();
		}
	}
	BOOL ret = SetIndicators(pIndicators, nSize);
	delete[] pIndicators;

	UINT nID, nStyle;
	int nWidth;
	for(pos = m_PaneList.GetTailPosition();pos != NULL;) 
	{
		pPane = m_PaneList.GetPrev(pos);
		if (pPane->IsPaneActive() && pPane->GetCommandID() != ID_SEPARATOR) 
		{
			int nIndex = GetPaneIndex(pPane->GetCommandID());
			GetPaneInfo(nIndex,nID,nStyle,nWidth);
			SetPaneInfo(nIndex,pPane->GetCommandID(),nStyle | pPane->GetStyle(),nWidth);
			SetPaneText(nIndex,_T(""));
		}
	}
	GetPaneInfo(0,nID,nStyle,nWidth);
	// First pane has its own style
	SetPaneInfo(0,nID,m_nStatusPane1Style,nWidth);
	if (bSave) 
	{
		// save to registry
		Save();
	}
	return ret;
}

void CUIStatusBar::Load()
{
	CWinApp *pApp = AfxGetApp();
	CString strPane;
	CStatusBarPane *pPane = NULL;
	int i=0;
	for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;i++) 
	{
		pPane = m_PaneList.GetPrev(pos);
		strPane.Format(_T("%s%d"),szPaneEntry,i);
		pPane->SetPaneActive(pApp->GetProfileInt(szSection,strPane,pPane->IsPaneActive()));      
	}
}

void CUIStatusBar::Save()
{
	CWinApp *pApp = AfxGetApp();
	CString strPane;
	CStatusBarPane *pPane = NULL;
	int i=0;
	for(POSITION pos = m_PaneList.GetTailPosition();pos != NULL;i++) 
	{
		pPane = m_PaneList.GetPrev(pos);
		strPane.Format(_T("%s%d"),szPaneEntry,i);
		pApp->WriteProfileInt(szSection,strPane,pPane->IsPaneActive());
	}
}

void CUIStatusBar::TogglePane(UINT nID)
{
	CStatusBarPane *pPane = GetPane(nID);
	if (pPane) 
	{
		pPane->SetPaneActive(!pPane->IsPaneActive());
		SetPanes(TRUE);
	}
}

void CUIStatusBar::SetText(UINT nPaneID,LPCTSTR szText,bool bUpdate)
{
	const CStatusBarPane *pPane = GetPane(nPaneID);
	ASSERT(pPane);
	SetTextPane(pPane,szText,bUpdate);
}

void CUIStatusBar::SetTextPane(const CStatusBarPane *pPane,LPCTSTR szText,bool bUpdate)
{
	if (!pPane->IsPaneActive())
		return;

	int nIndex = GetPaneIndex(pPane->GetCommandID());
	UINT nStyle;
	UINT nPaneID=pPane->GetCommandID();
	int nWidth;
	GetPaneInfo(nIndex, nPaneID, nStyle, nWidth);
	nStyle |= SBT_OWNERDRAW;
	if (nIndex != 0)
	{
		HGDIOBJ hOldFont = NULL;
		HFONT hFont = (HFONT)SendMessage(WM_GETFONT);
		CClientDC dc(NULL);
		if (hFont != NULL) 
			hOldFont = dc.SelectObject(hFont);
		CSize size = dc.GetTextExtent(szText);
		if (hOldFont != NULL) 
			dc.SelectObject(hOldFont);
		nWidth = size.cx;
	}
	SetPaneInfo(nIndex, nPaneID, nStyle, nWidth);
	SetPaneText(nIndex, szText, bUpdate);
	if (bUpdate)
		UpdateWindow();
}

void CUIStatusBar::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	CStatusBarPane *pPane = GetPane(GetPaneID(lpDrawItemStruct->itemID));
	if (pPane) 
	{
		// Get the pane rectangle and calculate text coordinates
		CRect rect(&lpDrawItemStruct->rcItem);
		CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
		COLORREF oldBkColor = pDC->SetBkColor(::GetSysColor(COLOR_BTNFACE));
		// draw the image
		CListImages &listImages = pPane->GetImageIndex();
		// make sure there is an image
		if (!listImages.IsEmpty()) 
		{
			for(POSITION pos=listImages.GetTailPosition();pos != NULL;)
			{
				m_pImageList->Draw(pDC,listImages.GetPrev(pos),CPoint(rect.left,rect.top),ILD_NORMAL);
				rect.left += ::GetSystemMetrics(SM_CXSMICON);
				rect.left += 5;
			}
		}
		// draw the text
		LPCTSTR pszText = (LPCTSTR)lpDrawItemStruct->itemData;
		// make sure there is text
		if (pszText)
		{
			UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_NOPREFIX | DT_VCENTER;
//			if (pPane->GetStyle() & SBPS_POPOUT)
//				nFormat |= DT_VCENTER;
//			else
//				nFormat |= DT_BOTTOM;
			pDC->DrawText(pszText,lstrlen(pszText),rect,nFormat);
		}
		pDC->SetBkColor(oldBkColor);
	}
}

void CUIStatusBar::Serialize(CArchive &ar)
{
	CStatusBar::Serialize(ar);
	m_PaneList.Serialize(ar);
}

template <> void AFXAPI SerializeElements <CStatusBarPane*> (CArchive& ar, CStatusBarPane **ppPane, int nCount)
{
    for (int i=0;i < nCount;i++,ppPane++)
    {
		if (ar.IsLoading())
		{
			ar >> *ppPane;
		}
		else
		{
			ar << *ppPane;
		}
    }
}


void CUIStatusBar::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CStatusBar::OnLButtonDown(nFlags, point);
}

BOOL CUIStatusBar::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
/*	if (theApp.IsLoading())
	{
		CPoint point;
		::GetCursorPos(&point);
		ScreenToClient(&point);
		CRect rect;
		GetItemRect(4,&rect);
		if (rect.PtInRect(point))
		{
			SetCursor(::LoadCursor(NULL,IDC_CROSS));
			return TRUE;
		}
	}
*/	
	return CStatusBar::OnSetCursor(pWnd, nHitTest, message);
}

////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CProgressBar, CProgressCtrl)
	
BEGIN_MESSAGE_MAP(CProgressBar, CProgressCtrl)
	//{{AFX_MSG_MAP(CProgressBar)
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CProgressBar::CProgressBar() : m_nPaneIndex(-1), m_pStatusBar(NULL)
{
}

CProgressBar::CProgressBar(int nPaneID, CUIStatusBar *pStatusBar, int MaxValue /* = 100 */)
{
	Create(nPaneID, pStatusBar, MaxValue);
}

CProgressBar::~CProgressBar()
{
	Clear();
}	

// Create the CProgressCtrl as a child of the status bar 
BOOL CProgressBar::Create(int nPaneID, CUIStatusBar *pStatusBar, int MaxValue)
{	
	m_pStatusBar = pStatusBar;
	m_nPaneIndex = pStatusBar->GetPaneIndex(nPaneID);
	if (m_nPaneIndex == -1)
		return FALSE;

	// Create the progress bar
	if (!CProgressCtrl::Create(WS_CHILD | WS_VISIBLE | PBS_SMOOTH, CRect(0,0,0,0), pStatusBar, 1))
		return FALSE;

	// Set range and step
	SetRange(0, MaxValue);
	SetStep(1);

	// Resize the control to its desired width
	Resize();

	return TRUE;
}

void CProgressBar::Clear()
{
}

void CProgressBar::SetRange(int nLower, int nUpper, int nStep /* = 1 */)	
{
	CProgressCtrl::SetRange(nLower, nUpper);
	CProgressCtrl::SetStep(nStep);
}

int CProgressBar::SetPos(int nPos)	 
{
	if (m_hWnd == NULL)
		return -1;
	ModifyStyle(0,WS_VISIBLE);
	return CProgressCtrl::SetPos(nPos);
}

int  CProgressBar::OffsetPos(int nPos) 
{ 
	if (m_hWnd == NULL)
		return -1;
	ModifyStyle(0,WS_VISIBLE);
	return CProgressCtrl::OffsetPos(nPos);
}

int  CProgressBar::SetStep(int nStep)
{ 
	if (m_hWnd == NULL)
		return -1;
	ModifyStyle(0,WS_VISIBLE);
	return CProgressCtrl::SetStep(nStep);	
}

int  CProgressBar::StepIt()			 
{ 
	if (m_hWnd == NULL)
		return -1;
	ModifyStyle(0,WS_VISIBLE);
	return CProgressCtrl::StepIt();	
}

void CProgressBar::Resize() 
{	
	ASSERT(m_pStatusBar);
	ASSERT(m_nPaneIndex != -1);

	if (!m_pStatusBar) 
		return;

	// Now get the rectangle in which we will draw the progress bar
	CRect rc;
	m_pStatusBar->GetItemRect (m_nPaneIndex, rc);	
	// Resize the window
	if (::IsWindow(m_hWnd))
	    MoveWindow(&rc);
}

BOOL CProgressBar::OnEraseBkgnd(CDC* pDC) 
{
	Resize();
	return CProgressCtrl::OnEraseBkgnd(pDC);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -