405 lines
11 KiB
C++
405 lines
11 KiB
C++
// MatDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "GridView.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
static COleVariant * g_lstSortFieldContents=NULL;
|
|
static BOOL g_bSortAscend=TRUE;
|
|
|
|
extern int CompareBookmark(COleVariant *pArray, const long *bookmark1, const long *bookmark2);
|
|
|
|
// bookmark is record number
|
|
static int CompareBookmarksForSort(const long *bookmark1, const long *bookmark2)
|
|
{
|
|
int nRes=CompareBookmark(g_lstSortFieldContents, bookmark1, bookmark2);
|
|
if (!g_bSortAscend) { //Reverse the result
|
|
if (nRes>0) nRes=-1;
|
|
else if (nRes<0) nRes=1;
|
|
}
|
|
return nRes;
|
|
}
|
|
|
|
|
|
// modify by xlc on 090902 消除tg5lib影响
|
|
//#if ADS<18
|
|
#if 0
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CGridView dialog
|
|
IMPLEMENT_DYNCREATE(CGridView, CFormView)
|
|
|
|
CGridView::CGridView(UINT id)
|
|
: CFormView(id), m_pTable(NULL), m_nCurIndex(-1), m_bAscend(TRUE)
|
|
{
|
|
//{{AFX_DATA_INIT(CGridView)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
AfxEnableControlContainer(); // OleInit
|
|
m_bReadEnable = FALSE;
|
|
}
|
|
|
|
BOOL CGridView::MoveTo(long bookmark)
|
|
{
|
|
for(int i=0; i<m_lstBookmarks.Length(); i++) {
|
|
if (*m_lstBookmarks[i]==bookmark) {
|
|
m_nCurIndex=i;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void CGridView::Move(long offset)
|
|
{
|
|
m_nCurIndex += offset;
|
|
if (m_nCurIndex>m_lstBookmarks.Length()) m_nCurIndex=m_lstBookmarks.Length();
|
|
else if (m_nCurIndex<-1) m_nCurIndex=-1;
|
|
}
|
|
|
|
void CGridView::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CFormView::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CGridView)
|
|
DDX_Control(pDX, IDC_GRID, m_grid);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CGridView, CFormView)
|
|
//{{AFX_MSG_MAP(CGridView)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CGridView message handlers
|
|
|
|
void CGridView::OnInitialUpdate()
|
|
{
|
|
CFormView::OnInitialUpdate();
|
|
|
|
CRect rect;
|
|
GetClientRect( &rect );
|
|
m_grid.SetWindowPos( NULL, rect.left, rect.top,
|
|
rect.right-rect.left, rect.bottom-rect.top,SWP_SHOWWINDOW);
|
|
|
|
OnDocFileChanged();
|
|
|
|
}
|
|
|
|
void CGridView::OnDocFileChanged()
|
|
{
|
|
// TODO: Add extra initialization here
|
|
|
|
m_sSortFieldName.Empty();
|
|
m_pTable = OpenDbfTable();
|
|
if (!m_pTable)
|
|
return;
|
|
|
|
CTrueDBGrid50_Columns Cols = m_grid.GetColumns();
|
|
Cols.RemoveAll();
|
|
GetBookmarks(TRUE);
|
|
ConfigGrid();
|
|
|
|
}
|
|
|
|
// 取得所有行的Bookmark或/并排序
|
|
void CGridView::GetBookmarks(BOOL bRetriveFromDbf)
|
|
{
|
|
if (!m_pTable) return;
|
|
if (bRetriveFromDbf) {
|
|
m_lstBookmarks.Reset();
|
|
for(m_pTable->MoveFirst(); !m_pTable->IsEOF(); m_pTable->MoveNext())
|
|
m_lstBookmarks.Append(new long(m_pTable->GetPosition()));
|
|
}
|
|
if (!m_sSortFieldName.IsEmpty()) {
|
|
if (g_lstSortFieldContents) delete [] g_lstSortFieldContents;
|
|
g_lstSortFieldContents = new COleVariant[(int) m_pTable->GetRecordCount(FALSE)];
|
|
int i=0;
|
|
|
|
for(m_pTable->MoveFirst(FALSE); !m_pTable->IsEOF(); m_pTable->MoveNext(FALSE)) {
|
|
XFieldContent *pContent=m_pTable->GetFieldContent(m_sSortFieldName);
|
|
ASSERT(pContent);
|
|
g_lstSortFieldContents[i]=pContent->AsVariant();
|
|
i++;
|
|
}
|
|
m_lstBookmarks.QuickSort(CompareBookmarksForSort);
|
|
delete [] g_lstSortFieldContents;
|
|
g_lstSortFieldContents=NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//布置Grid的界面
|
|
void CGridView::ConfigGrid()
|
|
{
|
|
if (!m_pTable) return;
|
|
m_bReadEnable = FALSE; //禁止Grid从数据源读取数据, 锁定
|
|
|
|
// Set other miscellaneous properties for the BookList grid
|
|
// Set properties for grid columns -- first remove the two default
|
|
// grid columns and add four more
|
|
CTrueDBGrid50_Columns Cols = m_grid.GetColumns();
|
|
Cols.RemoveAll();
|
|
m_grid.SuppressTransforms(TRUE);
|
|
|
|
int nLine=1;
|
|
int nColumn=m_lstHeadInfo.Length();
|
|
for(int i=0; i<nColumn; i++) {
|
|
CTrueDBGrid50_Column Col = Cols.Add(i);
|
|
Col.SetVisible(TRUE);
|
|
XString s1(256), s2(256);
|
|
CT_strnth(m_lstHeadInfo[i]->m_sDesc, 1, s1);
|
|
CT_strnth(m_lstHeadInfo[i]->m_sDesc, 2, s2);
|
|
if (!!s2) {
|
|
s1 << "\n" << s2;
|
|
nLine=2;
|
|
}
|
|
Col.SetCaption(s1);
|
|
Col.SetWidth(m_lstHeadInfo[i]->m_nWidth);
|
|
}
|
|
|
|
CTrueDBGrid50_Style headStyle=m_grid.GetHeadingStyle();
|
|
headStyle.SetAlignment(dbgCenter);
|
|
m_grid.SetHeadingStyle(headStyle);
|
|
m_grid.SetHeadLines(float(1.2*nLine));
|
|
|
|
m_grid.SetApproxCount(m_lstBookmarks.Length());
|
|
if (!m_lstBookmarks) {
|
|
COleVariant var;
|
|
V_VT(&var) = VT_NULL;
|
|
m_grid.SetBookmark(var);
|
|
}
|
|
else m_grid.SetBookmark(COleVariant(*m_lstBookmarks[0]));
|
|
|
|
m_bReadEnable = TRUE; //解开Grid从数据源读取数据的锁定
|
|
m_grid.ReBind();
|
|
}
|
|
|
|
|
|
|
|
|
|
BEGIN_EVENTSINK_MAP(CGridView, CFormView)
|
|
//{{AFX_EVENTSINK_MAP(CGridView)
|
|
ON_EVENT(CGridView, IDC_GRID, 41 /* UnboundReadDataEx */, OnUnboundReadDataExMatgrid, VTS_DISPATCH VTS_PVARIANT VTS_I4 VTS_PI4)
|
|
ON_EVENT(CGridView, IDC_GRID, 19 /* UnboundWriteData */, OnUnboundWriteDataMatgrid, VTS_DISPATCH VTS_PVARIANT)
|
|
ON_EVENT(CGridView, IDC_GRID, 20 /* UnboundAddData */, OnUnboundAddDataMatgrid, VTS_DISPATCH VTS_PVARIANT)
|
|
ON_EVENT(CGridView, IDC_GRID, 21 /* UnboundDeleteRow */, OnUnboundDeleteRowMatgrid, VTS_PVARIANT)
|
|
ON_EVENT(CGridView, IDC_GRID, 10 /* HeadClick */, OnHeadClickMatgrid, VTS_I2)
|
|
//}}AFX_EVENTSINK_MAP
|
|
END_EVENTSINK_MAP()
|
|
|
|
void CGridView::ReadData(CTrueDBGrid50_RowBuffer &RowBuffer, VARIANT FAR* StartLocation, long offset, long FAR* ApproximatePosition)
|
|
{
|
|
long RowsFetched = 0;
|
|
|
|
if (!m_pTable || !m_lstBookmarks || !m_bReadEnable) {
|
|
RowBuffer.SetRowCount(0);
|
|
return;
|
|
}
|
|
|
|
// If StartLocation is a Null VARIANT, it means we are positioning
|
|
// relative to BOF (if offset > 0) or EOF (if offset < 0)
|
|
if (V_VT(StartLocation) == VT_NULL) {
|
|
if (offset > 0) {
|
|
m_nCurIndex=-1;
|
|
} else {
|
|
// Position to EOF
|
|
m_nCurIndex=m_lstBookmarks.Length();
|
|
}
|
|
} else {
|
|
// StartLocation refers to a valid bookmark, so just go there.
|
|
ASSERT(V_VT(StartLocation)==VT_I4);
|
|
long nPos=V_I4(StartLocation);
|
|
if (!MoveTo(nPos)) {
|
|
V_VT(StartLocation)=VT_NULL;
|
|
}
|
|
}
|
|
|
|
Move(offset);
|
|
if (!IsBOF() && !IsEOF()) {
|
|
*ApproximatePosition = m_nCurIndex;
|
|
}
|
|
|
|
// Here we store the number of rows and columns requested by the grid
|
|
// for this event, so we don't have to ask for them over and over again.
|
|
long lRowCount = RowBuffer.GetRowCount();
|
|
short sColCount = RowBuffer.GetColumnCount();
|
|
|
|
// This is a big loop that fetches data and/or bookmarks that the
|
|
// grid requests. The number of rows we need to provide data for
|
|
// is given by RowBuffer.GetRowCount()
|
|
for(long row = 0; row < lRowCount; row++)
|
|
{
|
|
if (IsBOF() || IsEOF()) {
|
|
RowBuffer.SetRowCount(RowsFetched);
|
|
return;
|
|
}
|
|
|
|
m_pTable->MoveTo(*m_lstBookmarks[m_nCurIndex]);
|
|
for(short col = 0; col < sColCount; col++) {
|
|
short sColIndex = RowBuffer.GetColumnIndex(row, col);
|
|
ASSERT(sColIndex<m_lstHeadInfo.Length());
|
|
COleVariant vValue = m_pTable->GetFieldContent(m_lstHeadInfo[sColIndex]->m_sName)->AsVariant();
|
|
RowBuffer.SetValue(row, col, vValue);
|
|
}
|
|
|
|
// Now that data for all columns have been fetched (if any), supply
|
|
// the bookmark of this row of data to the grid. All we need to do
|
|
// is supply the bookmark of the current record in the recordset.
|
|
long nPos=*m_lstBookmarks[m_nCurIndex];
|
|
RowBuffer.SetBookmark(row, COleVariant(nPos));
|
|
|
|
// Increment the number of rows successfully fetched, and do a
|
|
// MoveNext on the recordset so we are ready to read the next record.
|
|
RowsFetched++;
|
|
MoveNext();
|
|
}
|
|
|
|
// Place the number of rows we were able to fetch into the RowBuffer's
|
|
// RowCount property
|
|
RowBuffer.SetRowCount(RowsFetched);
|
|
}
|
|
|
|
// 往grid送数据
|
|
void CGridView::OnUnboundReadDataExMatgrid(LPDISPATCH RowBuf, VARIANT FAR* StartLocation, long offset, long FAR* ApproximatePosition)
|
|
{
|
|
CTrueDBGrid50_RowBuffer RowBuffer(RowBuf);
|
|
static BOOL bLocked = FALSE; //进行锁定,即下一次的读数消息必须在本次消息结束之后方可以处理
|
|
if (bLocked) {
|
|
#if !defined(NDEBUG)
|
|
adsout << _T("\nGrid违背了锁定规则!");
|
|
#endif
|
|
return;
|
|
}
|
|
bLocked=TRUE;
|
|
ReadData(RowBuffer, StartLocation, offset, ApproximatePosition);
|
|
bLocked=FALSE;
|
|
}
|
|
|
|
// 更新材料库
|
|
void CGridView::OnUnboundWriteDataMatgrid(LPDISPATCH RowBuf, VARIANT FAR* WriteLocation)
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
CTrueDBGrid50_RowBuffer RowBuffer(RowBuf);
|
|
|
|
// Here we store the number of rows and columns requested by the grid
|
|
// for this event, so we don't have to ask for them over and over again.
|
|
ASSERT(V_VT(WriteLocation)==VT_I4);
|
|
long lBookmark=V_I4(WriteLocation);
|
|
m_pTable->MoveTo(lBookmark);
|
|
|
|
long lRowCount = RowBuffer.GetRowCount();
|
|
ASSERT(lRowCount==1);
|
|
short sColCount = RowBuffer.GetColumnCount();
|
|
for(short col = 0; col < sColCount; col++) {
|
|
short sColIndex = RowBuffer.GetColumnIndex(0, col);
|
|
COleVariant vValue = RowBuffer.GetValue(0, col);
|
|
|
|
XFieldContent *pField=m_pTable->GetFieldContent(m_lstHeadInfo[sColIndex]->m_sName);
|
|
ASSERT(pField);
|
|
*pField = vValue;
|
|
}
|
|
}
|
|
|
|
//增加一行记录
|
|
void CGridView::OnUnboundAddDataMatgrid(LPDISPATCH RowBuf, VARIANT FAR* NewRowBookmark)
|
|
{
|
|
// Construct a RowBuffer class object from the supplied LPDISPATCH (RowBuf). This
|
|
// allows us to use the RowBuffer wrapper class's functions to manipulate the
|
|
// RowBuffer object.
|
|
CTrueDBGrid50_RowBuffer RowBuffer(RowBuf);
|
|
|
|
XDbfTable *rs = m_pTable;
|
|
// If the recordset is invalid or is not open, exit the event. Setting the RowCount
|
|
// property to 0 indicates to the grid that the Add failed in the data source.
|
|
if (!rs) {
|
|
RowBuffer.SetRowCount(0);
|
|
return;
|
|
}
|
|
|
|
// Place the recordset into AddNew mode
|
|
rs->AppendBegin();
|
|
|
|
// For each column in the row buffer, copy the value into the new record
|
|
short sColCount = RowBuffer.GetColumnCount();
|
|
|
|
for(short col = 0; col < sColCount; col++)
|
|
{
|
|
short sColIndex = RowBuffer.GetColumnIndex(0, col);
|
|
COleVariant vValue = RowBuffer.GetValue(0, col);
|
|
|
|
XFieldContent *pField=rs->GetFieldContent(m_lstHeadInfo[sColIndex]->m_sName);
|
|
ASSERT(pField);
|
|
*pField = vValue;
|
|
}
|
|
|
|
// Save the changes made to the new record
|
|
rs->AppendEnd();
|
|
m_lstBookmarks.Append(new long(rs->GetPosition()));
|
|
|
|
// Copy the bookmark of the newly added record into the NewRowBookmark parameter
|
|
|
|
VariantCopy(NewRowBookmark, &COleVariant(rs->GetPosition()));
|
|
|
|
// Calibrate the vertical scrollbar by informing the grid of the new record count
|
|
m_grid.SetApproxCount(m_lstBookmarks.Length());
|
|
|
|
}
|
|
|
|
//删除一行
|
|
void CGridView::OnUnboundDeleteRowMatgrid(VARIANT FAR* Bookmark)
|
|
{
|
|
XDbfTable *rs = m_pTable;
|
|
if (!rs || !m_lstBookmarks)
|
|
{
|
|
V_VT(Bookmark) = VT_NULL;
|
|
return;
|
|
}
|
|
|
|
// Move to the record to be deleted in the recordset, then delete it
|
|
ASSERT(V_VT(Bookmark)==VT_I4);
|
|
long nBookmark=V_I4(Bookmark);
|
|
int nLen=m_lstBookmarks.Length();
|
|
for(int i=0; i<nLen; i++) {
|
|
if (*m_lstBookmarks[i]==nBookmark) {
|
|
m_lstBookmarks.Remove();
|
|
break;
|
|
}
|
|
}
|
|
ASSERT(i<nLen);
|
|
|
|
rs->MoveTo(nBookmark);
|
|
rs->Delete();
|
|
// Calibrate the vertical scrollbar by informing the grid of the new record count
|
|
m_grid.SetApproxCount(m_lstBookmarks.Length());
|
|
}
|
|
|
|
// 单击列的头部进行排序
|
|
void CGridView::OnHeadClickMatgrid(short ColIndex)
|
|
{
|
|
CTrueDBGrid50_Columns Cols = m_grid.GetColumns();
|
|
|
|
CString sField = m_lstHeadInfo[ColIndex]->m_sName;
|
|
if (sField==m_sSortFieldName) {
|
|
if (m_bAscend) m_bAscend=FALSE;
|
|
else m_bAscend=TRUE;
|
|
} else {
|
|
m_sSortFieldName = sField;
|
|
m_bAscend = TRUE;
|
|
}
|
|
g_bSortAscend = m_bAscend;
|
|
|
|
GetBookmarks(FALSE);
|
|
m_grid.ReBind();
|
|
}
|
|
#endif
|