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

📄 gridsvw6.cpp

📁 mfc internals 源码 mfc internals 源码
💻 CPP
字号:
// gridsvw6.cpp : implementation of the CGridSample6View 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 "gridsvw6.h"
#include "dlguser.h"
#include "mainfrm.h"
#include "gridfrms.h"

#ifndef _GXWND_H_
#include "gxwnd.h"
#endif

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

//
// CGridSample6View can be used as standalone, splitter or worksheet gridview
// as you have already seen with CGridSampleView
//
// CGridSample6View illustrates using a grid control as cell
// or dropdown grid
//

/////////////////////////////////////////////////////////////////////////////
// CDropDownGridWnd control

CDropDownGridWnd::CDropDownGridWnd()
{
}

BOOL CDropDownGridWnd::Create(CRect rect, CWnd* pParent)
{
	if (!CreateEx(
		0, CGXGridCombo::GetClassName(), NULL, WS_POPUP | WS_BORDER | WS_VSCROLL,
		rect.left-1, rect.top, rect.Width()+1, rect.Height(),
		pParent->GetSafeHwnd(), NULL))
	{
		TRACE0("Failed to create popup window in CDropDownGridWnd\n");
		ASSERT(0);
		// ASSERTION-> Failed to create popup window
		// Did you register the windowclass with CGXGridCombo::RegisterClass? ->END
	}

	m_pMsgWnd = pParent;

	return TRUE;
}

void CDropDownGridWnd::OnInitialUpdate()
{
	CGXGridWnd::OnInitialUpdate();

	// typical listbox initialization
	GetParam()->SetSpecialMode(GX_MODELBOX_SS);
	GetParam()->SetHideCurrentCell(TRUE);
	GetParam()->EnableTrackColWidth(FALSE);
	GetParam()->EnableTrackRowHeight(FALSE);
	GetParam()->EnableMoveRows(FALSE);
	GetParam()->EnableMoveCols(FALSE);

	// column widths and row/column count
	SetRowCount(20);
	SetColCount(3);
	SetColWidth(0,0,0);
	SetColWidth(1,1,38);
	SetColWidth(2,3,72);

	// select first row
	SetCurrentCell(1,0);
	SelectRange(CGXRange().SetTable(), FALSE);
	SelectRange(CGXRange().SetRows(1), TRUE);
}

BOOL CDropDownGridWnd::OnLButtonHitRowCol(ROWCOL nHitRow, ROWCOL nHitCol, ROWCOL nDragRow, ROWCOL nDragCol, CPoint point, UINT flags, WORD nHitState)
{
	BOOL b = CGXGridWnd::OnLButtonHitRowCol(nHitRow, nHitCol, nDragRow, nDragCol, point, flags, nHitState);

	if (nHitState & GX_HITEND)
		m_pMsgWnd->PostMessage(WM_GX_LBOXEND, 0, 0);

	return b;
}

BOOL CDropDownGridWnd::ProcessKeys(CWnd *pSender, UINT nMessage, UINT nChar, UINT nRepCnt, UINT flags)
{
	if (nChar == 13 || nChar == 10)
	{
		m_pMsgWnd->PostMessage(WM_GX_LBOXEND, 0, 0);
		return TRUE;
	}

	return CGXGridWnd::ProcessKeys(pSender, nMessage, nChar, nRepCnt, flags);
}

BOOL CDropDownGridWnd::OnActivateGrid( BOOL bActivate )
{
	if (GetLastActivePopup() != m_pGridWnd)
		return TRUE;

	BOOL bRet = CGXGridWnd::OnActivateGrid(bActivate);

	if (bRet && !bActivate)
		m_pMsgWnd->PostMessage(WM_GX_LBOXCANCEL, 0, 0);

	return bRet;
}


BEGIN_MESSAGE_MAP(CDropDownGridWnd, CGXGridWnd)
	//{{AFX_MSG_MAP(CDropDownGridWnd)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

#ifdef _DEBUG
void CDropDownGridWnd::AssertValid() const
{
	CGXGridWnd::AssertValid();
}

void CDropDownGridWnd::Dump(CDumpContext& dc) const
{
	CGXGridWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDropGridControl control

const int nComboBtnWidth = 15;
const int nComboBtnHeight = 18;

CDropGridControl::CDropGridControl(CGXGridCore* pGrid, UINT nEditID, UINT nDropGridID)
	: CGXEditControl(pGrid, nEditID)
{
	AddChild(m_pButton = new CGXComboBoxButton(this));
	m_nDropGridID = nDropGridID;
	m_pDropDownWnd = NULL;
}

CDropGridControl::~CDropGridControl()
{
	if (m_pDropDownWnd)
	{
		m_pDropDownWnd->DestroyWindow();
		m_pDropDownWnd  = NULL;
	}
}

BEGIN_MESSAGE_MAP(CDropGridControl, CGXEditControl)
	//{{AFX_MSG_MAP(CDropGridControl)
	ON_MESSAGE(WM_GX_LBOXEND, OnListBoxEnd)
	ON_MESSAGE(WM_GX_LBOXCANCEL, OnListBoxCancel)
	ON_MESSAGE(WM_GX_LBOXCHANGED, OnListBoxChanged)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CRect CDropGridControl::GetCellRect(ROWCOL nRow, ROWCOL nCol, LPRECT rectItem /* = NULL */, const CGXStyle* pStyle /*= NULL*/)
{
	// compute the interior rectangle for the text
	// without buttons and borders

	CRect rect = CGXEditControl::GetCellRect(nRow, nCol, rectItem, pStyle);

	rect.right -= nComboBtnWidth;

	return rect;
}

void CDropGridControl::Init(ROWCOL nRow, ROWCOL nCol)
{
	CGXEditControl::Init(nRow, nCol);

	// Force drawing of button for current cell
	GridWnd()->InvalidateRect(m_pButton->GetRect());
}

void CDropGridControl::OnInitChilds(ROWCOL nRow, ROWCOL nCol, const CRect& rect)
{
	nRow, nCol;

	// initialize combobox button
	CRect rectBtn(
			max(rect.left+1, rect.right-1-nComboBtnWidth),
			rect.top+1,
			rect.right-1,
			min(rect.top+nComboBtnHeight, rect.bottom-1));

	m_pButton->SetRect(rectBtn);
}

void CDropGridControl::OnClickedButton(CGXChild* pChild)
{
	pChild;

	TRACE("Button\n");

	if (m_pDropDownWnd)
		OnListBoxCancel(0,0);

	// Style
	const CGXStyle& style = Grid()->LookupStyleRowCol(m_nRow, m_nCol);

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

	// calculate rectangle for popup window
	CWnd* desktopWnd = CWnd::GetDesktopWindow();

	CRect desktopRect;
	desktopWnd->GetClientRect(&desktopRect);

	CRect listBoxRect(rect.left, rect.bottom, rect.left+200, rect.bottom+200);
	GridWnd()->ClientToScreen(listBoxRect);

	CGXGridCombo::SetComboBoxDropDown(TRUE);

	// show popup window with embedded listbox
	// if (m_pDropDownWnd == NULL)
	m_pDropDownWnd = &m_GridWnd;
	m_pDropDownWnd->Create(listBoxRect, this);
	m_pDropDownWnd->Initialize();
	// m_pDropDownWnd->Create(WS_POPUP | WS_BORDER | WS_VSCROLL, listBoxRect, this, m_nDropGridID);
	m_pDropDownWnd->ShowWindow(SW_SHOW);
	m_pDropDownWnd->SetFocus();
	m_pDropDownWnd->UpdateWindow();

	CGXGridCombo::SetComboBoxDropDown(FALSE);
}

LRESULT CDropGridControl::OnListBoxEnd(WPARAM, LPARAM )
{
	ASSERT(m_pStyle);

	// User has selected an item
	if (m_pDropDownWnd)
	{
		CGXGridCombo::SetComboBoxDropDown(TRUE);
		// I need to set m_pDropDownWnd = NULL before I destroy the window
		// This avoids problems when killing the focus results in a call to ListBoxCancel
		CWnd* pDropDownWnd = m_pDropDownWnd;
		m_pDropDownWnd  = NULL;

		pDropDownWnd->DestroyWindow();
		// delete pDropDownWnd;

		CGXGridCombo::SetComboBoxDropDown(TRUE);
	}

	return 0;
}

LRESULT CDropGridControl::OnListBoxCancel(WPARAM, LPARAM)
{
	// User has canceled listbox selection
	if (m_pDropDownWnd)
	{
		CGXGridCombo::SetComboBoxDropDown(TRUE);
		// I need to set m_pDropDownWnd = NULL before I destroy the window
		// This avoids problems when killing the focus results in a further call to ListBoxCancel
		CWnd* pDropDownWnd = m_pDropDownWnd;
		m_pDropDownWnd  = NULL;

		pDropDownWnd->DestroyWindow();
		// delete pDropDownWnd;
		CGXGridCombo::SetComboBoxDropDown(FALSE);
	}
	return 0;
}

LRESULT CDropGridControl::OnListBoxChanged(WPARAM, LPARAM)
{
	// User has changed selection
	return 0;
}

IMPLEMENT_DYNCREATE(CGridSample6View, CMyGridView)
IMPLEMENT_DYNAMIC(CDropDownGridWnd, CGXGridWnd)
IMPLEMENT_CONTROL(CDropGridControl, CGXEditControl)

static char BASED_CODE szInstruct[] =
		"This view illustrates using a grid control as cell "
		"or dropdown grid.";

#define new DEBUG_NEW



/////////////////////////////////////////////////////////////////////////////
// CGridSample6View

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

/////////////////////////////////////////////////////////////////////////////
// CGridSample6View construction/destruction

CGridSample6View::CGridSample6View()
{
	// SetDrawingTechnique(gxDrawDirectToDC);
}

CGridSample6View::~CGridSample6View()
{
}

BOOL CGridSample6View::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 CGridSample6View::SetupControls()
{
	// Register all controls for the view

	RegisterControl(IDS_CTRL_DROPGRID, new CDropGridControl(this, IDS_CTRL_GRIDCHILD, IDS_CTRL_GRIDCHILD+1));

	// ... This is a cool demonstration of the CGXWndWrapper class

	CGXGridWnd* pGridWnd = new CGXGridWnd();
	VERIFY(pGridWnd->Create(WS_BORDER | WS_VSCROLL | WS_HSCROLL, CRect(0,0,1,1), this, IDS_CTRL_GRIDCHILD));
	pGridWnd->Initialize();
	pGridWnd->SetRowCount(32);
	pGridWnd->SetColCount(16);

	RegisterControl(IDS_CTRL_GRIDCHILD,
		new CGXWndWrapper(this,
				pGridWnd,
				TRUE, // must delete
				TRUE, // can activate
				FALSE // no invert borders
			));
	//
	// Please note that deriving with multiple inheritance would be
	// the better solution (see the note in the CGXWndWrapper class definition)
	//
	// Normally, a control is shared among the cells. (see CGXSpinEdit, CGXComboBox, ...)
	// The CGXWndWrapper class allows you to connect every window you want.
	// The window is responsible for drawing its area.
	//
	// Attention!
	// You have to consider if it makes sense to share a CGXWndWrapper-object
	// among several cells. Each cell would have a pointer to the same window.
	// e.g. sharing sharing the grid control (see above) does not make sense.

}

/////////////////////////////////////////////////////////////////////////////
// CGridSample6View drawing

void CGridSample6View::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)

		// Number of rows and columns
		SetRowCount(100);
		SetColCount(20);

		GetParam()->GetProperties()->SetDisplayVertLines(FALSE);
		GetParam()->GetProperties()->SetDisplayHorzLines(FALSE);

		SetRowHeight(5, 20, Height_LPtoDP(GX_NYHEIGHT)*2);
					// GX_NYHEIGHT is the logical height of a line

		SetCoveredCellsRowCol(5, 1, 10, 5);
		SetStyleRange(CGXRange(5,1), CGXStyle()
				.SetControl(IDS_CTRL_GRIDCHILD)
			);


		SetStyleRange(CGXRange(12,2), CGXStyle().SetValue("Dropdown Grid -> "));
		SetStyleRange(CGXRange(12,3), CGXStyle()
				.SetControl(IDS_CTRL_DROPGRID)
				.SetInterior(RGB(192,192,192))
				.SetBorders(gxBorderAll, CGXPen().SetWidth(3).SetColor(RGB(0,0,128)))
			);


		// 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);
	}

	// Position the current cell

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

	// Enable Update-Hint-Mechanism

	EnableHints();
}

/////////////////////////////////////////////////////////////////////////////
// CGridSample6View diagnostics

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

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

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

#endif //_DEBUG


/////////////////////////////////////////////////////////////////////////////
// CGridSample6View message handlers

// Menu handler for View->Splitter View

void CGridSample6View::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;

	CGridSample6View* pView = (CGridSample6View*)
		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 CGridSample6View::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 + -