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

📄 gridsvw7.cpp

📁 mfc internals 源码 mfc internals 源码
💻 CPP
字号:
// gridsvw7.cpp : implementation of the CGridSample7View class
//

// This is a part of the Objective Grid C++ Library.
// Copyright (C) 1995 ClassWorks, Stefan Hoenig.
// All rights reserved.
//
// This source code is only intended as a supplement to
// the Objective Grid Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding
// the Objective Grid product.
//

#include "stdafx.h"
#include "gridapp.h"

#include "gridsdoc.h"
#include "gridsvw7.h"
#include "dlguser.h"
#include "mainfrm.h"
#include "gridfrms.h"

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

//
// CGridSample7View can be used as standalone, splitter or worksheet gridview
// as you have already seen with CGridSampleView
//
// CGridSample7View illustrates how to apply pushbuttons for headers
// and registering this header control (the skeletton for the control
// is simply copied from the CSimpleButton class in CGridSample5View).
//
// CGridSample7View also illustrates how to select cells with the
// SelectRange command and how to override OnLButtonHitRowCol to
// implement owner-written column dragging.
//

IMPLEMENT_DYNCREATE(CGridSample7View, CMyGridView)
IMPLEMENT_CONTROL(CHeaderButton, CGXStatic)

static char BASED_CODE szInstruct[] =
		"This view shows row and column headers which act like pushbuttons. "
		"When you click on the headers, you can select/deselect the row or column.";

#define new DEBUG_NEW


/////////////////////////////////////////////////////////////////////////////
// CHeaderButton control

// This control can be used as header with push button effect
//

CHeaderButton::CHeaderButton(CGXGridCore* pGrid)
	: CGXStatic(pGrid)
{
	m_bPressed = FALSE;
}

CHeaderButton::~CHeaderButton()
{
}

void CHeaderButton::Draw(CDC* pDC, CRect rect, ROWCOL nRow, ROWCOL nCol, const CGXStyle& style, const CGXStyle* pStandardStyle)
{
	WORD w = 0;

	// Select font
	CFont* pOldFont = LoadFont(pDC, style, pStandardStyle);

	BOOL bActive = (m_nRow == nRow && m_nCol == nCol && !Grid()->IsPrinting()
				&& Grid()->IsActiveFrame());

	if (bActive)
	{
		w |= GX_BTNFOCUS;

		if (m_bPressed)
			w |= GX_BTNPRESSED;
	}


	// start of drawing buttons technique 1 ->

	CRect rectText = GetCellRect(nRow, nCol, rect);

	// Background
	DrawBackground(pDC, rect, style);

	// Draw pressed or button look
	if (style.GetIncludeDraw3dFrame() || style.GetDraw3dFrame() == gxFrameNormal)
	{
		CRect r = CGXControl::GetCellRect(nRow, nCol, rect);

		if (bActive && m_bPressed)
		{
			// Inset
			GXDraw3dFrame(pDC, r.left, r.top, r.right-1, r.bottom-1, 1,
				  RGB(0,0,0), RGB(255,255,255));

			// text will be moved to the bottom-right corner a bit
			rectText += CPoint(1,1);
		}
		else
			// Raised
			GXDraw3dFrame(pDC, r.left, r.top, r.right-1, r.bottom-1, 1,
				  RGB(255,255,255), RGB(0,0,0));
	}

	// Draw static text
	pDC->SetBkMode(TRANSPARENT);

	DWORD dtAlign = style.GetHorizontalAlignment() | style.GetVerticalAlignment();

	if (style.GetWrapText())
		dtAlign |= DT_NOPREFIX | DT_WORDBREAK;
	else
		dtAlign |= DT_NOPREFIX | DT_SINGLELINE;

	pDC->SetTextColor(style.GetTextColor());

	if (style.GetIncludeValue())
		GXDrawTextLikeMultiLineEdit(pDC,
			style.GetValueRef(), strlen(style.GetValueRef()), rectText, (UINT) dtAlign | DT_NOPREFIX | DT_WORDBREAK);

	// <- end of technique 1

/*
	// start of drawing buttons technique 2 ->

	DrawBackground(pDC, rect, style);

	GXDrawPushButton(pDC,
		rect.left, rect.top,
		rect.Width(), rect.Height(),
		w,
		style.GetValueRef());

	// <- end of technique 2
*/

	if (pOldFont)
		pDC->SelectObject(pOldFont);
}

void CHeaderButton::InvertBorders(CDC* pDC, const CRect& r)
{
	// I don't want the borders to be inverted
	pDC, r;
}

BOOL CHeaderButton::KeyPressed(UINT nMessage, UINT nChar, UINT nRepCnt, UINT flags)
{
	// unused:
	nMessage, nRepCnt, flags;

	if (nChar == 32 && nMessage == WM_KEYDOWN)
	{
		// Draw pressed
		m_bPressed = TRUE;
		Refresh();
	}
	else if (nChar == 32 && nMessage == WM_KEYUP && m_bPressed)
	{
		// trigger event
		OnClickedButton(NULL);

		// Draw normal
		m_bPressed = FALSE;
		Refresh();
	}
	return TRUE;
}

BOOL CHeaderButton::LButtonDown(UINT nFlags, CPoint pt, UINT nHitState)
{
	m_bPressed = TRUE;
	m_bMouseDown = TRUE;

	Refresh();

	// unreferenced:
	nFlags, pt, nHitState;

	return TRUE;
}

BOOL CHeaderButton::RButtonDown(UINT nFlags, CPoint pt, UINT nHitState)
{
	m_bPressed = TRUE;
	m_bMouseDown = TRUE;

	Refresh();

	// unreferenced:
	nFlags, pt, nHitState;

	return TRUE;
}

BOOL CHeaderButton::LButtonUp(UINT nFlags, CPoint pt, UINT nHitState)
{
	nFlags, pt;

	CRect rect = CGXControl::GetCellRect(m_nRow, m_nCol);

	if (m_bPressed && rect.PtInRect(pt))
		OnClickedButton(NULL);

	m_bPressed = FALSE;
	m_bMouseDown = FALSE;
	Refresh();

	// unreferenced:
	nFlags, pt, nHitState;

	return TRUE;
}

BOOL CHeaderButton::RButtonUp(UINT nFlags, CPoint pt, UINT nHitState)
{
	nFlags, pt;

	CRect rect = CGXControl::GetCellRect(m_nRow, m_nCol);

	if (m_bPressed && rect.PtInRect(pt))
	{
		char s[512];

		sprintf(s, "Clicked right button on header at cell %d, %d", m_nRow, m_nCol);

		AfxMessageBox(s);
	}

	m_bPressed = FALSE;
	m_bMouseDown = FALSE;
	Refresh();

	// unreferenced:
	nFlags, pt, nHitState;

	return TRUE;
}

BOOL CHeaderButton::MouseMove(UINT nFlags, CPoint pt, UINT nHitState)
{
	nFlags, pt;

	CRect rect = CGXControl::GetCellRect(m_nRow, m_nCol);

	BOOL bState = rect.PtInRect(pt);

	if (m_bMouseDown && bState != m_bPressed)
	{
		m_bPressed = bState;
		Refresh();
	}

	// unreferenced:
	nFlags, pt, nHitState;

	return TRUE;
}

BOOL CHeaderButton::LButtonDblClk(UINT nFlags, CPoint point)
{
	// unreferenced:
	nFlags, point;

	char s[512];

	sprintf(s, "Double-clicked on header at cell %d, %d", m_nRow, m_nCol);

	AfxMessageBox(s);

	return TRUE;
}

void CHeaderButton::OnClickedButton(CGXChild* pChild)
{
	// Unreferenced parameters:
	pChild;

	// display a message box with the text specified in
	// the user attribut "MessageText" (see the style-sheet)

	CGXRangeList* pSelList = Grid()->GetParam()->GetRangeList();

	// toggle selection for row

	if (m_nRow > 0 && m_nCol == 0)
		Grid()->SelectRange(CGXRange().SetRows(m_nRow, m_nRow), !pSelList->IsCellInList(m_nRow, m_nCol));
	else if (m_nCol > 0 && m_nRow == 0)
		Grid()->SelectRange(CGXRange().SetCols(m_nCol, m_nCol), !pSelList->IsCellInList(m_nRow, m_nCol));

}


/////////////////////////////////////////////////////////////////////////////
// CGridSample7View

BEGIN_MESSAGE_MAP(CGridSample7View, CMyGridView)
	//{{AFX_MSG_MAP(CGridSample7View)
	ON_COMMAND(ID_VIEW_USERACTIONS, OnViewUseractions)
	ON_COMMAND(ID_VIEW_SPLITTERVIEW, OnViewSplitterview)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGridSample7View construction/destruction

CGridSample7View::CGridSample7View()
{
	// TODO: add construction code here
}

CGridSample7View::~CGridSample7View()
{
}

BOOL CGridSample7View::ConnectParam()
{
	// Note: this method is copied from CGridSampleView
	//

	BOOL bNew = FALSE;

	// Retrive the zero-based worksheet-id if used as worksheet
	if (GetParentTabWnd(this, TRUE))
		m_nViewID = GetParentTabViewID(this);

	// check if it is a new pane in a splitter window
	CSplitterWnd* pSplitterWnd = GetParentDynamicSplitter(this, TRUE);
	if (pSplitterWnd != NULL)
	{
		CGXGridView *pView = (CGXGridView *) pSplitterWnd->GetPane(0, 0);
		if (pView != this)
			m_nViewID = pView->GetViewID();
	}

	// check if parameter-object exist (in document)
	if (GetDocument()->GetParam(m_nViewID) == NULL)
	{
		// create a parameter-object on the heap
		GetDocument()->SetParam(m_nViewID, new CGXGridParam);

		bNew = TRUE;    // this view needs initializing
	}

	// connect parameter-object with grid
	SetParam((CGXGridParam*) GetDocument()->GetParam(m_nViewID), FALSE);

	return bNew;
}

void CGridSample7View::SetupControls()
{
	// Register all controls for the view

	// replace the default header control with my CHeaderButton

	RegisterControl(GX_IDS_CTRL_HEADER, new CHeaderButton(this));
}

/////////////////////////////////////////////////////////////////////////////
// CGridSample7View drawing

void CGridSample7View::OnInitialUpdate()
{
	BOOL bNew = ConnectParam();

	CMyGridView::OnInitialUpdate(); // Creates all objects and links them to the grid

	// Register all controls for the view
	SetupControls();

	if (bNew)
	{
		// Don't create undo-information for the following commands
		GetParam()->EnableUndo(FALSE);
		// (at the end of this procedure, I will reenable it)

		SetRowCount(10);
		SetColCount(10);

		// Instructions
		SetCoveredCellsRowCol(1, 1, 3, 5);
		SetStyleRange(CGXRange(1,1),
			CGXStyle()
				.SetWrapText(TRUE)
				.SetEnabled(FALSE)
				.SetFont(CGXFont().SetFaceName("Times New Roman"))
				.SetInterior(RGB(255,251,240))   // Off-white
				.SetHorizontalAlignment(DT_CENTER)
				.SetVerticalAlignment(DT_VCENTER)
				.SetControl(GX_IDS_CTRL_STATIC)
				.SetBorders(gxBorderAll, CGXPen().SetWidth(2))
				.SetValue(szInstruct));

		// Enable creation of undo-information for user interactions
		GetParam()->EnableUndo(TRUE);

		// disable selecting cells
		GetParam()->EnableSelection(GX_SELNONE);
		GetParam()->EnableMoveCols(FALSE);
		GetParam()->EnableMoveRows(FALSE);
	}

	// Position the current cell

	SetCurrentCell(4, 1, FALSE /* avoid immediate updating */);

	// Enable Update-Hint-Mechanism

	EnableHints();
}

/////////////////////////////////////////////////////////////////////////////
// dragging cells

BOOL CGridSample7View::OnLButtonHitRowCol(ROWCOL nHitRow, ROWCOL nHitCol, ROWCOL nDragRow, ROWCOL nDragCol, CPoint point, UINT flags, WORD nHitState)
{
	if (!CMyGridView::OnLButtonHitRowCol(nHitRow, nHitCol, nDragRow, nDragCol, point, flags, nHitState))
		return FALSE;

	// determine style and control of the cell
	const CGXStyle& style = LookupStyleRowCol(nHitRow, nHitCol);
	CGXControl* pControl = GetRegisteredControl(style.GetControl());

	if (nHitRow == 0 && nHitCol > 0)
	{
		if (nHitState & GX_HITSTART)
		{
			m_nLastDragCol = nHitCol;
		}
		else if (nHitState & GX_HITMOVE && m_nLastDragCol != nDragCol)
		{
			DrawDragLine(m_nLastDragCol, FALSE);

			// support for dragging columns
			if (nHitCol != nDragCol && nDragCol > 0)
				// display drag-cursor
				SetGridCursor(GX_IDC_SELDRAG);
			else
				// reset cursor
				SetGridCursor(0);

			DrawDragLine(m_nLastDragCol = nDragCol, TRUE);
		}
		else if (nHitState & GX_HITEND)
		{
			DrawDragLine(m_nLastDragCol, FALSE);

			// support for dragging columns
			if (nHitCol != nDragCol && nDragCol > 0)
			{
				// move the dragged column
				if (nDragCol < nHitCol)
					MoveCols(nHitCol, nHitCol, nDragCol);
				else
					MoveCols(nHitCol, nHitCol, nDragCol-1);
			}

			// reset cursor
			SetGridCursor(0);
		}
	}

	return TRUE;
}

void CGridSample7View::DrawDragLine(ROWCOL nCol, BOOL bOutline)
{
	// This method calls DrawGridLine to outline the gridline
	// for the specified column. DrawGridLine is an implementation
	// specific method, and is not further documented.

	CClientDC dc(m_pGridWnd);
	OnPrepareDC(&dc);

	if (!bOutline)
	{
		// Hide mark
		DrawGridLine(&dc, GX_VERTLINE, GetClientCol(nCol),
			!GetParam()->GetProperties()->GetDisplayVertLines() ? GX_INVERT : 0);
	}
	else
	{
		// Show mark
		DrawGridLine(&dc, GX_VERTLINE, GetClientCol(nCol),
			!GetParam()->GetProperties()->GetDisplayVertLines() ? GX_INVERT : GX_SELDRAGLINE);
	}
}

BOOL CGridSample7View::OnLButtonDblClkRowCol(ROWCOL nRow, ROWCOL nCol, UINT nFlags, CPoint pt)
{
	char s[512];

	sprintf(s, "Double-click on cell %lu, %lu", nRow, nCol);
	AfxMessageBox(s);

	// unreferenced:
	pt, nFlags;

	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CGridSample7View diagnostics

#ifdef _DEBUG
void CGridSample7View::AssertValid() const
{
	CMyGridView::AssertValid();
}

void CGridSample7View::Dump(CDumpContext& dc) const
{
	CMyGridView::Dump(dc);
}

CGridSampleDoc* CGridSample7View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGridSampleDoc)));
	return (CGridSampleDoc*) m_pDocument;
}

#endif //_DEBUG


/////////////////////////////////////////////////////////////////////////////
// CGridSample7View message handlers

// Menu handler for View->Splitter View

void CGridSample7View::OnViewSplitterview()
{
	CDocument* pDoc = GetDocument();

	CMyMultiDocTemplate* pTemplate
		= (CMyMultiDocTemplate*) ((CGridSampleApp*) AfxGetApp())->m_pSplitterTemplate;

	pTemplate->SetViewClass(GetRuntimeClass());

	CMDIChildWnd* pNewFrame
		= (CMDIChildWnd*) pTemplate->CreateNewFrame(GetDocument(), NULL);

	if (pNewFrame == NULL)
		return;     // not created

	ASSERT(pNewFrame->IsKindOf(RUNTIME_CLASS(CSplitterMDIChildWnd)));

	CSplitterWnd& splitter = (CSplitterWnd&)
		((CSplitterMDIChildWnd *) pNewFrame)->m_wndSplitter;

	CGridSample7View* pView = (CGridSample7View*)
		splitter.GetPane(0, 0);

	// Set view id to active tab view id
	pView->m_nViewID = m_nViewID;

	pTemplate->InitialUpdateFrame(pNewFrame, pDoc);

	pNewFrame->GetActiveView();
	ASSERT(pView);
}

// Menu handler for View->User Actions...

void CGridSample7View::OnViewUseractions()
{
	// Note: this method is copied from CGridSampleView
	//
	// Shows a dialog with some attributes of the parameter-object
	// where you can experiment with some attributes
	// such as allowing the user to track columns, select cells
	// or use the grid as a listbox.

	// Transfer Current Cell's Data to grid
	if (!TransferCurrentCell())
		return;

	CUserActionsDialog dlg(GetParam());

	if (dlg.DoModal() == IDOK)
	{
		// Redraw the grid
		Redraw();
	}
}

⌨️ 快捷键说明

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