📄 serialsampledoc.cpp
字号:
// SerialSampleDoc.cpp : implementation of the CSerialSampleDoc class
//
/* This sample application and corresponding sample code is provided
* for example purposes only. It has not undergone rigorous testing
* and as such should not be shipped as part of a final application
* without extensive testing on the part of the organization releasing
* the end-user product.
*/
#include "stdafx.h"
#include "SerialSample.h"
#include "SerialSampleDoc.h"
#include "IHelper.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CDaoDatabase CSerialSampleDoc::s_db;
/////////////////////////////////////////////////////////////////////////////
// CSerialSampleDoc
IMPLEMENT_DYNCREATE(CSerialSampleDoc, CDocument)
BEGIN_MESSAGE_MAP(CSerialSampleDoc, CDocument)
//{{AFX_MSG_MAP(CSerialSampleDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSerialSampleDoc construction/destruction
CSerialSampleDoc::CSerialSampleDoc()
{
// TODO: add one-time construction code here
}
CSerialSampleDoc::~CSerialSampleDoc()
{
if(s_db.IsOpen())
s_db.Close();
}
/////////////////////////////////////////////////////////////////////////////
// CSerialSampleDoc serialization
void CSerialSampleDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CSerialSampleDoc diagnostics
#ifdef _DEBUG
void CSerialSampleDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CSerialSampleDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSerialSampleDoc commands
/*
* Public Accessor for the Map control (for CSerialSampleView). Returns NULL
* if it isn't valid yet.
*/
CMapX* CSerialSampleDoc::GetMap() {
if(m_ctrlMapX.m_hWnd == NULL)
return NULL;
else
return &m_ctrlMapX;
}
CSerialSampleView* CSerialSampleDoc::GetMainView() {
POSITION pos = GetFirstViewPosition();
CView* view = GetNextView(pos);
if(view != NULL && view->IsKindOf(RUNTIME_CLASS(CSerialSampleView)))
return static_cast<CSerialSampleView*>(view);
else
return NULL;
}
BOOL CSerialSampleDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
CSerialSampleView* view = GetMainView();
if(view == NULL)
return FALSE;
RECT windRect;
view->GetClientRect(&windRect);
if(!m_ctrlMapX.Create(NULL, WS_VISIBLE, windRect, view, IDC_MAP))
return FALSE;
return TRUE;
}
BOOL CSerialSampleDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
CSerialSampleView* view = GetMainView();
if(view == NULL)
return FALSE;
CFileException except;
CFile* file = GetFile(lpszPathName, CFile::modeReadWrite | CFile::modeNoTruncate, &except);
if(file == NULL)
return FALSE;
RECT windRect;
view->GetClientRect(&windRect);
if(!m_ctrlMapX.Create(NULL, WS_VISIBLE, windRect, view, IDC_MAP, file, TRUE)) {
file->Close();
return FALSE;
}
file->Close();
IStorage* stg, *dsstg;
try {
stg = OpenStorage(lpszPathName);
dsstg = OpenSubstorage(stg,"DATASETS");
CStringList datasets;
EnumElementNames(&datasets, dsstg);
CDaoDatabase* curDB = GetDB();
for(POSITION i = datasets.GetHeadPosition(); i != NULL; ) {
COleVariant rsVt;
const CString stgName = datasets.GetNext(i);
CString dsName;
dsName = ReadStream(dsstg, stgName);
CDaoRecordset rs(curDB);
rs.Open(dbOpenTable, dsName);
rsVt.vt = VT_DISPATCH;
rsVt.pdispVal = rs.m_pDAORecordset;
rsVt.pdispVal->AddRef();
m_ctrlMapX.GetDatasets().Restore(dsName,rsVt);
rs.Close();
}
} catch(COleDispatchException* e) {
e->ReportError();
e->Delete();
} catch(COleException* e) {
e->ReportError();
e->Delete();
} catch(CFileException* e) {
e->Delete();
}
// Executed even when an error is thrown
CloseStorage(dsstg);
CloseStorage(stg);
return TRUE;
}
BOOL CSerialSampleDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
IPersistStorage* persStg = NULL;
IUnknown* control;
IStorage *stg, *dsstg;
HRESULT result;
try {
stg = CreateStorage(lpszPathName);
} catch(CFileException* e) {
e->Delete();
return FALSE;
}
dsstg = CreateSubstorage(stg, "DATASETS");
CString stgName;
for(int i = 1; i <= m_ctrlMapX.GetDatasets().GetCount(); i++) {
stgName.Format("%d", i);
CreateStream(dsstg, stgName, m_ctrlMapX.GetDatasets().Item(i).GetName());
}
SaveStorage(dsstg);
control = m_ctrlMapX.GetControlUnknown();
if(control == NULL)
return FALSE;
control->QueryInterface(IID_IPersistStorage,(void**)&persStg);
if(persStg == NULL) {
CloseStorage(stg);
return FALSE;
}
result = OleSave(persStg, stg, FALSE);
persStg->Release();
CloseStorage(stg);
if(result != S_OK)
return FALSE;
else
return TRUE;
}
CDaoDatabase* CSerialSampleDoc::GetDB() {
if(!s_db.IsOpen()) {
try {
const CString dbPath = GetDBPath();
s_db.Open(dbPath);
} catch(CString s) { // couldn't find path to demographic database
return NULL;
}
}
if(s_db.IsOpen())
return &s_db;
else
return NULL;
}
void CSerialSampleDoc::AddDataset(const CString tableName) {
CDaoRecordset rs(GetDB());
COptionalVariant optVt;
COleVariant titleVt(tableName);
COleVariant rsVt;
COleVariant bindLayerVt;
COleVariant geofieldVt;
rs.Open(dbOpenTable, tableName);
rsVt.vt = VT_DISPATCH;
rsVt.pdispVal = rs.m_pDAORecordset;
rsVt.pdispVal->AddRef();
if(tableName == "USA") {
bindLayerVt = "USA";
geofieldVt = "GEOABBR";
} else if(tableName == "US_cust") {
bindLayerVt = "USA";
geofieldVt = "STATE";
} else if(tableName.Find("County") == 0) {
bindLayerVt = "US County Boundaries";
geofieldVt = "Cnty_fips";
} else {
bindLayerVt.vt = VT_ERROR;
bindLayerVt.scode = DISP_E_PARAMNOTFOUND;
geofieldVt.vt = VT_ERROR;
geofieldVt.scode = DISP_E_PARAMNOTFOUND;
}
try {
theApp.DoWaitCursor(1);
if(GetMap() != NULL)
GetMap()->GetDatasets().Add(miDataSetDAO, rsVt, titleVt, geofieldVt, optVt, bindLayerVt, optVt, optVt);
theApp.DoWaitCursor(0);
} catch(COleDispatchException* e) {
e->ReportError();
e->Delete();
} catch(COleException* e) {
e->ReportError();
e->Delete();
}
}
/*
* Try to locate the MapStats.mdb demographic database. If it succeeds, it will return
* the path to the database. If it fails, it will return the empty string.
*/
const CString CSerialSampleDoc::GetDBPath() /*throw(CString)*/{
// find the MapX path from the registry, then, search for <MapX path>\Data\MapStats.mdb
DWORD retCode;
HKEY key;
CString strKey("SOFTWARE\\MapInfo\\MapX\\");
CString strVer = m_ctrlMapX.GetVersion();
int v1, v2, v3;
sscanf(strVer.GetBuffer(0), "%d.%d.%d", &v1, &v2, &v3);
strVer.Format("%d.0", v1);
strKey = strKey + strVer;
retCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKey, 0, KEY_READ, &key);
if(retCode != ERROR_SUCCESS) {
retCode = RegOpenKeyEx(HKEY_CURRENT_USER, strKey, 0, KEY_READ, &key);
if(retCode != ERROR_SUCCESS) {
CString strMsg("Could not find MapX registry key \"");
strMsg = strMsg + strKey + "\" in either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER";
throw strMsg;
}
}
ULONG valueLength = MAX_PATH;
CString path;
DWORD type;
retCode = RegQueryValueEx(key, "ProgramDir", NULL, &type, (LPBYTE)path.GetBuffer(valueLength), &valueLength);
path.ReleaseBuffer();
RegCloseKey(key);
if(retCode != ERROR_SUCCESS)
throw CString("Found MapX in registry, but could not open subkey \"ProgramDir\"");
if(type != REG_SZ)
throw CString("Found MapX ProgramDir key in registry, but it is of non-string type");
path += "\\Data\\MapStats.mdb";
if(!FileExists(path)) {
CString msg;
msg.Format("Could not find demographic database \"%s\"", path);
throw msg;
}
return path;
}
bool CSerialSampleDoc::FileExists(const CString path) {
CFileStatus fileStat;
return CFile::GetStatus(path, fileStat) != 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -