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