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

📄 dlgsplitter.cpp

📁 一个关于局域网简单抓包工具
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			// create the scroll bar when necessary
			if (!CreateScrollBarCtrl(SBS_VERT, AFX_IDW_VSCROLL_FIRST + row))
				AfxThrowResourceException();
			pScrollBar = GetDlgItem(AFX_IDW_VSCROLL_FIRST + row);
		}
		pScrollBar->ShowWindow(m_bHasVScroll ? SW_SHOW : SW_HIDE);
	}

	// show/destroy size box if necessary
	if (m_bHasVScroll && m_bHasHScroll)
	{
		pScrollBar = GetDlgItem(AFX_IDW_SIZE_BOX);
		if (pScrollBar == NULL)
		{
			// create size box when necessary
			if (!CreateScrollBarCtrl(SBS_SIZEBOX|WS_DISABLED, AFX_IDW_SIZE_BOX))
				AfxThrowResourceException();
			pScrollBar = GetDlgItem(AFX_IDW_SIZE_BOX);
		}
		pScrollBar->ShowWindow(SW_SHOW);
	}
	else
	{
		// the size box can be destroyed instead of hidden
		pScrollBar = GetDlgItem(AFX_IDW_SIZE_BOX);
		if (pScrollBar != NULL)
			pScrollBar->DestroyWindow();
	}

	// Note: call RecalcLayout for the new layout to take effect
}

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd client operations/overridables

void CDlgSplitterWnd::DeleteView(int row, int col)
{
	ASSERT_VALID(this);

	// if active child is being deleted - activate next
	CWnd* pPane = GetPane(row, col);
	ASSERT_KINDOF(CView, pPane);
	if (GetActivePane() == pPane)
		ActivateNext(FALSE);

	// default implementation assumes view will auto delete in PostNcDestroy
	pPane->DestroyWindow();
}

void CDlgSplitterWnd::OnDrawSplitter(CDC* pDC, ESplitType nType,
	const CRect& rectArg)
{
	// if pDC == NULL, then just invalidate
	if (pDC == NULL)
	{
		RedrawWindow(rectArg, NULL, RDW_INVALIDATE|RDW_NOCHILDREN);
		return;
	}
	ASSERT_VALID(pDC);

	// otherwise, actually draw
	CRect rect = rectArg;
	switch (nType)
	{
	case splitBorder:
		ASSERT(afxData.bWin4);
		pDC->Draw3dRect(rect, afxData.clrBtnShadow, afxData.clrBtnHilite);
		rect.InflateRect(-CX_BORDER, -CY_BORDER);
		pDC->Draw3dRect(rect, afxData.clrWindowFrame, afxData.clrBtnFace);
		return;

	case splitIntersection:
		ASSERT(!afxData.bWin4);
		break;

	case splitBox:
		if (afxData.bWin4)
		{
			pDC->Draw3dRect(rect, afxData.clrBtnFace, afxData.clrWindowFrame);
			rect.InflateRect(-CX_BORDER, -CY_BORDER);
			pDC->Draw3dRect(rect, afxData.clrBtnHilite, afxData.clrBtnShadow);
			rect.InflateRect(-CX_BORDER, -CY_BORDER);
			break;
		}
		// fall through...
	case splitBar:
		if (!afxData.bWin4)
		{
			pDC->Draw3dRect(rect, afxData.clrBtnHilite, afxData.clrBtnShadow);
			rect.InflateRect(-CX_BORDER, -CY_BORDER);
		}
		break;

	default:
		ASSERT(FALSE);  // unknown splitter type
	}

	// fill the middle
	COLORREF clr = afxData.clrBtnFace;
	pDC->FillSolidRect(rect, clr);
}

/////////////////////////////////////////////////////////////////////////////
// Dynamic row/col split etc

AFX_STATIC int AFXAPI _AfxCanSplitRowCol(CDlgSplitterWnd::CRowColInfo* pInfoBefore,
	int nBeforeSize, int nSizeSplitter)
	// request to split Before row at point nBeforeSize
	// returns size of new pane (nBeforeSize will be new size of Before pane)
	// return -1 if not big enough
{
	ASSERT(pInfoBefore->nCurSize > 0);
	ASSERT(pInfoBefore->nMinSize > 0);
	ASSERT(nBeforeSize <= pInfoBefore->nCurSize);

	// space gets take from before pane (weird UI for > 2 splits)
	if (nBeforeSize < pInfoBefore->nMinSize)
	{
		TRACE0("Warning: split too small to fit in a new pane.\n");
		return -1;
	}

	int nNewSize = pInfoBefore->nCurSize - nBeforeSize - nSizeSplitter;
	if (nBeforeSize < pInfoBefore->nMinSize)
	{
		TRACE0("Warning: split too small to shrink old pane.\n");
		return -1;
	}
	if (nNewSize < (pInfoBefore+1)->nMinSize)
	{
		TRACE0("Warning: split too small to create new pane.\n");
		return -1;
	}
	return nNewSize;
}

BOOL CDlgSplitterWnd::SplitRow(int cyBefore)
{
	ASSERT_VALID(this);
	ASSERT(GetStyle() & SPLS_DYNAMIC_SPLIT);
	ASSERT(m_pDynamicViewClass != NULL);
	ASSERT(m_nRows < m_nMaxRows);

	cyBefore -= m_cyBorder;
	int rowNew = m_nRows;
	int cyNew = _AfxCanSplitRowCol(&m_pRowInfo[rowNew-1], cyBefore, m_cySplitter);
	if (cyNew == -1)
		return FALSE;   // too small to split

	// create the scroll bar first (so new views can see that it is there)
	if (m_bHasVScroll &&
		!CreateScrollBarCtrl(SBS_VERT, AFX_IDW_VSCROLL_FIRST + rowNew))
	{
		TRACE0("Warning: SplitRow failed to create scroll bar.\n");
		return FALSE;
	}

	m_nRows++;  // bump count during view creation

	// create new views to fill the new row (RecalcLayout will position)
	for (int col = 0; col < m_nCols; col++)
	{
		CSize size(m_pColInfo[col].nCurSize, cyNew);
		if (!CreateView(rowNew, col, m_pDynamicViewClass, size, NULL))
		{
			TRACE0("Warning: SplitRow failed to create new row.\n");
			// delete anything we partially created 'col' = # columns created
			while (col > 0)
				DeleteView(rowNew, --col);
			if (m_bHasVScroll)
				GetDlgItem(AFX_IDW_VSCROLL_FIRST + rowNew)->DestroyWindow();
			m_nRows--;      // it didn't work out
			return FALSE;
		}
	}

	// new parts created - resize and re-layout
	m_pRowInfo[rowNew-1].nIdealSize = cyBefore;
	m_pRowInfo[rowNew].nIdealSize = cyNew;
	ASSERT(m_nRows == rowNew+1);
	RecalcLayout();

	return TRUE;
}

BOOL CDlgSplitterWnd::SplitColumn(int cxBefore)
{
	ASSERT_VALID(this);
	ASSERT(GetStyle() & SPLS_DYNAMIC_SPLIT);
	ASSERT(m_pDynamicViewClass != NULL);
	ASSERT(m_nCols < m_nMaxCols);

	cxBefore -= m_cxBorder;
	int colNew = m_nCols;
	int cxNew = _AfxCanSplitRowCol(&m_pColInfo[colNew-1], cxBefore, m_cxSplitter);
	if (cxNew == -1)
		return FALSE;   // too small to split

	// create the scroll bar first (so new views can see that it is there)
	if (m_bHasHScroll &&
		!CreateScrollBarCtrl(SBS_HORZ, AFX_IDW_HSCROLL_FIRST + colNew))
	{
		TRACE0("Warning: SplitRow failed to create scroll bar.\n");
		return FALSE;
	}

	m_nCols++;  // bump count during view creation

	// create new views to fill the new column (RecalcLayout will position)
	for (int row = 0; row < m_nRows; row++)
	{
		CSize size(cxNew, m_pRowInfo[row].nCurSize);
		if (!CreateView(row, colNew, m_pDynamicViewClass, size, NULL))
		{
			TRACE0("Warning: SplitColumn failed to create new column.\n");
			// delete anything we partially created 'col' = # columns created
			while (row > 0)
				DeleteView(--row, colNew);
			if (m_bHasHScroll)
				GetDlgItem(AFX_IDW_HSCROLL_FIRST + colNew)->DestroyWindow();
			m_nCols--;      // it didn't work out
			return FALSE;
		}
	}

	// new parts created - resize and re-layout
	m_pColInfo[colNew-1].nIdealSize = cxBefore;
	m_pColInfo[colNew].nIdealSize = cxNew;
	ASSERT(m_nCols == colNew+1);
	RecalcLayout();

	return TRUE;
}

void CDlgSplitterWnd::DeleteRow(int rowDelete)
{
	ASSERT_VALID(this);
	ASSERT(GetStyle() & SPLS_DYNAMIC_SPLIT);

	ASSERT(m_nRows > 1);
	ASSERT(rowDelete < m_nRows);

	int rowActive, colActive;
	if (GetActivePane(&rowActive, &colActive) != NULL && rowActive == rowDelete)
	{
		if (++rowActive >= m_nRows)
			rowActive = 0;
		SetActivePane(rowActive, colActive);
	}

	CWnd* pScrollDel = m_bHasVScroll ?
		GetDlgItem(AFX_IDW_VSCROLL_FIRST+rowDelete) : NULL;
	for (int col = 0; col < m_nCols; col++)
	{
		DeleteView(rowDelete, col);
		for (int row = rowDelete+1; row < m_nRows; row++)
		{
			CWnd* pPane = GetPane(row, col);
			ASSERT(pPane != NULL);
			pPane->SetDlgCtrlID(IdFromRowCol(row-1, col));
			if (m_bHasVScroll && col == m_nCols-1)
			{
				CWnd* pScroll = GetDlgItem(AFX_IDW_VSCROLL_FIRST+row);
				if (pScroll != NULL)
					pScroll->SetDlgCtrlID(AFX_IDW_VSCROLL_FIRST+row-1);
			}
		}
	}
	m_nRows--;
	if (pScrollDel != NULL)
		pScrollDel->DestroyWindow();

	RecalcLayout();     // re-assign the space
}

void CDlgSplitterWnd::DeleteColumn(int colDelete)
{
	ASSERT_VALID(this);
	ASSERT(GetStyle() & SPLS_DYNAMIC_SPLIT);

	ASSERT(m_nCols > 1);
	ASSERT(colDelete < m_nCols);

	int rowActive, colActive;
	if (GetActivePane(&rowActive, &colActive) != NULL && colActive == colDelete)
	{
		if (++colActive >= m_nCols)
			colActive = 0;
		SetActivePane(rowActive, colActive);
	}

	CWnd* pScrollDel = m_bHasHScroll ?
		GetDlgItem(AFX_IDW_HSCROLL_FIRST+colDelete) : NULL;
	for (int row = 0; row < m_nRows; row++)
	{
		DeleteView(row, colDelete);
		for (int col = colDelete+1; col < m_nCols; col++)
		{
			CWnd* pPane = GetPane(row, col);
			ASSERT(pPane != NULL);
			pPane->SetDlgCtrlID(IdFromRowCol(row, col-1));
			if (m_bHasHScroll && row == m_nRows-1)
			{
				CWnd* pScroll = GetDlgItem(AFX_IDW_HSCROLL_FIRST+col);
				if (pScroll != NULL)
					pScroll->SetDlgCtrlID(AFX_IDW_HSCROLL_FIRST+col-1);
			}
		}
	}
	m_nCols--;
	if (pScrollDel != NULL)
		pScrollDel->DestroyWindow();

	RecalcLayout();     // re-assign the space
}

/////////////////////////////////////////////////////////////////////////////
// CDlgSplitterWnd tracking support

// like GetClientRect but inset by shared scrollbars
void CDlgSplitterWnd::GetInsideRect(CRect& rect) const
{
	ASSERT_VALID(this);

	GetClientRect(rect);
	ASSERT(rect.left == 0 && rect.top == 0);

	// subtract space for 3d borders
	rect.InflateRect(-m_cxBorder, -m_cyBorder);

	// subtract scrollbar clearance
	if (m_bHasVScroll)
		rect.right -= afxData.cxVScroll - CX_BORDER;
	if (m_bHasHScroll)
		rect.bottom -= afxData.cyHScroll - CY_BORDER;
}

void CDlgSplitterWnd::StartTracking(int ht)
{
	ASSERT_VALID(this);
	if (ht == noHit)
		return;

	// GetHitRect will restrict 'm_rectLimit' as appropriate
	GetInsideRect(m_rectLimit);

	if (ht >= splitterIntersection1 && ht <= splitterIntersection225)
	{
		// split two directions (two tracking rectangles)
		int row = (ht - splitterIntersection1) / 15;
		int col = (ht - splitterIntersection1) % 15;

		GetHitRect(row + vSplitterBar1, m_rectTracker);
		int yTrackOffset = m_ptTrackOffset.y;
		m_bTracking2 = TRUE;
		GetHitRect(col + hSplitterBar1, m_rectTracker2);
		m_ptTrackOffset.y = yTrackOffset;
	}
	else if (ht == bothSplitterBox)
	{
		// hit on splitter boxes (for keyboard)
		GetHitRect(vSplitterBox, m_rectTracker);
		int yTrackOffset = m_ptTrackOffset.y;
		m_bTracking2 = TRUE;
		GetHitRect(hSplitterBox, m_rectTracker2);
		m_ptTrackOffset.y = yTrackOffset;

		// center it
		m_rectTracker.OffsetRect(0, m_rectLimit.Height()/2);
		m_rectTracker2.OffsetRect(m_rectLimit.Width()/2, 0);
	}
	else
	{
		// only hit one bar
		GetHitRect(ht, m_rectTracker);
	}

	//下面加注释的将从程序中删去。 
	// allow active view to preserve focus before taking it away
	//CView* pView = (CView*)GetActivePane();
	//if (pView != NULL && pView->IsKindOf(RUNTIME_CLASS(CView)))
	//{
		//ASSERT_VALID(pView);
		//CFrameWnd* pFrameWnd = GetParentFrame();
		//ASSERT_VALID(pFrameWnd);
		//pView->OnActivateFrame(WA_INACTIVE, pFrameWnd);
	//}
	// steal focus and capture
	SetCapture();
	SetFocus();

	// make sure no updates are pending
	RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_UPDATENOW);

	// set tracking state and appropriate cursor
	m_bTracking = TRUE;
	OnInvertTracker(m_rectTracker);
	if (m_bTracking2)
		OnInvertTracker(m_rectTracker2);
	m_htTrack = ht;
	SetSplitCursor(ht);
}

void CDlgSplitterWnd::TrackRowSize(int y, int row)
{
	ASSERT_VALID(this);
	ASSERT(m_nRows > 1);

	CPoint pt(0, y);
	ClientToScreen(&pt);
	GetPane(row, 0)->ScreenToClient(&pt);
	m_pRowInfo[row].nIdealSize = pt.y;      // new size
	if (pt.y < m_pRowInfo[row].nMinSize)
	{
		// resized too small
		m_pRowInfo[row].nIdealSize = 0; // make it go away
		if (GetStyle() & SPLS_DYNAMIC_SPLIT)
			DeleteRow(row);
	}
	else if (m_pRowInfo[row].nCurSize + m_pRowInfo[row+1].nCurSize
			< pt.y + m_pRowInfo[row+1].nMinSize)
	{
		// not enough room for other pane
		if (GetStyle() & SPLS_DYNAMIC_SPLIT)
			DeleteRow(row + 1);
	}
}

void CDlgSplitterWnd::TrackColumnSize(int x, int col)
{
	ASSERT_VALID(this);
	ASSERT(m_nCols > 1);

	CPoint pt(x, 0);
	ClientToScreen(&pt);
	GetPane(0, col)->ScreenToClient(&pt);
	m_pColInfo[col].nIdealSize = pt.x;      // new size
	if (pt.x < m_pColInfo[col].nMinSize)
	{
		// resized too small
		m_pColInfo[col].nIdealSize = 0; // make it go away
		if (GetStyle() & SPLS_DYNAMIC_SPLIT)
			DeleteColumn(col);
	}
	else if (m_pColInfo[col].nCurSize + m_pColInfo[col+1].nCurSize
			< pt.x + m_pColInfo[col+1].nMinSize)
	{
		// not enough room for other pane
		if (GetStyle() & SPLS_DYNAMIC_SPLIT)
			DeleteColumn(col + 1);
	}
}

void CDlgSplitterWnd::StopTracking(BOOL bAccept)
{
	ASSERT_VALID(this);

	if (!m_bTracking)
		return;

	ReleaseCapture();

	// erase tracker rectangle
	OnInvertTracker(m_rectTracker);
	if (m_bTracking2)
		OnInvertTracker(m_rectTracker2);
	m_bTracking = m_bTracking2 = FALSE;

	// save old active view
	CWnd* pOldActiveView = GetActivePane();

	// m_rectTracker is set to the new splitter position (without border)
	// (so, adjust relative to where the border will be)
	m_rectTracker.OffsetRect(-CX_BORDER , -CY_BORDER);

⌨️ 快捷键说明

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