ZoomOut.cpp
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // #include "ZoomOut.h" ZoomOut::ZoomOut() { m_ipHookHelper.CreateInstance(CLSID_HookHelper); // Load the cursors ISystemMouseCursorPtr ipSysMouseCur(CLSID_SystemMouseCursor); ipSysMouseCur->LoadFromFile(CComBSTR(L"./Res/ZoomOut.CUR")); OLE_HANDLE hTmp; HRESULT hr = ipSysMouseCur->get_Cursor(&hTmp); if (SUCCEEDED(hr)) m_hCursor = hTmp; ipSysMouseCur->LoadFromFile(CComBSTR(L"./Res/MoveZoomOut.cur")); hr = ipSysMouseCur->get_Cursor(&hTmp); if (SUCCEEDED(hr)) m_hCursorMove = hTmp; // Load the bitmap IRasterPicturePtr ipRastPict(CLSID_BasicRasterPicture); IPicturePtr ipPict; hr = ipRastPict->LoadPicture(CComBSTR(L"./Res/ZoomOut.bmp"), &ipPict); if (SUCCEEDED(hr)) { OLE_HANDLE hBitmap; hr = ipPict->get_Handle(&hBitmap); if (SUCCEEDED(hr)) m_hBitmap = hBitmap; } } ZoomOut::~ZoomOut() { m_ipHookHelper = 0; m_hBitmap = 0; m_hCursor = 0; m_hCursorMove = 0; m_ipPoint = 0; m_ipFeedback = 0; } HRESULT ZoomOut::get_Enabled(VARIANT_BOOL* Enabled) { if (!Enabled) return E_POINTER; IMapPtr ipMap; m_ipHookHelper->get_FocusMap(&ipMap); if (ipMap == 0) return S_OK; *Enabled = VARIANT_TRUE; return S_OK; } HRESULT ZoomOut::get_Checked(VARIANT_BOOL* Checked) { if (!Checked) return E_POINTER; *Checked = VARIANT_FALSE; return S_OK; } HRESULT ZoomOut::get_Name(BSTR* Name) { if (!Name) return E_POINTER; *Name = ::AoAllocBSTR(L"Sample_Pan/Zoom_Zoom Out"); return S_OK; } HRESULT ZoomOut::get_Caption(BSTR* Caption) { if (!Caption) return E_POINTER; *Caption = ::AoAllocBSTR(L"Zoom Out"); return S_OK; } HRESULT ZoomOut::get_Tooltip(BSTR* Tooltip) { if (!Tooltip) return E_POINTER; *Tooltip = ::AoAllocBSTR(L"Zoom Out"); return S_OK; } HRESULT ZoomOut::get_Message(BSTR* Message) { if (!Message) return E_POINTER; *Message = ::AoAllocBSTR(L"Zooms the Display Out By Rectangle Or Single Click"); return S_OK; } HRESULT ZoomOut::get_Bitmap(OLE_HANDLE* bitmap) { if (!bitmap) return E_POINTER; if (m_hBitmap != 0) { *bitmap = m_hBitmap; return S_OK; } return E_FAIL; } HRESULT ZoomOut::get_Category(BSTR* categoryName) { if (!categoryName) return E_POINTER; *categoryName = ::AoAllocBSTR(L"Sample_Pan/Zoom"); return S_OK; } // Create the command and set who it will work with HRESULT ZoomOut::OnCreate(IDispatch* hook) { if (!hook) return E_POINTER; m_ipHookHelper->putref_Hook(hook); return S_OK; } // When clicked, the button appears pressed HRESULT ZoomOut::OnClick() { return S_OK; } HRESULT ZoomOut::get_Cursor(OLE_HANDLE* cursorName) { if (cursorName == NULL) return E_POINTER; if (m_hCursor != 0 && !m_bInUse) { *cursorName = m_hCursor; return S_OK; } else if (m_hCursorMove !=0 && m_bInUse) { *cursorName = m_hCursorMove; return S_OK; } return E_FAIL; } HRESULT ZoomOut::OnMouseDown(LONG Button, LONG Shift, LONG X, LONG Y) { IActiveViewPtr ipActiveView; m_ipHookHelper->get_ActiveView(&ipActiveView); if (ipActiveView == 0) return S_OK; // If the active view is a page layout IPageLayoutPtr ipPageLayout(ipActiveView); if (ipPageLayout != 0) { // Create a point in map coordinates IScreenDisplayPtr ipPLScreenDisp; ipActiveView->get_ScreenDisplay(&ipPLScreenDisp); IDisplayTransformationPtr ipPLDispTrans; ipPLScreenDisp->get_DisplayTransformation(&ipPLDispTrans); IPointPtr ipPLPoint; ipPLDispTrans->ToMapPoint(X, Y, &ipPLPoint); // Get the map if the point is within a data frame IMapPtr ipMap; ipActiveView->HitTestMap(ipPLPoint, &ipMap); if (ipMap == 0) return S_OK; // Set the map to be the page layout's focus map IMapPtr ipFocusMap; m_ipHookHelper->get_FocusMap(&ipFocusMap); if (ipMap != ipFocusMap) { ipActiveView->putref_FocusMap(ipMap); ipActiveView->PartialRefresh(esriViewGraphics, NULL, NULL); } } // Create a point in map coordinates IMapPtr ipMap; m_ipHookHelper->get_FocusMap(&ipMap); IActiveViewPtr ipAVFocusMap(ipMap); IScreenDisplayPtr ipScreenDisp; ipAVFocusMap->get_ScreenDisplay(&ipScreenDisp); IDisplayTransformationPtr ipDispTrans; ipScreenDisp->get_DisplayTransformation(&ipDispTrans); ipDispTrans->ToMapPoint(X, Y, &m_ipPoint); m_bInUse = true; // Start capturing mouse events //************************************* return S_OK; } HRESULT ZoomOut::OnMouseMove(LONG Button, LONG Shift, LONG X, LONG Y) { if (!m_bInUse) return S_OK; // Get the focus map IMapPtr ipMap; m_ipHookHelper->get_FocusMap(&ipMap); IActiveViewPtr ipActiveView(ipMap); // Start an envelope feedback if (m_ipFeedback == 0) { m_ipFeedback.CreateInstance(CLSID_NewEnvelopeFeedback); IScreenDisplayPtr ipScreenDisp; ipActiveView->get_ScreenDisplay(&ipScreenDisp); m_ipFeedback->putref_Display(ipScreenDisp); m_ipFeedback->Start(m_ipPoint); } // Move the envelope feedback IPointPtr ipMoveTo; IScreenDisplayPtr ipScreenDisp; ipActiveView->get_ScreenDisplay(&ipScreenDisp); IDisplayTransformationPtr ipDispTrans; ipScreenDisp->get_DisplayTransformation(&ipDispTrans); ipDispTrans->ToMapPoint(X, Y, &ipMoveTo); m_ipFeedback->MoveTo(ipMoveTo); return S_OK; } HRESULT ZoomOut::OnMouseUp(LONG Button, LONG Shift, LONG X, LONG Y) { if (!m_bInUse) return S_OK; // Stop capturing mouse events //************************************* IEnvelopePtr ipEnv; IEnvelopePtr ipFeedEnv; // Get the focus map IMapPtr ipMap; m_ipHookHelper->get_FocusMap(&ipMap); IActiveViewPtr ipActiveView(ipMap); if (m_ipFeedback == 0) // If an envelope has not been tracked { // Zoom out from the mouse click ipActiveView->get_Extent(&ipEnv); ipEnv->Expand(2, 2, VARIANT_TRUE); ipEnv->CenterAt(m_ipPoint); } else // An env is being tracked { // Stop the envelope feedback m_ipFeedback->Stop(&ipFeedEnv); // Exit if the envelope height or width is 0 double dHeight; double dWidth; ipFeedEnv->get_Width(&dWidth); ipFeedEnv->get_Height(&dHeight); if (dWidth == 0 || dHeight == 0) { m_ipFeedback = 0; m_bInUse = false; return S_OK; } // Create new extent height and width double dExtWidth; double dExtHeight; double dNewWidth; double dNewHeight; IEnvelopePtr ipExtEnv; ipActiveView->get_Extent(&ipExtEnv); ipExtEnv->get_Width(&dExtWidth); dNewWidth = dExtWidth * (dExtWidth / dWidth); ipExtEnv->get_Height(&dExtHeight); dNewHeight = dExtHeight * (dExtHeight / dHeight); // Set the new extent coordinates ipEnv.CreateInstance(CLSID_Envelope); double dExtXMin; ipExtEnv->get_XMin(&dExtXMin); double dExtYMin; ipExtEnv->get_YMin(&dExtYMin); double dFeedXMin; ipFeedEnv->get_XMin(&dFeedXMin); double dFeedYMin; ipFeedEnv->get_YMin(&dFeedYMin); double dFeedWidth; ipFeedEnv->get_Width(&dFeedWidth); double dFeedHeight; ipFeedEnv->get_Height(&dFeedHeight); double dBaseXMin = dExtXMin - ((dFeedXMin - dExtXMin) * (dExtWidth / dFeedWidth)); double dBaseYMin = dExtYMin - ((dFeedYMin - dExtYMin) * (dExtHeight / dFeedHeight)); ipEnv->PutCoords(dBaseXMin, dBaseYMin, dBaseXMin + dNewWidth, dBaseYMin + dNewHeight); } // Set the new extent ipActiveView->put_Extent(ipEnv); ipActiveView->Refresh(); m_ipFeedback = 0; m_bInUse = false; return S_OK; } HRESULT ZoomOut::OnDblClick() { return E_NOTIMPL; } HRESULT ZoomOut::OnKeyDown(LONG keyCode, LONG Shift) { if (m_bInUse) if (keyCode == 27) // ESC key { //***************************** // RELEASE CAPTURE //***************************** m_ipFeedback = 0; m_bInUse = false; IActiveViewPtr ipActiveView; m_ipHookHelper->get_ActiveView(&ipActiveView); ipActiveView->PartialRefresh(esriViewForeground, NULL, NULL); } return S_OK; } HRESULT ZoomOut::OnKeyUp(LONG keyCode, LONG Shift) { return E_NOTIMPL; } HRESULT ZoomOut::OnContextMenu(LONG X, LONG Y, VARIANT_BOOL* handled) { return E_NOTIMPL; } HRESULT ZoomOut::Refresh(OLE_HANDLE ole) { return E_NOTIMPL; } HRESULT ZoomOut::Deactivate(VARIANT_BOOL* complete) { if (!complete) return E_POINTER; *complete = VARIANT_TRUE; return S_OK; }