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

📄 dlgsplitter.cpp

📁 一个关于局域网简单抓包工具
💻 CPP
📖 第 1 页 / 共 5 页
字号:

#include "stdafx.h"

#ifdef AFX_CORE3_SEG
#pragma code_seg(AFX_CORE3_SEG)
#endif

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

/////////////////////////////////////////////////////////////////////////////
// Visual attributes and other constants

// HitTest return values (values and spacing between values is important)
enum HitTestValue
{
	noHit                   = 0,		//表示没有选中任何对象
	vSplitterBox            = 1,
	hSplitterBox            = 2,
	bothSplitterBox         = 3,        // just for keyboard
	vSplitterBar1           = 101,		//代表各个方向的水平分割条
	vSplitterBar15          = 115,
	hSplitterBar1           = 201,		//代表垂直方向的各个分割条
	hSplitterBar15          = 215,
	splitterIntersection1   = 301,		//代表各个交叉点
	splitterIntersection225 = 525
};

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd

BEGIN_MESSAGE_MAP(CDlgSplitterWnd, CWnd)
	//{{AFX_MSG_MAP(CDlgSplitterWnd)
	ON_WM_SETCURSOR()
	ON_WM_MOUSEMOVE()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_LBUTTONUP()
	ON_WM_KEYDOWN()
	ON_WM_SIZE()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_NCCREATE()
	ON_WM_SYSCOMMAND()
	ON_WM_CANCELMODE()
	ON_MESSAGE_VOID(WM_DISPLAYCHANGE, OnDisplayChange)
	ON_MESSAGE_VOID(WM_WININICHANGE, OnDisplayChange)
	ON_MESSAGE_VOID(WM_SETTINGCHANGE, OnDisplayChange)
	ON_WM_MOUSEWHEEL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd construction/destruction

CDlgSplitterWnd::CDlgSplitterWnd()
{
	AFX_ZERO_INIT_OBJECT(CWnd);

	// default splitter box/bar sizes (includes borders)
	if (!afxData.bWin4)
	{
		m_cxSplitter = m_cySplitter = 4;
		m_cxBorderShare = m_cyBorderShare = 1;
		m_cxSplitterGap = m_cySplitterGap = 4 + 1 + 1;
		ASSERT(m_cxBorder == 0 && m_cyBorder == 0);
	}
	else
	{
		m_cxSplitter = m_cySplitter = 3 + 2 + 2;
		m_cxBorderShare = m_cyBorderShare = 0;
		m_cxSplitterGap = m_cySplitterGap = 3 + 2 + 2;
		m_cxBorder = m_cyBorder = 2;
	}

#ifdef _DEBUG
	if (GetSystemMetrics(SM_CXBORDER) != 1 ||
		GetSystemMetrics(SM_CYBORDER) != 1)
	{
		TRACE0("Warning: CDlgSplitterWnd assumes 1 pixel border.\n");
		// will look ugly if borders are not 1 pixel wide and 1 pixel high
	}
#endif
}

CDlgSplitterWnd::~CDlgSplitterWnd()
{
	delete[] m_pRowInfo;
	delete[] m_pColInfo;
}

BOOL CDlgSplitterWnd::Create(CWnd* pParentWnd,
	int nMaxRows, int nMaxCols, SIZE sizeMin,
	CCreateContext* pContext, DWORD dwStyle, UINT nID)
{
	ASSERT(pParentWnd != NULL);
	ASSERT(sizeMin.cx > 0 && sizeMin.cy > 0);   // minimum must be non-zero

	ASSERT(pContext != NULL);
	ASSERT(pContext->m_pNewViewClass != NULL);
	ASSERT(dwStyle & WS_CHILD);
	ASSERT(dwStyle & SPLS_DYNAMIC_SPLIT);   // must have dynamic split behavior

	// Dynamic splitters are limited to 2x2
	ASSERT(nMaxRows >= 1 && nMaxRows <= 2);
	ASSERT(nMaxCols >= 1 && nMaxCols <= 2);
	ASSERT(nMaxCols > 1 || nMaxRows > 1);       // 1x1 is not permitted

	m_nMaxRows = nMaxRows;
	m_nMaxCols = nMaxCols;
	ASSERT(m_nRows == 0 && m_nCols == 0);       // none yet
	m_nRows = m_nCols = 1;      // start off as 1x1
	if (!CreateCommon(pParentWnd, sizeMin, dwStyle, nID))
		return FALSE;
	ASSERT(m_nRows == 1 && m_nCols == 1);       // still 1x1

	ASSERT(pContext->m_pNewViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
	m_pDynamicViewClass = pContext->m_pNewViewClass;
		// save for later dynamic creations

	// add the first initial pane
	if (!CreateView(0, 0, m_pDynamicViewClass, sizeMin, pContext))
	{
		DestroyWindow(); // will clean up child windows
		return FALSE;
	}
	m_pColInfo[0].nIdealSize = sizeMin.cx;
	m_pRowInfo[0].nIdealSize = sizeMin.cy;

	return TRUE;
}

// simple "wiper" splitter
BOOL CDlgSplitterWnd::CreateStatic(CWnd* pParentWnd,
	int nRows, int nCols, DWORD dwStyle, UINT nID)
{
	ASSERT(pParentWnd != NULL);
	ASSERT(nRows >= 1 && nRows <= 16);
	ASSERT(nCols >= 1 && nCols <= 16);
	ASSERT(nCols > 1 || nRows > 1);     // 1x1 is not permitted
	ASSERT(dwStyle & WS_CHILD);
	ASSERT(!(dwStyle & SPLS_DYNAMIC_SPLIT)); // can't have dynamic split

	ASSERT(m_nRows == 0 && m_nCols == 0);       // none yet
	m_nRows = m_nMaxRows = nRows;
	m_nCols = m_nMaxCols = nCols;

	// create with zero minimum pane size
	if (!CreateCommon(pParentWnd, CSize(0, 0), dwStyle, nID))
		return FALSE;

	// all panes must be created with explicit calls to CreateView
	return TRUE;
}

BOOL CDlgSplitterWnd::CreateCommon(CWnd* pParentWnd,
	SIZE sizeMin, DWORD dwStyle, UINT nID)
{
	ASSERT(pParentWnd != NULL);
	ASSERT(sizeMin.cx >= 0 && sizeMin.cy >= 0);
	ASSERT(dwStyle & WS_CHILD);
	ASSERT(nID != 0);

	ASSERT(m_pColInfo == NULL && m_pRowInfo == NULL);   // only do once
	ASSERT(m_nMaxCols > 0 && m_nMaxRows > 0);

	// the Windows scroll bar styles bits turn on the smart scrollbars
	DWORD dwCreateStyle = dwStyle & ~(WS_HSCROLL|WS_VSCROLL);
	if (afxData.bWin4)
		dwCreateStyle &= ~WS_BORDER;

	VERIFY(AfxDeferRegisterClass(AFX_WNDMDIFRAME_REG));

	// create with the same wnd-class as MDI-Frame (no erase bkgnd)
	if (!CreateEx(0, _afxWndMDIFrame, NULL, dwCreateStyle, 0, 0, 0, 0,
	  pParentWnd->m_hWnd, (HMENU)nID, NULL))
		return FALSE;       // create invisible

	// attach the initial splitter parts
	TRY
	{
		m_pColInfo = new CRowColInfo[m_nMaxCols];
		for (int col = 0; col < m_nMaxCols; col++)
		{
			m_pColInfo[col].nMinSize = m_pColInfo[col].nIdealSize = sizeMin.cx;
			m_pColInfo[col].nCurSize = -1; // will be set in RecalcLayout
		}
		m_pRowInfo = new CRowColInfo[m_nMaxRows];
		for (int row = 0; row < m_nMaxRows; row++)
		{
			m_pRowInfo[row].nMinSize = m_pRowInfo[row].nIdealSize = sizeMin.cy;
			m_pRowInfo[row].nCurSize = -1; // will be set in RecalcLayout
		}

		// create scroll bars by setting the style
		SetScrollStyle(dwStyle);
	}
	CATCH_ALL(e)
	{
		DestroyWindow(); // will clean up child windows
		// Note: DELETE_EXCEPTION(e) not required
		return FALSE;
	}
	END_CATCH_ALL

	return TRUE;
}

BOOL CDlgSplitterWnd::OnNcCreate(LPCREATESTRUCT lpcs)
{
	if (!CWnd::OnNcCreate(lpcs))
		return FALSE;

	// remove WS_EX_CLIENTEDGE style from parent window
	//  (the splitter itself will provide the 3d look)
	CWnd* pParent = GetParent();
	ASSERT_VALID(pParent);
	pParent->ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_DRAWFRAME);

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd default creation of parts

// You must create ALL panes unless DYNAMIC_SPLIT is defined!
//  Usually the splitter window is invisible when creating a pane
BOOL CDlgSplitterWnd::CreateView(int row, int col,
	CRuntimeClass* pViewClass, SIZE sizeInit, CCreateContext* pContext)
{
#ifdef _DEBUG
	ASSERT_VALID(this);
	ASSERT(row >= 0 && row < m_nRows);
	ASSERT(col >= 0 && col < m_nCols);
	ASSERT(pViewClass != NULL);
	ASSERT(pViewClass->IsDerivedFrom(RUNTIME_CLASS(CWnd)));
	ASSERT(AfxIsValidAddress(pViewClass, sizeof(CRuntimeClass), FALSE));

	if (GetDlgItem(IdFromRowCol(row, col)) != NULL)
	{
		TRACE2("Error: CreateView - pane already exists for row %d, col %d.\n",
			row, col);
		ASSERT(FALSE);
		return FALSE;
	}
#endif

	// set the initial size for that pane
	m_pColInfo[col].nIdealSize = sizeInit.cx;
	m_pRowInfo[row].nIdealSize = sizeInit.cy;

	BOOL bSendInitialUpdate = FALSE;

	CCreateContext contextT;
	if (pContext == NULL)
	{
		// if no context specified, generate one from the currently selected
		//  client if possible
		CView* pOldView = (CView*)GetActivePane();
		if (pOldView != NULL && pOldView->IsKindOf(RUNTIME_CLASS(CView)))
		{
			// set info about last pane
			ASSERT(contextT.m_pCurrentFrame == NULL);
			contextT.m_pLastView = pOldView;
			contextT.m_pCurrentDoc = pOldView->GetDocument();
			if (contextT.m_pCurrentDoc != NULL)
				contextT.m_pNewDocTemplate =
				  contextT.m_pCurrentDoc->GetDocTemplate();
		}
		pContext = &contextT;
		bSendInitialUpdate = TRUE;
	}

	CWnd* pWnd;
	TRY
	{
		pWnd = (CWnd*)pViewClass->CreateObject();
		if (pWnd == NULL)
			AfxThrowMemoryException();
	}
	CATCH_ALL(e)
	{
		TRACE0("Out of memory creating a splitter pane.\n");
		// Note: DELETE_EXCEPTION(e) not required
		return FALSE;
	}
	END_CATCH_ALL

	ASSERT_KINDOF(CWnd, pWnd);
	ASSERT(pWnd->m_hWnd == NULL);       // not yet created

	DWORD dwStyle = AFX_WS_DEFAULT_VIEW;
	if (afxData.bWin4)
		dwStyle &= ~WS_BORDER;

	// Create with the right size (wrong position)
	CRect rect(CPoint(0,0), sizeInit);
	if (!pWnd->Create(NULL, NULL, dwStyle,
		rect, this, IdFromRowCol(row, col), pContext))
	{
		TRACE0("Warning: couldn't create client pane for splitter.\n");
			// pWnd will be cleaned up by PostNcDestroy
		return FALSE;
	}
	ASSERT((int)_AfxGetDlgCtrlID(pWnd->m_hWnd) == IdFromRowCol(row, col));

	// send initial notification message
	if (bSendInitialUpdate)
		pWnd->SendMessage(WM_INITIALUPDATE);

	return TRUE;
}

BOOL CDlgSplitterWnd::CreateScrollBarCtrl(DWORD dwStyle, UINT nID)
{
	ASSERT_VALID(this);
	ASSERT(m_hWnd != NULL);

	HWND hWnd = ::CreateWindow(_T("SCROLLBAR"), NULL,
		dwStyle | WS_VISIBLE | WS_CHILD,
		0, 0, 1, 1, m_hWnd, (HMENU)nID,
		AfxGetInstanceHandle(), NULL);

#ifdef _DEBUG
	if (hWnd == NULL)
		TRACE1("Warning: Window creation failed: GetLastError returns 0x%8.8X\n",
			GetLastError());
#endif

	return hWnd != NULL;
}

int CDlgSplitterWnd::IdFromRowCol(int row, int col) const
{
	ASSERT_VALID(this);
	ASSERT(row >= 0);
	ASSERT(row < m_nRows);
	ASSERT(col >= 0);
	ASSERT(col < m_nCols);

	return AFX_IDW_PANE_FIRST + row * 16 + col;
}

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd attributes

CWnd* CDlgSplitterWnd::GetPane(int row, int col) const
{
	ASSERT_VALID(this);

	CWnd* pView = GetDlgItem(IdFromRowCol(row, col));
	ASSERT(pView != NULL);  // panes can be a CWnd, but are usually CViews
	return pView;
}

BOOL CDlgSplitterWnd::IsChildPane(CWnd* pWnd, int* pRow, int* pCol)
{
	ASSERT_VALID(this);
	ASSERT_VALID(pWnd);

	UINT nID = _AfxGetDlgCtrlID(pWnd->m_hWnd);
	if (IsChild(pWnd) && nID >= AFX_IDW_PANE_FIRST && nID <= AFX_IDW_PANE_LAST)
	{
		if (pRow != NULL)
			*pRow = (nID - AFX_IDW_PANE_FIRST) / 16;
		if (pCol != NULL)
			*pCol = (nID - AFX_IDW_PANE_FIRST) % 16;
		ASSERT(pRow == NULL || *pRow < m_nRows);
		ASSERT(pCol == NULL || *pCol < m_nCols);
		return TRUE;
	}
	else
	{
		if (pRow != NULL)
			*pRow = -1;
		if (pCol != NULL)
			*pCol = -1;
		return FALSE;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd information access

// The get routines return the current size
// The set routines set the ideal size
//  RecalcLayout must be called to update current size

void CDlgSplitterWnd::GetRowInfo(int row, int& cyCur, int& cyMin) const
{
	ASSERT_VALID(this);
	ASSERT(row >= 0 && row < m_nMaxRows);

	cyCur = m_pRowInfo[row].nCurSize;
	cyMin = m_pRowInfo[row].nMinSize;
}

void CDlgSplitterWnd::SetRowInfo(int row, int cyIdeal, int cyMin)
{
	ASSERT_VALID(this);
	ASSERT(row >= 0 && row < m_nMaxRows);
	ASSERT(cyIdeal >= 0);
	ASSERT(cyMin >= 0);

	m_pRowInfo[row].nIdealSize = cyIdeal;
	m_pRowInfo[row].nMinSize = cyMin;
}

void CDlgSplitterWnd::GetColumnInfo(int col, int& cxCur, int& cxMin) const
{
	ASSERT_VALID(this);
	ASSERT(col >= 0 && col < m_nMaxCols);

	cxCur = m_pColInfo[col].nCurSize;
	cxMin = m_pColInfo[col].nMinSize;
}

void CDlgSplitterWnd::SetColumnInfo(int col, int cxIdeal, int cxMin)
{
	ASSERT_VALID(this);
	ASSERT(col >= 0 && col < m_nMaxCols);
	ASSERT(cxIdeal >= 0);
	ASSERT(cxMin >= 0);

	m_pColInfo[col].nIdealSize = cxIdeal;
	m_pColInfo[col].nMinSize = cxMin;
}

DWORD CDlgSplitterWnd::GetScrollStyle() const
{
	DWORD dwStyle = 0;
	if (m_bHasHScroll)
		dwStyle |= WS_HSCROLL;
	if (m_bHasVScroll)
		dwStyle |= WS_VSCROLL;
	return dwStyle;
}

void CDlgSplitterWnd::SetScrollStyle(DWORD dwStyle)
{
	// optimize for scroll info already set correctly
	dwStyle &= (WS_HSCROLL|WS_VSCROLL);
	if (GetScrollStyle() == dwStyle)
		return;

	// update to new state
	m_bHasHScroll = (dwStyle & WS_HSCROLL) != 0;
	m_bHasVScroll = (dwStyle & WS_VSCROLL) != 0;

	CWnd* pScrollBar;

	// show/hide all the shared horz scroll bars
	for (int col = 0; col < m_nCols; col++)
	{
		pScrollBar = GetDlgItem(AFX_IDW_HSCROLL_FIRST + col);
		if (pScrollBar == NULL)
		{
			// create the scroll bar when necessary
			if (!CreateScrollBarCtrl(SBS_HORZ, AFX_IDW_HSCROLL_FIRST + col))
				AfxThrowResourceException();
			pScrollBar = GetDlgItem(AFX_IDW_HSCROLL_FIRST + col);
		}
		pScrollBar->ShowWindow(m_bHasHScroll ? SW_SHOW : SW_HIDE);
	}

	// show/hide all the shared vert scroll bars
	for (int row = 0; row < m_nRows; row++)
	{
		pScrollBar = GetDlgItem(AFX_IDW_VSCROLL_FIRST + row);
		if (pScrollBar == NULL)
		{

⌨️ 快捷键说明

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