CSplitterWnd扩展类实现隐藏/显示列Pan

这是一位仁兄的代码:
CSplitterWnd实现隐藏/显示列Pan
//////////////////////////////////////////////////////////////////
//
// splitex.h
// (c) 1997, Oleg G. Galkin

class CSplitterWndEx : public CSplitterWnd
{
protected:
   int m_nHidedCol;    // hide column number, -1 if all columns
                       // are shown

public:
    CSplitterWndEx();

   void ShowColumn();
   void HideColumn(int colHide);

// ClassWizard generated virtual function overrides
   //{{AFX_VIRTUAL(CSplitterWndEx)
   //}}AFX_VIRTUAL

// Generated message map functions
protected:
   //{{AFX_MSG(CSplitterWndEx)
      // NOTE - the ClassWizard will add and remove member
      //         functions here.
      //}}AFX_MSG

     DECLARE_MESSAGE_MAP()
};

//////////////////////////////////////////////////////////////////
//
// splitex.cpp
// (c) 1997, Oleg G. Galkin

#include "stdafx.h"
#include "splitex.h"

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

//////////////////////////////////////////////////////////////////
/
// CSplitterWndEx

CSplitterWndEx::CSplitterWndEx()
:m_nHidedCol(-1)
{
}

void CSplitterWndEx::ShowColumn()
{
    ASSERT_VALID(this);
    ASSERT(m_nCols < m_nMaxCols);
    ASSERT(m_nHidedCol != -1);

   int colNew = m_nHidedCol;
    m_nHidedCol = -1;
   int cxNew = m_pColInfo[m_nCols].nCurSize;
    m_nCols++;    // add a column
    ASSERT(m_nCols == m_nMaxCols);

   // fill the hidden column
   int col;
   for (int row = 0; row < m_nRows; row++)
    {
       CWnd* pPaneShow = GetDlgItem(
          AFX_IDW_PANE_FIRST + row * 16 + m_nCols);
       ASSERT(pPaneShow != NULL);
       pPaneShow->ShowWindow(SW_SHOWNA);

      for (col = m_nCols - 2; col >= colNew; col--)
       {
          CWnd* pPane = GetPane(row, col);
          ASSERT(pPane != NULL);
          pPane->SetDlgCtrlID(IdFromRowCol(row, col + 1));
       }

       pPaneShow->SetDlgCtrlID(IdFromRowCol(row, colNew));
    }

   // new panes have been created -- recalculate layout
   for (col = colNew + 1; col < m_nCols; col++)
       m_pColInfo[col].nIdealSize = m_pColInfo[col - 1].nCurSize;
    m_pColInfo[colNew].nIdealSize = cxNew;
    RecalcLayout();
}

void CSplitterWndEx::HideColumn(int colHide)
{
    ASSERT_VALID(this);
    ASSERT(m_nCols > 1);
    ASSERT(colHide < m_nCols);
    ASSERT(m_nHidedCol == -1);
    m_nHidedCol = colHide;

   // if the column has an active window -- change it
   int rowActive, colActive;
   if (GetActivePane(&rowActive, &colActive) != NULL &&
        colActive == colHide)
    {
      if (++colActive >= m_nCols)
          colActive = 0;
       SetActivePane(rowActive, colActive);
    }

   // hide all column panes
   for (int row = 0; row < m_nRows; row++)
    {
       CWnd* pPaneHide = GetPane(row, colHide);
       ASSERT(pPaneHide != NULL);
       pPaneHide->ShowWindow(SW_HIDE);
       pPaneHide->SetDlgCtrlID(
          AFX_IDW_PANE_FIRST + row * 16 + m_nCols);

      for (int col = colHide + 1; col < m_nCols; col++)
       {
          CWnd* pPane = GetPane(row, col);
          ASSERT(pPane != NULL);
          pPane->SetDlgCtrlID(IdFromRowCol(row, col - 1));
       }
    }
    m_nCols--;
    m_pColInfo[m_nCols].nCurSize = m_pColInfo[colHide].nCurSize;
     RecalcLayout();
}

BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
//{{AFX_MSG_MAP(CSplitterWndEx)
   // NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


视图分割,以前写的代码,今天也要用到,加了些新的东西,跟大家分享一下。。视图分割,视图隐藏等,分割条的移动与否。
下面是代码:

头文件:
#pragma once
#include "afxext.h"
#include "2DArray.h"

class CSplitterWndEx :
	public CSplitterWnd
{
public:
	CSplitterWndEx(void);
	virtual ~CSplitterWndEx();
	typedef std::list<int> LIST_INT;//模板函数

	// Attributes
public:

	// Operations
public:
	void	ShowColumn();//显示列视图
	void	HideColumn(int colHide);//隐藏列视图

	BOOL	CreateStatic(CWnd* pParentWnd,int nRows,int nCols,
		DWORD dwStyle=WS_CHILD|WS_VISIBLE,UINT nID=AFX_IDW_PANE_FIRST);
	void	Init();//初始化
	BOOL	CreateView(int row,int col,CRuntimeClass* pViewClass,SIZE sizeInit,CCreateContext* pContext);

protected:
	void	RenumeratePanes();
	void	RemoveColInfo(int place,int col);
	CPoint	RelToAbsPosition(int i, int j);
	int		RelToAbsPosition(LIST_INT &vis_list, LIST_INT &hid_list, int cur_index);
	BOOL	IsPaneVisible(int row, int col);
	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CSplitterWndEx)
	//}}AFX_VIRTUAL

	// Implementation
public:
	void OnInvertTracker(const CRect& rect);
	void OnDrawSplitter( CDC* pDC, ESplitType nType, const CRect& rectArg );

	// Generated message map functions
protected:
	//{{AFX_MSG(CSplitterWndEx)
	DECLARE_MESSAGE_MAP()
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

public:
	LIST_INT m_shown_cols;		//shown  column list
	LIST_INT m_hid_cols;		//hidden column list

	LIST_INT m_shown_rows;		//shown  rows list
	LIST_INT m_hid_rows;		//hidden rows list
protected:
	C2DArray m_pane_ptr_array;	// array of pointers to splitter panes
	CRowColInfo* m_pSavedColInfo;
	CRowColInfo* m_pSavedRowInfo;
protected:
	int m_nHidedCol;    // hide column number, -1 if all columns
};
#include "StdAfx.h"
#include "SplitterWndEx.h"

CSplitterWndEx::CSplitterWndEx()
{
	//更改分割条和窗格间距大小
	m_cxSplitter = m_cySplitter = 1;
	m_cxSplitterGap = m_cySplitterGap = 1;
}

CSplitterWndEx::~CSplitterWndEx()
{
	if(m_pSavedColInfo != NULL)
	{
		delete []m_pSavedColInfo;
		m_pSavedColInfo = NULL;
	}
	if(m_pSavedRowInfo != NULL)
	{
		delete []m_pSavedRowInfo;
		m_pSavedRowInfo = NULL;
	}
}

BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
END_MESSAGE_MAP()

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

	CWnd::OnLButtonDown(nFlags, point);
}

void CSplitterWndEx::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default

	CWnd::OnMouseMove(nFlags, point);
}

BOOL CSplitterWndEx::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	// TODO: Add your message handler code here and/or call default

	return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

//绘制分割窗口特征
void CSplitterWndEx::OnDrawSplitter( CDC* pDC, ESplitType nType, const CRect& rectArg)
{
	if (pDC == NULL)
	{
		RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN);
		return;
	}
	ASSERT_VALID(pDC);

	// otherwise, actually draw
	CRect rc = rectArg;
	switch(nType) 
	{ 
	case splitBorder:
		//重画分割窗口边界,使为绿色
		pDC->Draw3dRect(rc,RGB(0,200,0),RGB(0,200,0));
		rc.InflateRect(-1,-1); 
		pDC->Draw3dRect(rc,RGB(0,100,0),RGB(0,100,0)); 
		return; 
	case splitBox:
		pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
		rc.InflateRect(-1,-1); 
		pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
		rc.InflateRect(-1,-1);
		pDC->FillSolidRect(rc,RGB(0,0,0)); 
		pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
		return; 
	case splitBar: 
		//重画分割条,使之为绿色 
		pDC->FillSolidRect(rc,RGB(0,80,0));
		rc.InflateRect(-1,-1); 
		pDC->Draw3dRect(rc,RGB(0,0,200),RGB(0,0,200));		
		return; 
	default: 
		ASSERT(FALSE); 
	} 
	// fill the middle
	pDC->FillSolidRect(rc,RGB(0,200,0));
}

//绘制分割条
void CSplitterWndEx::OnInvertTracker(const CRect& rect)
{
	ASSERT_VALID(this);
	ASSERT(!rect.IsRectEmpty());
	ASSERT((GetStyle() & WS_CLIPCHILDREN) == 0);

	// pat-blt without clip children on
	CDC* pDC = GetDC();
	//翻转画刷模式
	CBrush* pBrush = CDC::GetHalftoneBrush();
	HBRUSH hOldBrush = NULL;
	if (pBrush != NULL)
		hOldBrush = (HBRUSH)SelectObject(pDC->m_hDC, pBrush->m_hObject);

	//在设备上下文创建位模式
	pDC->PatBlt(rect.left,rect.top,rect.Width(),rect.Height(),PATINVERT);

	if (hOldBrush != NULL)
		SelectObject(pDC->m_hDC, hOldBrush);
	ReleaseDC(pDC);
}

void CSplitterWndEx::ShowColumn()
{
	ASSERT_VALID(this);
	ASSERT(m_nCols < m_nMaxCols);
	ASSERT(m_nHidedCol != -1);

	int colNew = m_nHidedCol;
	m_nHidedCol = -1;
	int cxNew = m_pColInfo[m_nCols].nCurSize;
	m_nCols++;    // add a column
	ASSERT(m_nCols == m_nMaxCols);

	// fill the hidden column
	int col;
	for (int row = 0; row < m_nRows; row++)
	{
		CWnd* pPaneShow = GetDlgItem(
			AFX_IDW_PANE_FIRST + row * 16 + m_nCols);
		ASSERT(pPaneShow != NULL);
		pPaneShow->ShowWindow(SW_SHOWNA);

		for (col = m_nCols - 2; col >= colNew; col--)
		{
			CWnd* pPane = GetPane(row, col);
			ASSERT(pPane != NULL);
			pPane->SetDlgCtrlID(IdFromRowCol(row, col + 1));
		}

		pPaneShow->SetDlgCtrlID(IdFromRowCol(row, colNew));
	}

	// new panes have been created -- recalculate layout
	for (col = colNew + 1; col < m_nCols; col++)
		m_pColInfo[col].nIdealSize = m_pColInfo[col - 1].nCurSize;
	m_pColInfo[colNew].nIdealSize = cxNew;
	RecalcLayout();
}

//隐藏视图
void CSplitterWndEx::HideColumn(int colHide)
{
	ASSERT_VALID(this);
	ASSERT(m_nCols > 1);
	ASSERT(colHide < m_nCols);
	ASSERT(m_nHidedCol != -1);
	m_nHidedCol = colHide;

	// if the column has an active window -- change it
	int rowActive, colActive;
	if (GetActivePane(&rowActive, &colActive) != NULL &&
		colActive == colHide)
	{
		if (++colActive >= m_nCols)
			colActive = 0;
		SetActivePane(rowActive, colActive);
	}

	// hide all column panes
	for (int row = 0; row < m_nRows; row++)
	{
		CWnd* pPaneHide = GetPane(row, colHide);
		ASSERT(pPaneHide != NULL);
		pPaneHide->ShowWindow(SW_HIDE);
		pPaneHide->SetDlgCtrlID(
			AFX_IDW_PANE_FIRST + row * 16 + m_nCols);

		for (int col = colHide + 1; col < m_nCols; col++)
		{
			CWnd* pPane = GetPane(row, col);
			ASSERT(pPane != NULL);
			pPane->SetDlgCtrlID(IdFromRowCol(row, col - 1));
		}
	}
	m_nCols--;
	m_pColInfo[m_nCols].nCurSize = m_pColInfo[colHide].nCurSize;
	RecalcLayout();
}

//重载静态视图创建
BOOL CSplitterWndEx::CreateStatic(CWnd* pParentWnd,int nRows,int nCols,DWORD dwStyle,UINT nID)
{
	BOOL ret;
	ret= CSplitterWnd::CreateStatic(pParentWnd,nRows,nCols,dwStyle,nID);
	Init();
	return ret;
}

void CSplitterWndEx::Init()//初始化
{
	int i,j;	
	m_pane_ptr_array.Init(m_nMaxRows,m_nMaxCols);
	for(i=0; i<m_nMaxRows; i++){
		m_shown_rows.push_back(i);
	}
	for(j=0; j<m_nMaxCols; j++){
		m_shown_cols.push_back(j);
	}	
	m_pSavedColInfo = new CRowColInfo[m_nMaxCols];
	m_pSavedRowInfo = new CRowColInfo[m_nMaxRows];
}

//重载视图创建
BOOL CSplitterWndEx::CreateView(int row,int col,CRuntimeClass* pViewClass,SIZE sizeInit,CCreateContext* pContext )
{
	BOOL ret = CSplitterWnd::CreateView(row, col, pViewClass, sizeInit, pContext );
	CWnd* pWnd = GetPane(row,col);
	ASSERT(pWnd);
	m_pane_ptr_array(row,col)= pWnd;
	return ret;
}

void CSplitterWndEx::RenumeratePanes()
{
	int i,j,id;	
	for(i=0; i<m_nMaxRows; i++){
		for(j=0;j<m_nMaxCols;j++){
			CPoint pos	= RelToAbsPosition(i,j);
			CWnd* pPane = (CWnd*) m_pane_ptr_array(pos.x, pos.y);
			ASSERT(pPane != NULL);			
			id=AFX_IDW_PANE_FIRST+i*16+j;			
			int r=pPane->SetDlgCtrlID(id);
			ASSERT(r);			
			if(IsPaneVisible(pos.x,pos.y))
				pPane->ShowWindow(SW_SHOW);
			else
				pPane->ShowWindow(SW_HIDE);		
		}		
	}
}

void CSplitterWndEx::RemoveColInfo(int place,int col)
{
	ASSERT(m_nCols<=m_nMaxCols);
	m_pSavedColInfo[col] = m_pColInfo[place];
	for(int i=place; i<m_nCols; i++){
		m_pColInfo[i] = m_pColInfo[i+1];
	}
}

CPoint CSplitterWndEx::RelToAbsPosition(int row,int col)
{
	CPoint pos;
	pos.x = RelToAbsPosition(m_shown_rows, m_hid_rows,row);
	pos.y = RelToAbsPosition(m_shown_cols, m_hid_cols,col);
	return pos;
}

int	CSplitterWndEx::RelToAbsPosition(LIST_INT &vis_list, LIST_INT &hid_list, int cur_index)
{
	int org_index;
	int i;
	LIST_INT::iterator it;
	if( cur_index < (int)vis_list.size()){
		it=vis_list.begin();
		for(i=0;i<cur_index; i++){
			it++;
		}		
		org_index = *it;
	}
	else{
		it=hid_list.begin();
		for(i=0;i<cur_index-(int)vis_list.size(); i++){
			it++;
		}
		org_index = *it;
	}
	return org_index;
}

BOOL CSplitterWndEx::IsPaneVisible(int row, int col)
{
	BOOL  bRow, bCol;	
	ASSERT(m_nRows<=m_nMaxCols);	
	if( m_shown_rows.end() != std::find(m_shown_rows.begin(),m_shown_rows.end(),row)){
		bRow = TRUE;	
	}
	else{
		bRow=FALSE;
	}	
	ASSERT(m_nCols<=m_nMaxCols);	
	if( m_shown_cols.end() != std::find(m_shown_cols.begin(),m_shown_cols.end(),col)){
		bCol = TRUE;	
	}
	else{
		bCol=FALSE;
	}	
	return bRow && bCol;
}


你可能感兴趣的:(list,null,delete,iterator,扩展,Pointers)