📄 gridsvw7.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 + -