📄 mapxsampview.cpp
字号:
// construct a safearray of column numbers (could use names instead)
SAFEARRAY FAR* psa=NULL;
SAFEARRAYBOUND rgsabound[1];
long ix;
rgsabound[0].lLbound = 1;
rgsabound[0].cElements = n;
psa = SafeArrayCreate(VT_I4, 1, rgsabound);
if(psa == NULL){
return;
}
for (int i=0; i< n; i++) {
ix=i+1;
SafeArrayPutElement(psa, &ix, &FieldNums[i]);
}
// put array in field param
Field.vt = VT_ARRAY | VT_I4;
Field.parray = psa;
try {
// get themes collection
CMapXThemes objThemes = m_ctrlMapX.GetDatasets()[1L].GetThemes();
// want to see full legend
m_ctrlMapX.SetPreferCompactLegends(FALSE);
// add theme - will be visible by default
CMapXTheme thm = objThemes.Add(Type, Field, Name);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
// clean up fields array
if (psa)
SafeArrayDestroy(psa);
}
void CMapxSampleView::OnSetFocus(CWnd* pOldWnd)
{
CView::OnSetFocus(pOldWnd);
m_ctrlMapX.SetFocus();
}
// tool handlers
// all we need to do is tell mapx
// which tool we are using
void CMapxSampleView::OnMapToolArrow()
{
m_ctrlMapX.SetCurrentTool(miArrowTool);
}
void CMapxSampleView::OnMapToolCenter()
{
m_ctrlMapX.SetCurrentTool(miCenterTool);
}
void CMapxSampleView::OnMapToolPan()
{
m_ctrlMapX.SetCurrentTool(miPanTool);
}
void CMapxSampleView::OnMapToolRadiusselect()
{
m_ctrlMapX.SetCurrentTool(miRadiusSelectTool);
}
void CMapxSampleView::OnMapToolRectangleselect()
{
m_ctrlMapX.SetCurrentTool(miRectSelectTool);
}
void CMapxSampleView::OnMapToolSelect()
{
m_ctrlMapX.SetCurrentTool(miSelectTool);
}
void CMapxSampleView::OnMapToolPolygonselect()
{
m_ctrlMapX.SetCurrentTool(miPolygonSelectTool);
}
void CMapxSampleView::OnMapToolZoomout()
{
m_ctrlMapX.SetCurrentTool(miZoomOutTool);
}
void CMapxSampleView::OnMapToolZoomin()
{
m_ctrlMapX.SetCurrentTool(miZoomInTool);
}
void CMapxSampleView::OnContextPreviousview()
{
m_ctrlMapX.ZoomTo(m_dPrevZoom, m_dPrevX, m_dPrevY);
}
void CMapxSampleView::OnUpdateContextPreviousview(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_dPrevZoom != 0);
}
// remember the previous view settings
// for the previous view command
BOOL CMapxSampleView::OnMapViewChanged()
{
m_dPrevZoom = m_dCurZoom;
m_dPrevX = m_dCurX;
m_dPrevY = m_dCurY;
try {
m_dCurZoom = m_ctrlMapX.GetZoom();
m_dCurX = m_ctrlMapX.GetCenterX();
m_dCurY = m_ctrlMapX.GetCenterY();
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
return TRUE;
}
// copy map to clipboard as a metafile
// by making the width and height params optional
// we are telling mapx to use the width and height
// of the map as it is displayed
void CMapxSampleView::OnEditCopy()
{
// turn off the scale bar, because the way
// we draw it, it is only accurate if the metafile is
// drawn at the same size as the map, and it would be
/// confusing to be showing an incorrect scale on the map
// not a problem for other formats, just metafiles, because they can scale
if (m_bScaleBar) {
m_ctrlMapX.GetLayers().Item("ScaleBar").SetVisible(FALSE);
}
m_ctrlMapX.ExportMap("clipboard", miFormatWMF);
if (m_bScaleBar) {
m_ctrlMapX.GetLayers().Item("ScaleBar").SetVisible(TRUE);
}
}
static char BASED_CODE szTabFilter[] = "MapInfo Map Files (*.tab)|*.tab|All Files (*.*)|*.*||";
// display a file open dialog to get 1 or more filenames
// then open the mapinfo .tab files one at a time
void CMapxSampleView::OnFileOpen()
{
CFileDialog dlgFile(TRUE, "*.tab", NULL, 0, szTabFilter, this);
dlgFile.m_ofn.lpstrTitle = "Open MapInfo Tables";
// We want a multiple select file open, but on NT 3.51 the GetNextPathName() call
// returns bogus filenames (Can't handle spaces I think.)
// So if NT 3.51 or less, then don't set the multi-select flag
OSVERSIONINFO vers;
vers.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&vers)) {
if (vers.dwMajorVersion < 4 && vers.dwPlatformId == VER_PLATFORM_WIN32_NT) {
// no multiple select
}
else {
dlgFile.m_ofn.Flags |= OFN_ALLOWMULTISELECT;
}
}
if (dlgFile.DoModal() == IDCANCEL)
return;
try {
POSITION pos = dlgFile.GetStartPosition();
CString strFile;
while (pos) {
strFile = dlgFile.GetNextPathName(pos);
m_ctrlMapX.GetLayers().Add(strFile);
}
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
// zoom out to see whole map
void CMapxSampleView::OnViewViewentiremap()
{
try {
m_ctrlMapX.SetZoom(m_ctrlMapX.GetGeoSetWidth());
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
// print using current size of map
void CMapxSampleView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
try {
double dPaperWidth;
double dPaperHeight;
CPoint ptVpOrg;
CSize szVExt;
// get paper width in cm and convert to HIMETRIC (100th of a mm)
m_ctrlMapX.SetPaperUnit(miUnitCentimeter);
dPaperWidth = m_ctrlMapX.GetMapPaperWidth() * 10 * 100;
dPaperHeight = m_ctrlMapX.GetMapPaperHeight()* 10 * 100;
// figure out where the preview dc wants us to draw
// convert to himetric - Using DPtoHIMETRIC was using the
// printer DC, but we the starting points returned by
// GetViewportOrgEx were actually screen device units,
// so I convert to himetric assuming 96.0 pixels per inch
// (could use get sysmetrics on a screen device to be sure)
::GetViewportOrgEx(pDC->m_hDC, &ptVpOrg);
ptVpOrg.x = (long)((double)ptVpOrg.x/96.0 * 2540.0);
ptVpOrg.y = (long)((double)ptVpOrg.y/96.0 * 2540.0);
if (pInfo->m_bPreview) {
// now get our drawing width in himetric
// during print preview the ViewportExtent has this
::GetViewportExtEx(pDC->m_hDC, &szVExt);
pDC->DPtoHIMETRIC(&szVExt);
// also, keep the aspect ration of the map so it isn't distorted
szVExt.cy = (long)((double)szVExt.cy * (dPaperHeight/dPaperWidth));
m_ctrlMapX.PrintMap((long)pDC->m_hDC, ptVpOrg.x, ptVpOrg.y, szVExt.cx, szVExt.cy);
}
else {
m_ctrlMapX.PrintMap((long)pDC->m_hDC, ptVpOrg.x, ptVpOrg.y, (long)dPaperWidth, (long)dPaperHeight);
}
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
void CMapxSampleView::OnViewLayercontrol()
{
try {
VARIANT vHelpFile, vHelpID; // mark as optional since we don't have a helpfile
vHelpFile.vt = VT_ERROR;
vHelpFile.scode = DISP_E_PARAMNOTFOUND;
vHelpID.vt = VT_ERROR;
vHelpID.scode = DISP_E_PARAMNOTFOUND;
CMapXLayers layers = m_ctrlMapX.GetLayers();
layers.LayersDlg(vHelpFile, vHelpID);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
void CMapxSampleView::OnToolUsed(short ToolNum, double X1, double Y1, double X2, double Y2, double Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault)
{
CString str;
str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %s\n",
ToolNum, X1,Y1,X2,Y2,Distance, (Shift)?"Shift":"",(Ctrl)?"Ctrl":"");
TRACE(str);
//AfxMessageBox(str);
// this info tool will pop up a modal dlg
// with info from the dataset(1)
// Note that we are only getting info from the MapX Dataset
// you could use the SourceRows collection to get back
// to the source data to display info from dao, odbc or whatever
if (ToolNum == MYTOOL_INFO) {
try {
if (m_ctrlMapX.GetDatasets().GetCount() == 0) {
AfxMessageBox("This info tool requires that a dataset be added.");
return;
}
CMapXPoint pt;
CMapXFeatures fs;
CMapXFeature f;
CMapXDataset ds;
pt.CreateDispatch(pt.GetClsid());
pt.Set(X1,Y1);
fs = m_ctrlMapX.GetLayers().Item("USA").SearchAtPoint(pt);
// just use first feature from collection. Since usa is a layer of
// all regions, we will not get back > 1 feature in the collection
// because there are no overlapping regions
if (fs.GetCount() != 1) {
return;
}
f = fs.Item(1);
ds = m_ctrlMapX.GetDatasets().Item(1);
CInfoDlg dlg;
COleVariant vRow;
COleVariant vVal;
vRow.vt = VT_DISPATCH;
vRow.pdispVal = f.m_lpDispatch;
vRow.pdispVal->AddRef();
vVal = ds.GetValue(vRow, COleVariant(2L));
vVal.ChangeType(VT_BSTR);
dlg.m_strState = vVal.bstrVal;
vVal = ds.GetValue(vRow, COleVariant(3L));
vVal.ChangeType(VT_R8);
dlg.m_dTotal = vVal.dblVal;
vVal = ds.GetValue(vRow, COleVariant(4L));
vVal.ChangeType(VT_R8);
dlg.m_dFemale = vVal.dblVal;
vVal = ds.GetValue(vRow, COleVariant(5L));
vVal.ChangeType(VT_R8);
dlg.m_dMale = vVal.dblVal;
dlg.DoModal();
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
}
// on objects passed to events, the event handler does not change the reference count
// ie: do not call release on the object
void CMapxSampleView::OnThemeModifyRequested(LPDISPATCH Theme)
{
try {
CMapXTheme theme;
VARIANT vHelpFile, vHelpID; // mark as optional since we don't have a helpfile
vHelpFile.vt = VT_ERROR;
vHelpFile.scode = DISP_E_PARAMNOTFOUND;
vHelpID.vt = VT_ERROR;
vHelpID.scode = DISP_E_PARAMNOTFOUND;
theme.AttachDispatch(Theme, FALSE); // don't auto release
theme.ThemeDlg(vHelpFile, vHelpID);
// could decide to bring up legend dlg here instead
//CMapXLegend leg(theme.GetLegend());
//leg.LegendDlg(vHelpFile, vHelpID);
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
void CMapxSampleView::OnUpdateViewScalebar(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_bScaleBar);
}
void CMapxSampleView::OnViewScalebar()
{
try {
if(m_bScaleBar)
{
m_ctrlMapX.GetLayers().Remove("ScaleBar");
m_bScaleBar = FALSE;
}
else
{
m_ctrlMapX.GetLayers().AddUserDrawLayer("ScaleBar", 1);
m_bScaleBar = TRUE;
}
}
catch (COleDispatchException *e) {
e->ReportError();
e->Delete();
}
catch (COleException *e) {
e->ReportError();
e->Delete();
}
}
// Draw the Scalebar layer whenever this event is called
// we could check the Layer.Name property if we needed to handle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -