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

📄 multipanestatusbarex.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////////////////
// 
//	MultiPaneStatusBarEx.h
//
//  Author: Pablo Aliskevicius.
//  Copyright (C) 2004 Pablo Aliskevicius.
//
//  The code and information  is provided  by the  author and  copyright  holder 'as-is',
//  and any express or implied  warranties,  including,  but not  limited to, the implied
//  warranties of  merchantability and  fitness for a particular purpose  are disclaimed.
//  In no event shall the author or copyright holders be liable for any direct, indirect,
//  incidental, special, exemplary, or consequential damages (including,  but not limited
//  to, procurement of substitute goods or services;  loss of use,  data, or profits;  or
//  business  interruption)  however caused  and on any  theory of liability,  whether in
//  contract, strict liability,  or tort  (including negligence or otherwise)  arising in
//  any way out of the use of this software,  even if advised of the  possibility of such
//  damage.
//
/////////////////////////////////////////////////////////////////////////////////////////
//
// Classes in this file:
//
// CProgressBarInPaneImpl<T> - CMPSBarWithProgress, 
//							   CMPSBarWithProgressAndBMP, 
//                            [CMPSBarWithProgressAndAnimation - not implemented],
//							   CMPSBarWithAll
// CBitmapInPaneImpl<T>     -  CMPSBarWithBitmaps,
//                     		   CMPSBarWithProgressAndBMP,
//           				  [CMPSBarWithAnimAndBMP - not implemented ],
//							   CMPSBarWithAll
// CAnimationInPaneImpl<T>   - CMPSBarWithAnimation,
//                            [CMPSBarWithProgressAndAnimation - not implemented],
//           				  [CMPSBarWithAnimAndBMP - not implemented ],
//                             CMPSBarWithAll

// MultiPaneStatusBarWithProgress.h: interface for the CMPSBarWithProgress class.
//
// This class extends WTL::CMultiPaneStatusBarCtrl to support creating and updating a 
// progress bar in one of its panes, and moving that progress bar around.
//
// Usage:
// ======
//
//    Wherever you'd create a CMultiPaneStatusBarCtrl, create one of the CMPSBarWithXXXXX
//    classes instead (the one which provides the functionality you'll use).
//
//    Showing progress bars:
//	  ----------------------
//
//	     Show a progress bar using ProgCreate()	
//		 Hide it using ProgDestroyWindow()
//		 Display progress using ProgSetPos(), or ProgStepIt() after	ProgSetStep()
//		 All other functions of WTL::CProgressBarCtrl, version 7.1, are also exposed.
//
//    Showing bitmaps:
//	  ----------------
//
//		 Use SetBitmap() to display a bitmap. There are two versions of the function.
//		 Use DestroyBitmap() to hide the bitmap, and optionally call DestroyObject() 
//		 on its handle.
//
//    Showing animations:
//	  -------------------
//
//		 Use AnimCreate() to display an animation.
//	  	 Use AnimDestroyWindow() to close an animation.
//
//    Showing anything (I don't like it, so there's an #ifdef):
//	  ---------------------------------------------------------
//
//       #define MULTI_PANE_WITH_ANY before including this file.
//
//		 Use CMPSBarWithAll as your member variable.
//
//		 Use AttachWindow() to attach an HWND to a pane.
//		 Use DetachWindow() to detach that HWND from that pane.
//
//
/////////////////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_MULTIPANESTATUSBARWITHPROGRESS_H__D2F37B4C_6E3D_450D_94B5_B14D377226FA__INCLUDED_)
#define AFX_MULTIPANESTATUSBARWITHPROGRESS_H__D2F37B4C_6E3D_450D_94B5_B14D377226FA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __ATLCTRLS_H__
#error You have to include <ATLCTRLS.H> for CProgressBarCtrl, CStatic and CAnimateCtrl.
#endif
#ifndef __ATLCTRLX_H__
#error You have to include <ATLCTRLX.H> for CMultiPaneStatusBarCtrlImpl<T>.
#endif

/////////////////////////////////////////////////////////////////////////////////////////
// Implementation classes, meant to be inherited from (mixins).
/////////////////////////////////////////////////////////////////////////////////////////

template <class T>
class CProgressBarInPaneImpl
{
	public:
		typedef CProgressBarInPaneImpl<T> CThisClass;
		// Constructor, destructor...
		CProgressBarInPaneImpl<T>(): m_iProgressPane(-1) 
		{
		}
		virtual ~CProgressBarInPaneImpl<T>() 
		{
			ProgDestroyWindow();
		}
		// UpdatePanesLayout() override, to handle resizing the progress bar whenever relevant
		BOOL UpdatePanesLayout(void)
		{
			if (m_iProgressPane != -1)
			{
				T* pt = static_cast<T*>(this);
				RECT rc;
				pt->GetRect(m_iProgressPane, &rc);
				// ::InflateRect(&rc, -1, -1); 
				m_Progress.MoveWindow(&rc);
			}
			return TRUE; // Mixed function.
		}
		
		BEGIN_MSG_MAP(CProgressBarInPaneImpl<T>)
			MESSAGE_HANDLER(SB_SIMPLE, OnSimple)
		END_MSG_MAP()
			
		LRESULT OnSimple(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
		{
			if (::IsWindow(m_Progress.m_hWnd))
				m_Progress.ShowWindow(wParam ? SW_HIDE: SW_SHOW);

			bHandled = FALSE;
			return 0;
		}
		//////////////////////////////////////////////////////////////////////////////////
		// Prog* functions enable access to the contained CProgressBarCtrl. 
		// We'll expose most of its functionality, and a few additional bits.
		//////////////////////////////////////////////////////////////////////////////////

		BOOL ProgCreate(int iPane,         // Status pane where we'll create the progress bar.
			int nMin = 0, int nMax = 100,  // Progress bar initial range
			DWORD dwStyle = WS_CHILD | WS_VISIBLE | PBS_SMOOTH, // Progress bar styles
			DWORD dwExStyle = 0
			) 
		{
			// Check there is such a pane
			T* pt = static_cast<T*>(this);
			ATLASSERT(::IsWindow(pt->m_hWnd));
			if (iPane >= pt->m_nPanes)
				return FALSE;
			// Check there is not a progress bar already open.
			if (::IsWindow(m_Progress.m_hWnd))
				return FALSE;
			// Get the pane's rectangle
			RECT rc;
			pt->GetRect( iPane, &rc );
			// ::InflateRect(&rc, -1, -1); 
			
			// Create the window, using the status bar (this) as a parent.
			m_Progress.Create ( pt->m_hWnd, rc, NULL, dwStyle,  dwExStyle);
			// Set the progress bar's range and position
			m_Progress.SetRange ( nMin, nMax ); 
			m_Progress.SetPos ( nMin );   
			m_Progress.SetStep ( 1 );
			// Hold this, we'll need it to move around.
			m_iProgressPane = iPane;
			return TRUE;
		}
		// This function can be used to close a progress bar, after ending whatever 
		// lengthy operation justified opening it to begin with.
		void ProgDestroyWindow(void)
		{
			if (::IsWindow(m_Progress.m_hWnd))
			{
				m_Progress.ShowWindow(SW_HIDE);
				m_Progress.DestroyWindow();
			}
			m_iProgressPane = -1;
			m_Progress.m_hWnd = NULL;
		}
		// Just in case. 
		int   ProgGetPane() const                 { return m_iProgressPane; }
		//////////////////////////////////////////////////////////////////////////////////
		// CProgressBarCtrl functionality (WTL version 7.1):
		// CWindow functionality in CProgressBarCtrl is hidden by design.
		//
		DWORD ProgSetRange(int nLower, int nUpper)  { return m_Progress.SetRange(nLower, nUpper); }
		int   ProgSetPos(int nPos)                  { return m_Progress.SetPos(nPos); }
		int   ProgOffsetPos(int nPos)               { return m_Progress.OffsetPos(nPos); }
		int   ProgSetStep(int nStep)                { return m_Progress.SetStep(nStep); }
		UINT  ProgGetPos() const                    { return m_Progress.GetPos(); }
		
		void  ProgGetRange(PPBRANGE pPBRange) const { m_Progress.GetRange(pPBRange); } 
		int   ProgGetRangeLimit(BOOL bLimit)  const { return m_Progress.GetRangeLimit(bLimit); }
		DWORD ProgSetRange32(int nMin, int nMax)    { return m_Progress.SetRange32(nMin, nMax); }
		
#if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
		COLORREF ProgSetBarColor(COLORREF clr)      { return m_Progress.SetBarColor(clr); }
		COLORREF ProgSetBkColor(COLORREF clr)       { return m_Progress.SetBkColor(clr); }
#endif //(_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
		
#if (_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE)
		BOOL ProgSetMarquee(BOOL bMarquee, UINT uUpdateTime = 0U)
													{ return m_Progress.SetMarquee(bMarquee, uUpdateTime); }
#endif //(_WIN32_WINNT >= 0x0501) && defined(PBM_SETMARQUEE)
		int ProgStepIt()                            { return m_Progress.StepIt(); }
		
	protected:
	//////////////////////////////////////////////////////////////////////////////////
	// Member variables (of course, protected)
	//
		CProgressBarCtrl m_Progress;  // This is the contained control.
		int m_iProgressPane;          // Pane ordinal where the progress bar resides, or -1 when off.
	
}; // CProgressBarInPaneImpl


// This one also handles bitmaps

template <class T> class CBitmapInPaneImpl
{
public:
	// You can have up to 15 bitmaps per status bar.
	enum { MAX_MANAGED = 15 };

	BEGIN_MSG_MAP(CBitmapInPaneImpl<T>)
		MESSAGE_HANDLER(SB_SIMPLE, OnSimple)
	END_MSG_MAP()
	
	// Show bitmaps when the status bar is in multi pane state, hide them when it's simple.
	LRESULT OnSimple(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		int sw = (wParam) ? SW_HIDE: SW_SHOW;
		// Hide all children (static bitmaps)
		for (int i = 0; i < MAX_MANAGED; i++)
		{
			if (m_Manager[i].hw)
				::ShowWindow(m_Manager[i].hw, sw);
		}
		bHandled = false;
		return 0;
	}
	
	// Move bitmaps around to stay on top of their panes.
	BOOL UpdatePanesLayout(void)
	{
		RECT rc;	
		T *pT = static_cast<T*>(this);
		for (int i = 0;   i < MAX_MANAGED; i++)
		{
			if (m_Manager[i].hw)
			{
				pT->GetRect( m_Manager[i].iPane, &rc );
				// ::InflateRect(&rc, -1, -1); 
				CStatic cs(m_Manager[i].hw);
				cs.MoveWindow(&rc);
				cs.Invalidate();
			}
		} // for
		return TRUE;
	}
	// Add a bitmap to the status bar, in a pane chosen by ordinal.
	BOOL SetBitmap(int iPane,    // Zero based ordinal (not resource ID) of the chosen pane.
		           HBITMAP hbmp, // Handle to a bitmap.
		           bool bManage = false) // If true, DestroyObject() will be called on the HBITMAP.
	{
		if (NULL == hbmp)
			return false;
		// If the pane was in use, release it.
		if (!DestroyBitmap(iPane))
			return FALSE;
		// Use the first available array entry to put the selected bitmap.
		T *pT = static_cast<T *>(this);
		for (int i = 0; i < MAX_MANAGED; i++)
		{
			if (!m_Manager[i].hw)
			{
				RECT rct;
				pT->GetRect( iPane, &rct);
				// ::InflateRect(&rct, -1, -1);
				CStatic cs;
				cs.Create(pT->m_hWnd, rct,  NULL,
					WS_CHILDWINDOW | WS_VISIBLE | WS_DISABLED | SS_BITMAP | SS_LEFT | SS_SUNKEN, 
					WS_EX_NOPARENTNOTIFY, WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
				cs.SetBitmap(hbmp);
				m_Manager[i].hw = cs.m_hWnd;
				m_Manager[i].iPane = iPane;
				m_Manager[i].hbmp = hbmp;
				m_Manager[i].bManage = bManage;
				UpdatePanesLayout();
				return TRUE;
			}
		}
		return FALSE;
	}
	// Same as the former, but loads the bitmap from a resource.
	BOOL SetBitmap(int iPane, int iBmpResource)
	{
		HBITMAP hb = ::LoadBitmap(_Module.m_hInstResource, MAKEINTRESOURCE(iBmpResource));
		if (NULL == hb)
			return FALSE;
		// The caller has no access to the bitmap's handle, we MUST manage it from here.
		return SetBitmap(iPane, hb, true);
	}
	// If there is a bitmap in the selected pane, destroy it.
	BOOL DestroyBitmap(int iPane)
	{
		T *pT = static_cast<T *>(this);
		// Check we're really talking about a pane.
		if (iPane < 0 || iPane >= pT->m_nPanes)
			return FALSE;
		// Find the pane in the array.
		for (int i = 0; i < MAX_MANAGED; i++)
		{
			if (m_Manager[i].iPane == iPane)
			{
				// If the pane is in use, release whatever is there.
				if (m_Manager[i].bManage)
					::DeleteObject(m_Manager[i].hbmp);
				::DestroyWindow(m_Manager[i].hw);
				// Initialize array entry to suitable values.        
				m_Manager[i].Clear();
				break;
			}
		}
		return TRUE; // The pane is free.
	}
	CBitmapInPaneImpl<T>()
	{
	}
	
	virtual ~CBitmapInPaneImpl<T>()
	{
		// Destroy all windows, release all managed bitmaps.
		for (int i = 0; i < MAX_MANAGED; i++)
		{
			if (m_Manager[i].hw)
				::DestroyWindow(m_Manager[i].hw);
			if (m_Manager[i].bManage)
				::DeleteObject(m_Manager[i].hbmp);
		}
	}
	
   protected:
		// This class ties one bitmap/HWND/pane.	   
	   class CBmpManager
	   {
	   public:
		   HWND hw;
		   HBITMAP hbmp;
		   int iPane;
		   bool bManage; 
		   CBmpManager(): hw(NULL), hbmp(NULL), bManage(false), iPane(-1)
		   {}
		   void Clear(void)
		   {
				hbmp = NULL;
				hw = NULL;
				bManage = false;
				iPane = -1;
		   }
	   };  // class CBmpManager
	   CBmpManager m_Manager[MAX_MANAGED]; // 15 are more than enough, I hope.
	   
}; // class CBitmapInPaneImpl


template <class T>
class CAnimationInPaneImpl
{
public:
	CAnimationInPaneImpl<T>(): m_iAnimPane(-1) {}
	virtual ~CAnimationInPaneImpl<T>()
	{
		AnimDestroyWindow();

⌨️ 快捷键说明

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