📄 mygridvw.cpp
字号:
// mygridvw.cpp : implementation of the CMyGridView 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 "resource.h"
#include "mygridvw.h"
#ifndef _GXSTYDLG_H_
#include "gxstydlg.h"
#endif
#ifndef _GXPRPD_H_
#include "gxprpdlg.h"
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CMyGridView, CGXGridView)
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
// CMyGridView
//
// CMyGridView contains code for menu handlers
//
// Use this class as a collection of code which you can copy to your
// specific gridview class or simply copy the whole file to your
// project and use it as a base class for your gridview classes.
//
// Following menu handlers are implemented in CMyGridView:
// File->
// Page Setup
// Header/Footer Setup
// Edit->
// Clear
// Insert Column
// Insert Row
// Remove Column
// Remove Row
// View->
// Zoom In
// Zoom Out
// 100%
// Read Only
// Properties...
// Format->
// Cells...
// Lookup...
// Freeze Columns
// Unfreeze Columns
// Freeze Rows
// Unfreeze Rows
// Cover Cells
// Remove Covering
// Styles...
// Resize Rows
// Resize Columns
// Align->
// Left
// Center
// Right
// Style->
// Bold
// Italic
// Underline
//
// Following menu handlers are implemented in CGXGridView:
// Edit->
// Undo (ID_EDIT_UNDO)
// Redo (ID_EDIT_REDO)
// Find... (ID_EDIT_FIND)
// Replace... (ID_EDIT_REPLACE)
// Find again (ID_EDIT_REPEAT)
// Cut (ID_EDIT_CUT)
// Copy (ID_EDIT_COPY)
// Paste (ID_EDIT_PASTE)
//
// Additional Operations ease the applying of styles to selected cell ranges
//
// BOOL NeedStyle(const CGXStyle& styleNeeded, BOOL& bRet);
// Is used by OnUpdateFormatStyle... and OnUpdateFormatAlign... to determine
// the state of a specific style as bold, italic, underline
// for the current cell or selected range of cells.
//
// void SetStyle(const CGXStyle& style, GXModifyType mt = gxOverride);
// void SetStyle(const CGXStyle* pStyle, GXModifyType mt);
// Is used by OnFormatStyle... and OnFormatAlign... to set
// the style for the current cell or selected range of cells.
//
// written by Stefan Hoenig, 12.02.94
//
BEGIN_MESSAGE_MAP(CMyGridView, CGXGridView)
//{{AFX_MSG_MAP(CMyGridView)
ON_COMMAND(ID_FILE_HEADERFOOTER, OnFileHeaderfooter)
ON_COMMAND(ID_FILE_PAGE_SETUP, OnFilePageSetup)
ON_COMMAND(ID_EDIT_INSERTCOL, OnEditInsertcol)
ON_COMMAND(ID_EDIT_INSERTROW, OnEditInsertrow)
ON_COMMAND(ID_EDIT_REMOVECOLS, OnEditRemovecols)
ON_COMMAND(ID_EDIT_REMOVEROWS, OnEditRemoverows)
ON_COMMAND(ID_VIEW_100, OnView100)
ON_COMMAND(ID_VIEW_PROPERTIES, OnViewProperties)
ON_COMMAND(ID_VIEW_READONLY, OnViewReadonly)
ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
ON_COMMAND(ID_FORMAT_ALIGN_CENTER, OnFormatAlignCenter)
ON_COMMAND(ID_FORMAT_ALIGN_LEFT, OnFormatAlignLeft)
ON_COMMAND(ID_FORMAT_ALIGN_RIGHT, OnFormatAlignRight)
ON_COMMAND(ID_FORMAT_CELLS, OnFormatCells)
ON_COMMAND(ID_FORMAT_COVERCELLS, OnFormatCovercells)
ON_COMMAND(ID_FORMAT_FREEZECOLS, OnFormatFreezecols)
ON_COMMAND(ID_FORMAT_FREEZEROWS, OnFormatFreezerows)
ON_COMMAND(ID_FORMAT_LOOKUP, OnFormatLookup)
ON_COMMAND(ID_FORMAT_REMOVECOVER, OnFormatRemovecover)
ON_COMMAND(ID_FORMAT_STYLE_BOLD, OnFormatStyleBold)
ON_COMMAND(ID_FORMAT_STYLE_ITALIC, OnFormatStyleItalic)
ON_COMMAND(ID_FORMAT_STYLE_UNDERLINE, OnFormatStyleUnderline)
ON_COMMAND(ID_FORMAT_STYLES, OnFormatStyles)
ON_COMMAND(ID_FORMAT_UNFREEZECOLS, OnFormatUnfreezecols)
ON_COMMAND(ID_FORMAT_UNFREEZEROWS, OnFormatUnfreezerows)
ON_UPDATE_COMMAND_UI(ID_EDIT_REMOVECOLS, OnUpdateEditRemovecols)
ON_UPDATE_COMMAND_UI(ID_EDIT_REMOVEROWS, OnUpdateEditRemoverows)
ON_UPDATE_COMMAND_UI(ID_FORMAT_ALIGN_CENTER, OnUpdateFormatAlignCenter)
ON_UPDATE_COMMAND_UI(ID_FORMAT_ALIGN_LEFT, OnUpdateFormatAlignLeft)
ON_UPDATE_COMMAND_UI(ID_FORMAT_ALIGN_RIGHT, OnUpdateFormatAlignRight)
ON_UPDATE_COMMAND_UI(ID_FORMAT_CELLS, OnUpdateFormatCells)
ON_UPDATE_COMMAND_UI(ID_FORMAT_COVERCELLS, OnUpdateFormatCovercells)
ON_UPDATE_COMMAND_UI(ID_FORMAT_FREEZECOLS, OnUpdateFormatFreezecols)
ON_UPDATE_COMMAND_UI(ID_FORMAT_FREEZEROWS, OnUpdateFormatFreezerows)
ON_UPDATE_COMMAND_UI(ID_FORMAT_LOOKUP, OnUpdateFormatLookup)
ON_UPDATE_COMMAND_UI(ID_FORMAT_REMOVECOVER, OnUpdateFormatRemovecover)
ON_UPDATE_COMMAND_UI(ID_FORMAT_STYLE_BOLD, OnUpdateFormatStyleBold)
ON_UPDATE_COMMAND_UI(ID_FORMAT_STYLE_ITALIC, OnUpdateFormatStyleItalic)
ON_UPDATE_COMMAND_UI(ID_FORMAT_STYLE_UNDERLINE, OnUpdateFormatStyleUnderline)
ON_UPDATE_COMMAND_UI(ID_FORMAT_UNFREEZECOLS, OnUpdateFormatUnfreezecols)
ON_UPDATE_COMMAND_UI(ID_FORMAT_UNFREEZEROWS, OnUpdateFormatUnfreezerows)
ON_UPDATE_COMMAND_UI(ID_VIEW_READONLY, OnUpdateViewReadonly)
ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMIN, OnUpdateViewZoomin)
ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOMOUT, OnUpdateViewZoomout)
ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditClear)
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave)
ON_COMMAND(ID_FORMAT_RESIZECOLS, OnFormatResizecols)
ON_UPDATE_COMMAND_UI(ID_FORMAT_RESIZECOLS, OnUpdateFormatResizecols)
ON_COMMAND(ID_FORMAT_RESIZEROWS, OnFormatResizerows)
ON_UPDATE_COMMAND_UI(ID_FORMAT_RESIZEROWS, OnUpdateFormatResizerows)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CGXGridView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CGXGridView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyGridView construction/destruction
CMyGridView::CMyGridView()
{
// TODO: add construction code here
}
CMyGridView::~CMyGridView()
{
}
const UINT gxnFirstCtrl = 18001;
void CMyGridView::OnInitialUpdate()
{
// check parameter object
if (GetParam() == NULL)
SetParam(new CGXGridParam);
// check styles
if (GetParam()->GetStylesMap() == NULL)
{
CGXStylesMap* stylesmap = new CGXStylesMap;
// standard styles
stylesmap->CreateStandardStyles();
// use spin-control in "User"-page
CGXStyle styleSpin;
styleSpin.SetControl(GX_IDS_CTRL_SPINEDIT).SetWrapText(FALSE);
// user attributes
// Validation: warning message
stylesmap->AddUserAttribute(GX_IDS_UA_VALID_MSG,
CGXStyle().SetWrapText(TRUE).SetAutoSize(TRUE));
// Validation: maximum value
stylesmap->AddUserAttribute(GX_IDS_UA_VALID_MAX,
&styleSpin);
// Validation: Minimum value
stylesmap->AddUserAttribute(GX_IDS_UA_VALID_MIN,
&styleSpin);
// Spinbounds: Minimum value
stylesmap->AddUserAttribute(GX_IDS_UA_SPINBOUND_MIN,
&styleSpin);
// Spinbounds: maximum value
stylesmap->AddUserAttribute(GX_IDS_UA_SPINBOUND_MAX,
&styleSpin);
// Spinbounds: wrap value
stylesmap->AddUserAttribute(GX_IDS_UA_SPINBOUND_WRAP,
CGXStyle().SetControl(GX_IDS_CTRL_CHECKBOX3D)
.SetVerticalAlignment(DT_VCENTER)
.SetHorizontalAlignment(DT_CENTER));
// load profile/registry settings
stylesmap->ReadProfile();
// attach object to parameter-object
GetParam()->SetStylesMap(stylesmap);
}
CGXGridView::OnInitialUpdate();
// Register default controls (they need to be register for each view)
// All registered controls will appear in the control-listbox in the control-page
// of the style-sheet. The user can apply these controls to cells.
// GX_IDS_CTRL_EDIT is registered by default in CGXGridCore::OnInitialUpdate()
// GridMFC Comboboxes (not derived from CComboBox)
// allow text input which fits the choice list
RegisterControl(GX_IDS_CTRL_TEXTFIT,
new CGXComboBox(this, gxnFirstCtrl+1, gxnFirstCtrl+2, GXCOMBO_TEXTFIT));
// allow user to input any text
RegisterControl(GX_IDS_CTRL_COMBOBOX,
new CGXComboBox(this, gxnFirstCtrl+3, gxnFirstCtrl+4, GXCOMBO_NOTEXTFIT));
// use an integer as cell value
RegisterControl(GX_IDS_CTRL_ONEBASED,
new CGXComboBox(this, gxnFirstCtrl+5, gxnFirstCtrl+6, GXCOMBO_ONEBASED));
// use an zero-based integer as cell value
RegisterControl(GX_IDS_CTRL_ZEROBASED,
new CGXComboBox(this, gxnFirstCtrl+7, gxnFirstCtrl+8, GXCOMBO_ZEROBASED));
// CComboBox adapter (derived from CComboBox)
// CComboBox adapter with CBS_DROPDOWN style
{
CGXComboBoxWnd* pWnd = new CGXComboBoxWnd(this);
pWnd->Create(WS_VSCROLL | CBS_DROPDOWN, gxnFirstCtrl+9);
pWnd->m_bFillWithChoiceList = TRUE;
pWnd->m_bWantArrowKeys = FALSE;
RegisterControl(GX_IDS_CTRL_CBS_DROPDOWN, pWnd);
}
// CComboBox adapter with CBS_DROPDOWNLIST style
{
CGXComboBoxWnd* pWnd = new CGXComboBoxWnd(this);
pWnd->Create(WS_VSCROLL | CBS_DROPDOWNLIST, gxnFirstCtrl+10);
pWnd->m_bFillWithChoiceList = TRUE;
pWnd->m_bWantArrowKeys = FALSE;
RegisterControl(GX_IDS_CTRL_CBS_DROPDOWNLIST, pWnd);
}
// If you need a combobox with CBS_SORT style or if you
// need an ownerdrawn combobox, you can register them
// as seen for the GX_IDS_CTRL_CBS_DROPDOWNLIST and
// GX_IDS_CTRL_CBS_DROPDOWN controls.
// Textcontrol with Spinbuttons
RegisterControl(GX_IDS_CTRL_SPINEDIT, new CGXSpinEdit(this, gxnFirstCtrl+10));
// Textcontrol with hotspot button
RegisterControl(GX_IDS_CTRL_HOTSPOT, new CGXHotSpotEdit(this, gxnFirstCtrl+11));
// Textcontrol with Vertical scrollbars
RegisterControl(GX_IDS_CTRL_SCROLLEDIT, new CGXVScrollEdit(this, gxnFirstCtrl+12));
// Listbox
RegisterControl(GX_IDS_CTRL_LISTBOX, new CGXListBox(this, gxnFirstCtrl+13));
// Static Text
RegisterControl(GX_IDS_CTRL_STATIC, new CGXStatic(this));
// Push Button
RegisterControl(GX_IDS_CTRL_PUSHBTN, new CGXPushbutton(this));
// Radio Buttons
RegisterControl(GX_IDS_CTRL_RADIOBTN, new CGXRadioButton(this, FALSE /* normal Look */));
RegisterControl(GX_IDS_CTRL_RADIOBTN3D, new CGXRadioButton(this, TRUE /* 3d-Look */));
// Check Boxes
RegisterControl(GX_IDS_CTRL_CHECKBOX, new CGXCheckBox(this, FALSE /* normal Look */));
RegisterControl(GX_IDS_CTRL_CHECKBOX3D, new CGXCheckBox(this, TRUE /* 3d-Look */));
}
/////////////////////////////////////////////////////////////////////////////
// CMyGridView diagnostics
#ifdef _DEBUG
void CMyGridView::AssertValid() const
{
CGXGridView::AssertValid();
}
void CMyGridView::Dump(CDumpContext& dc) const
{
CGXGridView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMyGridView Operations
BOOL CMyGridView::NeedStyle(const CGXStyle& styleNeeded, BOOL& bRet)
{
CGXRangeList* pSelList = GetParam()->GetRangeList();
POSITION pos = pSelList->GetHeadPosition();
ROWCOL nRow, nCol;
bRet = FALSE;
if (pos)
{
nRow = pSelList->GetAt(pos)->top;
nCol = pSelList->GetAt(pos)->left;
}
else if (!GetCurrentCell(&nRow, &nCol))
{
return FALSE;
}
if (nRow > GetRowCount() || nCol > GetColCount())
return FALSE;
if (nRow > 0 && nCol > 0)
{
// Cell range
const CGXStyle& style = LookupStyleRowCol(nRow, nCol);
bRet = style.IsSubSet(styleNeeded);
}
else
{
// Row or column ranges
// Compose style
CGXStyle* pStyle = new CGXStyle;
GetStyleRowCol(nRow, nCol, *pStyle, gxCopy, -1);
GetStyleRowCol(0, 0, *pStyle, gxApplyNew, -1);
pStyle->LoadBaseStyle(*m_pParam->GetStylesMap());
bRet = pStyle->IsSubSet(styleNeeded);
delete pStyle;
}
return TRUE;
}
void CMyGridView::SetStyle(const CGXStyle& style, GXModifyType mt)
{
SetStyle(&style, mt);
}
void CMyGridView::SetStyle(const CGXStyle* pStyle, GXModifyType mt, BOOL bExpand)
{
// if there are no cells selected,
// copy the current cell's coordinates
BOOL bAbort = FALSE;
CGXRangeList selList;
if (!CopyRangeList(selList, TRUE))
return;
CGXLongOperation theOp;
BOOL bTrans = selList.GetCount() > 1;
if (bTrans)
BeginTrans(GXGetAppData()->strmCellFormatting);
ROWCOL nRowCount = GetRowCount();
ROWCOL nColCount = GetColCount();
// loop through selected cells
POSITION pos = selList.GetHeadPosition();
while (pos)
{
CGXRange rect = selList.GetNext(pos);
if (bExpand)
rect.ExpandRange(1, 1, nRowCount, nColCount);
// SetStyleRange returns FALSE if operation failed.
if (!SetStyleRange(rect, pStyle, mt, rect.IsCells() ? 0: -1)
|| theOp.DoMessages(bAbort) && bAbort)
{
if (bTrans)
Rollback();
return;
}
}
if (bTrans)
CommitTrans();
ROWCOL nRow, nCol;
if (GetCurrentCell(nRow, nCol))
GetControl(nRow, nCol)->Refresh();
}
/////////////////////////////////////////////////////////////////////////////
// File menu handlers
void CMyGridView::OnUpdateFileSave(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetDocument()->IsModified());
}
void CMyGridView::OnFilePageSetup()
{
BOOL bSaveDefault = FALSE;
CGXProperties* pPropertyObj = GetParam()->GetProperties();
ASSERT(pPropertyObj->IsKindOf(RUNTIME_CLASS(CGXProperties)));
CGXProperties* pNewSettings = new CGXProperties;
*pNewSettings = *pPropertyObj;
CGXPrintPropertiesDialog dlg(pNewSettings, GetParam()->GetStylesMap(), &bSaveDefault, FALSE);
int result = dlg.DoModal();
if (result == IDOK)
{
*pPropertyObj = *pNewSettings;
if (bSaveDefault)
pPropertyObj->WriteProfile();
SetModifiedFlag();
}
delete pNewSettings;
}
void CMyGridView::OnFileHeaderfooter()
{
BOOL bSaveDefault = FALSE;
CGXProperties* pPropertyObj = GetParam()->GetProperties();
ASSERT(pPropertyObj->IsKindOf(RUNTIME_CLASS(CGXProperties)));
CGXProperties* pNewSettings = new CGXProperties;
*pNewSettings = *pPropertyObj;
CGXHeaderFooterDialog dlg(pNewSettings, &bSaveDefault);
int result = dlg.DoModal();
if (result == IDOK)
{
*pPropertyObj = *pNewSettings;
if (bSaveDefault)
pPropertyObj->WriteProfile();
SetModifiedFlag();
}
delete pNewSettings;
}
/////////////////////////////////////////////////////////////////////////////
// Edit menu handlers
void CMyGridView::OnEditClear()
{
SetStyle(NULL, gxRemove, TRUE);
}
void CMyGridView::OnUpdateEditClear(CCmdUI* pCmdUI)
{
pCmdUI->Enable(GetParam() && GetParam()->GetRangeList()->GetCount() > 0 || IsCurrentCell());
}
void CMyGridView::OnEditInsertcol()
{
ROWCOL nRow = 0, nCol = 0;
// if there are no cells selected,
// copy the current cell's coordinates
CGXRangeList selList;
if (CopyRangeList(selList, TRUE))
nCol = selList.GetHead()->left;
else
nCol = GetColCount()+1;
nCol = max(1, nCol);
InsertCols(nCol, 1);
ScrollCellInView(GetTopRow(), nCol+1);
}
void CMyGridView::OnEditInsertrow()
{
ROWCOL nRow = 0, nCol = 0;
// if there are no cells selected,
// copy the current cell's coordinates
CGXRangeList selList;
if (CopyRangeList(selList, TRUE))
nRow = selList.GetHead()->top;
else
nRow = GetRowCount()+1;
nRow = max(1, nRow);
InsertRows(nRow, 1);
ScrollCellInView(nRow+1, GetLeftCol());
}
void CMyGridView::OnEditRemovecols()
{
CGXRangeList* pSelList = GetParam()->GetRangeList();
if (pSelList->IsAnyCellFromRow(0) && pSelList->GetCount() == 1)
{
CGXRange range = pSelList->GetHead();
range.ExpandRange(0, 1, 0, GetColCount());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -