📄 mapxdataset.cpp
字号:
else {
dTmp = 0.0;
}
SafeArrayPutElement(psa, &nCount, &dTmp);
break;
}
case VT_BSTR: {
CString strVal;
if( strColumnName.CompareNoCase("StateAbbr") == 0 ){
strVal = aachStateAbbr[iRows];
}
else if( strColumnName.CompareNoCase("TOTPOPHIS") == 0 ){
strVal="";
}
else if( strColumnName.CompareNoCase("TOTPOPCUR") == 0 ){
strVal="";
}
else if( strColumnName.CompareNoCase("TOTPOPPRO") == 0 ){
strVal="";
}
else {
strVal="";
}
BSTR bstrVal = strVal.AllocSysString();
SafeArrayPutElement(psa, &nCount, bstrVal);
break;
}
default:
// Shouldn't ever happen
break;
}
}
}
catch (...) {
*pNumRecordsFetched = -1;
if( psa!=NULL ) {
SafeArrayDestroy(psa);
}
return E_FAIL;
}
pvarData->vt = vtRequested | VT_ARRAY;
pvarData->parray = psa;
*pNumRecordsFetched = nCount;
return S_OK;
}
// IMMapXStaticDataset interface
// TODO: Implement the routines in this interface.
// See IMMapXStaticDataset Interface specification for details.
STDMETHODIMP CMapXSampleDataset::BeginFetch()
{
return S_OK;
}
STDMETHODIMP CMapXSampleDataset::EndFetch()
{
return S_OK;
}
STDMETHODIMP CMapXSampleDataset::FetchData(long lColNum, long lIdxRow, VARTYPE vtRequested, VARIANT* pvarData, BOOL * pbNoMoreData)
{
HRESULT hrRet = S_OK;
if ( lIdxRow > (sizeof(aachStateAbbr) / sizeof(aachStateAbbr[0]) ) ){
*pbNoMoreData = TRUE;
return hrRet;
}
try {
IMMapXColumnInfo* pIMMapXColumnInfo;
HRESULT hr = GetColumnInfoByIndex( lColNum, &pIMMapXColumnInfo);
if( FAILED(hr) ) throw hr;
CComBSTR bstrColumnName;
hr = pIMMapXColumnInfo->GetName(&bstrColumnName);
if( FAILED(hr) ) throw hr;
pIMMapXColumnInfo->Release();
CString strColumnName = bstrColumnName;
switch (vtRequested) {
// TODO: we cheat here because we know that currently MapX
// will ask for only doubles or BSTR's. You shouldn't.
case VT_R8: {
double dTmp;
if( strColumnName.CompareNoCase("StateAbbr") == 0 ){
dTmp = 0.0;
}
else if( strColumnName.CompareNoCase("TOTPOPHIS") == 0 ){
dTmp = alTOTPOPHIS[lIdxRow];
}
else if( strColumnName.CompareNoCase("TOTPOPCUR") == 0 ){
dTmp = alTOTPOPCUR[lIdxRow];
}
else if( strColumnName.CompareNoCase("TOTPOPPRO") == 0 ){
dTmp = alTOTPOPPRO[lIdxRow];
}
else {
dTmp = 0.0;
}
pvarData->vt = VT_R8;
pvarData->dblVal = dTmp;
break;
}
case VT_BSTR: {
CString strVal;
if( strColumnName.CompareNoCase("StateAbbr") == 0 ){
strVal = aachStateAbbr[lIdxRow];
}
else if( strColumnName.CompareNoCase("TOTPOPHIS") == 0 ){
strVal.Format("%d",alTOTPOPHIS[lIdxRow]);
}
else if( strColumnName.CompareNoCase("TOTPOPCUR") == 0 ){
strVal.Format("%d",alTOTPOPCUR[lIdxRow]);
}
else if( strColumnName.CompareNoCase("TOTPOPPRO") == 0 ){
strVal.Format("%d",alTOTPOPPRO[lIdxRow]);
}
else {
strVal = "";
}
pvarData->vt = VT_BSTR;
pvarData->bstrVal = strVal.AllocSysString();
break;
}
default:
// Shouldn't ever happen
break;
}
}
catch( HRESULT hrThrown ) {
hrRet = hrThrown;
}
return hrRet;
}
#define MAX_KEY_LEN 3
long KeyToRow(CString& strKey)
{
// This could (obviously) be much more efficient
char* pchKey = strKey.GetBuffer(MAX_KEY_LEN);
long lIdx = 0;
long lRetVal = -1;
while( lIdx <= sizeof(aachStateAbbr) / sizeof(aachStateAbbr[0]) ) {
if( strnicmp( pchKey, aachStateAbbr[lIdx], 2 ) == 0 ) {
lRetVal = lIdx;
break;
}
lIdx++;
}
strKey.ReleaseBuffer();
return lRetVal;
}
// IMMapXDynamicDataset
// TODO: Implement the routines in this interface.
// See IMMapXDynamicDataset Interface specification for details.
STDMETHODIMP CMapXSampleDataset::FetchData(long lColNum, long lKeyColNum, BSTR bstrKey, long lRefineColNum, BSTR bstrRefiningKey, VARTYPE vtRequested, VARIANT *pvarData)
{
HRESULT hrRet = S_OK;
CString strKey = bstrKey;
try {
IMMapXColumnInfo* pIMMapXColumnInfo;
HRESULT hr = GetColumnInfoByIndex( lKeyColNum, &pIMMapXColumnInfo);
if( FAILED(hr) ) throw hr;
CComBSTR bstrKeyColumnName;
hr = pIMMapXColumnInfo->GetName(&bstrKeyColumnName);
if( FAILED(hr) ) throw hr;
pIMMapXColumnInfo->Release();
CString strKeyColumnName = bstrKeyColumnName;
if( strKeyColumnName.CompareNoCase("StateAbbr") != 0 ) {
throw E_FAIL;
}
long lIdxRow = KeyToRow(strKey);
if( lIdxRow == -1 ) {
throw E_FAIL;
}
hr = GetColumnInfoByIndex( lColNum, &pIMMapXColumnInfo);
if( FAILED(hr) ) throw hr;
CComBSTR bstrColumnName;
hr = pIMMapXColumnInfo->GetName(&bstrColumnName);
if( FAILED(hr) ) throw hr;
pIMMapXColumnInfo->Release();
CString strColumnName = bstrColumnName;
switch (vtRequested) {
// TODO: we cheat here because we know that currently MapX
// will ask for only doubles or BSTR's. You shouldn't.
case VT_R8: {
double dTmp;
if( strColumnName.CompareNoCase("StateAbbr") == 0 ){
dTmp = 0.0;
}
else if( strColumnName.CompareNoCase("TOTPOPHIS") == 0 ){
dTmp = alTOTPOPHIS[lIdxRow];
}
else if( strColumnName.CompareNoCase("TOTPOPCUR") == 0 ){
dTmp = alTOTPOPCUR[lIdxRow];
}
else if( strColumnName.CompareNoCase("TOTPOPPRO") == 0 ){
dTmp = alTOTPOPPRO[lIdxRow];
}
else {
dTmp = 0.0;
}
pvarData->vt = VT_R8;
pvarData->dblVal = dTmp;
break;
}
case VT_BSTR: {
CString strVal;
if( strColumnName.CompareNoCase("StateAbbr") == 0 ){
strVal = aachStateAbbr[lIdxRow];
}
else if( strColumnName.CompareNoCase("TOTPOPHIS") == 0 ){
strVal.Format("%d",alTOTPOPHIS[lIdxRow]);
}
else if( strColumnName.CompareNoCase("TOTPOPCUR") == 0 ){
strVal.Format("%d",alTOTPOPCUR[lIdxRow]);
}
else if( strColumnName.CompareNoCase("TOTPOPPRO") == 0 ){
strVal.Format("%d",alTOTPOPPRO[lIdxRow]);
}
else {
strVal = "";
}
pvarData->vt = VT_BSTR;
pvarData->bstrVal = strVal.AllocSysString();
break;
}
default:
// Shouldn't ever happen
break;
}
}
catch( HRESULT hrThrown ) {
hrRet = hrThrown;
}
return hrRet;
}
// IMMapXColumnInfoContainer interface
// The implementation of this interface is pretty standard. We provide the following
// implementation. Use it if you wish, or replace it with your own optimized/customized
// implementation if appropriate.
STDMETHODIMP CMapXSampleDataset::GetColumnInfoByName(BSTR bstrColumnName, IMMapXColumnInfo** ppIMMapXColumnInfo)
{
HRESULT hrRet = S_OK;
*ppIMMapXColumnInfo = NULL;
try {
if (!cols || !m_lCols) throw E_FAIL;
for (long l = 0; l < m_lCols; l++) {
CComBSTR bstr;
HRESULT hRes = (cols[l])->GetName(&bstr);
if( FAILED(hRes) ) throw hRes;
if( wcscmp(bstr, bstrColumnName) == 0) {
// found a match
*ppIMMapXColumnInfo = cols[l];
(*ppIMMapXColumnInfo)->AddRef();
hrRet = S_OK;
break;
}
}
}
catch(HRESULT hrThrown) {
hrRet = hrThrown;
}
return hrRet;
}
STDMETHODIMP CMapXSampleDataset::GetColumnInfoByIndex(long lIndex, IMMapXColumnInfo** ppIMMapXColumnInfo)
{
HRESULT hrRet = S_OK;
*ppIMMapXColumnInfo = NULL;
try {
if (!cols || !m_lCols) throw E_FAIL;
for (long l = 0; l < m_lCols; l++) {
long lColumnNumber;
HRESULT hr = (cols[l])->GetColumnNumber(&lColumnNumber);
if( FAILED(hr) ) return E_FAIL;
if (lColumnNumber == lIndex) {
*ppIMMapXColumnInfo = cols[l];
(*ppIMMapXColumnInfo)->AddRef();
break;
}
}
}
catch(HRESULT hrThrown) {
hrRet = hrThrown;
}
return hrRet;
}
STDMETHODIMP CMapXSampleDataset::GetColumnInfoEnumerator(IMEnumMapXColumnInfo** ppIMEnumMapXColumnInfo)
{
CComObject<CMEnumMapXColumnInfo> *penum = NULL;
try {
penum=new CComObject<CMEnumMapXColumnInfo>;
if( !penum ) throw E_OUTOFMEMORY;
// We need to give the enumerator object our unknown so it can reference count us.
// It needs to reference count us because we own the IMMapXColumnInfo*s that it is
// enumerating
// We want ATL to make it's own copy of the IMMapXColumnInfo*'s in our array for the
// enumerator object.
HRESULT hr = penum->Init(&cols[0], &cols[m_lCols], GetUnknown(), AtlFlagCopy);
if( FAILED(hr) ) {
throw hr;
}
}
catch (HRESULT hrThrown) {
if( penum ) delete penum;
return hrThrown;
}
catch(...) {
if( penum ) delete penum;
return E_FAIL;
}
// NOTE: Nothing below here can throw an exception.
// If the enumerator were created by CoCreateInstance(), our ClassFactory
// would call FinalConstruct(). But it wasn抰, so call it explicitly.
penum->InternalFinalConstructAddRef();
HRESULT hr = penum->FinalConstruct();
penum->InternalFinalConstructRelease();
if (SUCCEEDED(hr)) {
hr = penum->QueryInterface(IID_IMEnumMapXColumnInfo, reinterpret_cast<void**>(ppIMEnumMapXColumnInfo));
}
if (FAILED(hr)) {
delete penum;
}
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -