📄 rscgdlg.cpp
字号:
// RsCgDlg.cpp : implementation file
//
#include "stdafx.h"
#include "RsCgDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRsCgDlg dialog
CRsCgDlg::CRsCgDlg(CWnd* pParent /*=NULL*/)
: CDialog(CRsCgDlg::IDD, pParent)
{
// TO DO: Change m_strConnection to point to
// proper location of ADBDMod.mdb database file.
m_strConnection = _T("Provider=Microsoft.JET.OLEDB.4.0;"
"Data Source=Demo.mdb" );
m_strCmdText = _T("Select * From DemoTable");
m_pRs = NULL;
m_piAdoRecordBinding = NULL;
//{{AFX_DATA_INIT(CRsCgDlg)
//m_lDlgProductID = 0;
m_strDlgProductName = _T("");
m_strDlgQuantityPerUnit = _T("");
//m_dDlgUnitPrice = 0;
//m_sDlgUnitsInStock = 0;
//m_sDlgUnitsOnOrder = 0;
//m_sDlgReorderLevel = 0;
//}}AFX_DATA_INIT
}
CRsCgDlg::~CRsCgDlg()
{
if ( m_piAdoRecordBinding ) m_piAdoRecordBinding->Release();
m_piAdoRecordBinding = NULL;
m_pRs = NULL;
}
BOOL CRsCgDlg::OnInitDialog()
{
HRESULT hr = NOERROR;
CDialog::OnInitDialog();
try
{
m_pRs.CreateInstance(__uuidof(Recordset));
m_pRs->CursorLocation = adUseClient;
m_pRs->Open((LPCTSTR)m_strCmdText, (LPCTSTR)m_strConnection, adOpenKeyset,
adLockOptimistic, adCmdText);
if (FAILED(hr = m_pRs->QueryInterface(__uuidof(IADORecordBinding), (LPVOID *)&m_piAdoRecordBinding)))
_com_issue_error(hr);
if (FAILED(hr = m_piAdoRecordBinding->BindToRecordset(this)))
_com_issue_error(hr);
RefreshBoundData();
}
catch (_com_error &e)
{
GenerateError(e.Error(), e.Description());
}
return TRUE;
}
void CRsCgDlg::RefreshBoundData()
{
//if (adFldOK == lProductIDStatus)
// m_lDlgProductID = m_lProductID;
//else
// m_lDlgProductID = 0;
if (adFldOK == lProductNameStatus)
m_strDlgProductName = m_szProductName;
else
m_strDlgProductName = _T("");
if (adFldOK == lQuantityPerUnitStatus)
m_strDlgQuantityPerUnit = m_szQuantityPerUnit;
else
m_strDlgQuantityPerUnit = _T("");
//if (adFldOK == lUnitPriceStatus)
// m_dDlgUnitPrice = m_dUnitPrice;
//else
// m_dDlgUnitPrice = 0;
//if (adFldOK == lUnitsInStockStatus)
// m_sDlgUnitsInStock = m_sUnitsInStock;
//else
// m_sDlgUnitsInStock = 0;
//if (adFldOK == lUnitsOnOrderStatus)
// m_sDlgUnitsOnOrder = m_sUnitsOnOrder;
//else
// m_sDlgUnitsOnOrder = 0;
//if (adFldOK == lReorderLevelStatus)
// m_sDlgReorderLevel = m_sReorderLevel;
//else
// m_sDlgReorderLevel = 0;
UpdateData(FALSE);
}
void CRsCgDlg::GenerateError(HRESULT hr, PWSTR pwszDescription)
{
CString strError;
strError.Format("Run-time error '%d (%x)'", hr, hr);
strError += "\n\n";
strError += pwszDescription;
AfxMessageBox(strError);
}
void CRsCgDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CRsCgDlg)
//DDX_Text(pDX, IDC_EDIT_PRODUCTID, m_lDlgProductID);
DDX_Text(pDX, IDC_EDIT_PRODUCTNAME, m_strDlgProductName);
DDX_Text(pDX, IDC_EDIT_QUANTITYPERUNIT, m_strDlgQuantityPerUnit);
//DDX_Text(pDX, IDC_EDIT_UNITPRICE, m_dDlgUnitPrice);
//DDX_Text(pDX, IDC_EDIT_UNITSINSTOCK, m_sDlgUnitsInStock);
//DDX_Text(pDX, IDC_EDIT_UNITSONORDER, m_sDlgUnitsOnOrder);
//DDX_Text(pDX, IDC_EDIT_REORDERLEVEL, m_sDlgReorderLevel);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CRsCgDlg, CDialog)
//{{AFX_MSG_MAP(CRsCgDlg)
ON_BN_CLICKED(ID_BTN_MOVEFIRST, OnBtnMoveFirst)
ON_BN_CLICKED(ID_BTN_MOVELAST, OnBtnMoveLast)
ON_BN_CLICKED(ID_BTN_MOVENEXT, OnBtnMoveNext)
ON_BN_CLICKED(ID_BTN_MOVEPREVIOUS, OnBtnMovePrevious)
ON_BN_CLICKED(IDC_SAVE_RECORD, OnSaveRecord)
ON_BN_CLICKED(IDC_ADD_RECORD, OnAddRecord)
ON_BN_CLICKED(IDC_DELETE_RECORD, OnDeleteRecord)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CRsCgDlg message handlers
void CRsCgDlg::OnBtnMoveFirst()
{
try
{
m_pRs->MoveFirst();
RefreshBoundData();
}
catch (_com_error &e)
{
GenerateError(e.Error(), e.Description());
}
}
void CRsCgDlg::OnBtnMoveLast()
{
try
{
m_pRs->MoveLast();
RefreshBoundData();
}
catch (_com_error &e)
{
GenerateError(e.Error(), e.Description());
}
}
void CRsCgDlg::OnBtnMoveNext()
{
try
{
m_pRs->MoveNext();
RefreshBoundData();
}
catch (_com_error &e)
{
GenerateError(e.Error(), e.Description());
}
}
void CRsCgDlg::OnBtnMovePrevious()
{
try
{
m_pRs->MovePrevious();
RefreshBoundData();
}
catch (_com_error &e)
{
GenerateError(e.Error(), e.Description());
}
}
BOOL CRsCgDlg::IsDirty()
{
// Skip if recordset not ready.
if ( NULL == m_pRs ) return FALSE;
// Pull data into dialog member variables.
UpdateData( TRUE );
// Compare dialog members with binding members.
//if ( m_lProductID != m_lDlgProductID ) return TRUE;
if ( m_strDlgProductName.Compare( m_szProductName ) ) return TRUE;
if ( m_strDlgQuantityPerUnit.Compare( m_szQuantityPerUnit ) ) return TRUE;
//if ( m_dUnitPrice != m_dDlgUnitPrice ) return TRUE;
//if ( m_sUnitsInStock != m_sDlgUnitsInStock ) return TRUE;
//if ( m_sUnitsOnOrder != m_sDlgUnitsOnOrder ) return TRUE;
//if ( m_sReorderLevel != m_sDlgReorderLevel ) return TRUE;
return FALSE;
}
void CRsCgDlg::PrepareBoundData()
{
// Copies data from dialog member variables into
// ADO C++ binding member variables in order to
// prepare ADO C++ binding for AddNew or Update.
// Skip if recordset not ready.
if ( NULL == m_pRs ) return;
// Pull data into dialog member variables.
UpdateData( TRUE );
// Copy dialog members into ADO C++ binding members.
//m_lProductID = m_lDlgProductID;
//lProductIDStatus = adFldOK;
// For strings, copy data and then check for zero-length.
// Set the field status to adFldNull to indicate the field
// should be set to null if the length of the string is zero.
strncpy( m_szProductName, m_strDlgProductName, sizeof(m_szProductName) );
lProductNameStatus = (0==strlen(m_szProductName)) ? adFldNull : adFldOK;
strncpy( m_szQuantityPerUnit, m_strDlgQuantityPerUnit, sizeof(m_szQuantityPerUnit) );
lQuantityPerUnitStatus = (0==strlen(m_szQuantityPerUnit)) ? adFldNull : adFldOK;
//m_dUnitPrice = m_dDlgUnitPrice;
//lUnitPriceStatus = adFldOK;
//m_sUnitsInStock = m_sDlgUnitsInStock;
//lUnitsInStockStatus = adFldOK;
//m_sUnitsOnOrder = m_sDlgUnitsOnOrder;
//lUnitsOnOrderStatus = adFldOK;
//m_sReorderLevel = m_sDlgReorderLevel;
//lReorderLevelStatus = adFldOK;
}
void CRsCgDlg::SaveRecord()
{
// Skip if recordset not ready.
if ( NULL == m_pRs ) return;
// Copy data from dialog into ADO C++ binding members.
PrepareBoundData();
// Call Update method of IADORecordBinding interface,
// passing in dialog class which doubles as our CADORecordBinding structure.
HRESULT hr = m_piAdoRecordBinding->Update( (CADORecordBinding*)this );
if ( FAILED(hr) )
{
TraceADOErrors();
TraceFieldStatus();
GenerateError( hr, L"CRsCgDlg::SaveRecord() Failed." );
}
RefreshBoundData();
}
void CRsCgDlg::AddRecord()
{
// Skip if recordset not ready.
if ( NULL == m_pRs ) return;
// 资料复制到对话框到C + +中使用ADO成员具有约束力
PrepareBoundData();
// Call AddNew method of IADORecordBinding interface,
// passing in dialog class which doubles as our CADORecordBinding structure.
HRESULT hr = m_piAdoRecordBinding->AddNew( (CADORecordBinding*)this );
if ( FAILED(hr) )
{
TraceADOErrors();
TraceFieldStatus();
GenerateError( hr, L"CRsCgDlg::AddRecord() Failed." );
}
RefreshBoundData();
}
void CRsCgDlg::OnSaveRecord()
{
// Check if record is dirty, then save record.
if ( IsDirty() )
{
SaveRecord();
}
}
void CRsCgDlg::OnAddRecord()
{
AddRecord();
}
void CRsCgDlg::OnDeleteRecord()
{
// Skip if recordset not ready.
if ( NULL == m_pRs ) return;
// Delete record and refresh recordset.
m_pRs->Delete( adAffectCurrent );
OnBtnMoveFirst();
}
void CRsCgDlg::TraceFieldStatus()
{
// Generic code to trace the status flag for each
// field in the ADO binding structure.
// By checking the field status indicators, you can
// see which field(s) caused errors during an
// AddNew or Update call.
const char* szStatus[] = { "adFldOK","adFldBadAccessor","adFldCantConvertValue","adFldNull",
"adFldTruncated","adFldSignMismatch","adFldDataOverFlow","adFldCantCreate",
"adFldUnavailable","adFldPermissionDenied","adFldIntegrityViolation",
"adFldSchemaViolation","adFldBadStatus","adFldDefault" };
// Note: GetADOBindingEntries is defined by the BEGIN_ADO_BINDING macro.
// It returns a pointer to an array of ADO_BINDING_ENTRY records.
// The END_ADO_BINDING() macro adds the last array entry and sets the
// ulOrdinal member to 0 so you can use this member to check for the
// end of the array.
const ADO_BINDING_ENTRY* pBindingArray = GetADOBindingEntries();
CCustomRs* pBindingClass = (CCustomRs*) this;
TRACE( _T("Listing ADO VC++ Binding field status information:\n") );
while ( pBindingArray->ulOrdinal )
{
TRACE( _T("Field[%d].Status=%s\n"),
pBindingArray->ulOrdinal,
szStatus[ *( (ULONG*) (((BYTE*)pBindingClass) + pBindingArray->ulStatusOffset) ) ] );
pBindingArray++;
}
}
void CRsCgDlg::TraceADOErrors()
{
// Generic code for looping through ADO errors collection.
// Skip if recordset not ready.
if ( NULL == m_pRs ) return;
_ConnectionPtr conn = NULL;
// Cast _variant_t -> IDispatch* -> _Connection*
// These casts result in QueryInterface calls since we
// are using smart pointers.
conn = (_Connection *) (IDispatch*) m_pRs->GetActiveConnection();
ErrorPtr err;
TRACE( _T("Listing ADO Errors collection:\n") );
for ( long i=0; i<conn->Errors->Count; i++ )
{
err = conn->Errors->Item[i];
TRACE( _T("Err[%lu].Number : 0x%08x\n"), i, err->Number );
// Cast _bstr_t to char* to do BSTR -> ANSI string conversion.
TRACE( _T("Err[%lu].Description: %s\n"), i, (char*) err->Description );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -