Map tips
MapTipTool.cpp
// Copyright 2011 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.
// 

  

// MapTipTool.cpp : Implementation of MapTipTool
//

#include "MapTipTool.h"

MapTipTool::MapTipTool(Widget tooltipwidget)
  : m_tooltipwidget(tooltipwidget),
    m_ipPoint(CLSID_Point),
    m_layerIndex(-1),
    m_fieldIsSet(false),
    m_hBitmap (0),
    m_hCursor(0)
{
  // Load the bitmap
  IRasterPicturePtr ipRastPict(CLSID_BasicRasterPicture);
  IPicturePtr ipPict;
  HRESULT hr = ipRastPict->LoadPicture(CComBSTR(L"maptip.bmp"), &ipPict);
  if (SUCCEEDED(hr))
  {
    OLE_HANDLE hBitmap;
    hr = ipPict->get_Handle(&hBitmap);
    if (SUCCEEDED(hr))
      m_hBitmap = hBitmap;
  }

  // Load the cursor
  ISystemMouseCursorPtr ipSysMouseCur(CLSID_SystemMouseCursor);
  ipSysMouseCur->LoadFromFile(CComBSTR(L"maptip.cur"));
  OLE_HANDLE hTmp;
  hr = ipSysMouseCur->get_Cursor(&hTmp);
  if (SUCCEEDED(hr))
    m_hCursor = hTmp;
}

HRESULT MapTipTool::get_Enabled(VARIANT_BOOL * Enabled)
{
  if (Enabled == NULL)
    return E_POINTER;

  // Enable the tool always    
  *Enabled = VARIANT_TRUE;   

  return S_OK;
}

HRESULT MapTipTool::get_Name(BSTR * Name)
{
  if (Name == NULL)
    return E_POINTER;
    
  *Name = ::AoAllocBSTR(L"MapTip Tool");
  return S_OK;
}

HRESULT MapTipTool::get_Caption(BSTR * Caption)
{
  if (Caption == NULL)
    return E_POINTER;
    
  *Caption = ::AoAllocBSTR(L"MapTip Tool");
  return S_OK;
}

HRESULT MapTipTool::get_Tooltip(BSTR * Tooltip)
{
  if (Tooltip == NULL)
    return E_POINTER;
    
  *Tooltip = ::AoAllocBSTR(L"Show Maptips");
  return S_OK;
}

HRESULT MapTipTool::get_Message(BSTR * Message)
{
  if (Message == NULL)
    return E_POINTER;
    
  *Message = ::AoAllocBSTR(L"Display map tips in a text widget");
  return S_OK;
}

HRESULT MapTipTool::get_Bitmap(OLE_HANDLE * bitmapFile)
{
  if (bitmapFile == NULL)
    return E_POINTER;

  if (m_hBitmap != 0)
  {
    *bitmapFile = m_hBitmap;
    return S_OK;
  }

  return E_NOTIMPL;
}

HRESULT MapTipTool::get_Category(BSTR * categoryName)
{
  if (categoryName == NULL)
    return E_POINTER;
    
  *categoryName = ::AoAllocBSTR(L"Motif Samples");
  return S_OK;
}

HRESULT MapTipTool::OnCreate(IDispatch * hook)
{
  if (!hook)
    return E_POINTER;

  // An IToolbarControl * is passed in as the hook
  m_ipToolbarControl = hook;

  // Set the reference for the map control by getting the toolbar's buddy
  IDispatchPtr ipDispatch;
  m_ipToolbarControl->get_Buddy(&ipDispatch);
  m_ipMapControl = ipDispatch;

  // Open the cursor
  ISystemMouseCursorPtr ipSysMouseCur(CLSID_SystemMouseCursor);
  ipSysMouseCur->LoadFromFile(CComBSTR(L"./res/maptip.cur"));
  OLE_HANDLE hTmp;
  HRESULT hr = ipSysMouseCur->get_Cursor(&hTmp);
  if (SUCCEEDED(hr)) m_hCursor = hTmp;
  
  return S_OK;
}

HRESULT MapTipTool::get_Checked(VARIANT_BOOL * Checked)
{
  return E_NOTIMPL;
}
HRESULT MapTipTool::OnClick()
{
  return E_NOTIMPL;
}

// ITool
HRESULT MapTipTool::get_Cursor(OLE_HANDLE * Cursor)
{
  if (Cursor == NULL)
    return E_POINTER;

  if (m_hCursor != 0)
  {
    *Cursor = m_hCursor;
    return S_OK;
  }
    
  return E_NOTIMPL;
}

HRESULT MapTipTool::OnMouseMove(LONG Button, LONG Shift, LONG X, LONG Y)
{
  USES_CONVERSION;
  
  if (m_layerIndex != -1 && m_fieldIsSet)
  {
    // Convert X and Y to map coordinates
    m_ipMapControl->ToMapPoint(X, Y, &m_ipPoint);
    double mapX, mapY;
    m_ipPoint->get_X(&mapX);
    m_ipPoint->get_Y(&mapY);

    // Get the width of the map's extent (to use in tolerance calculation)
    IEnvelopePtr ipEnv;
    m_ipMapControl->get_Extent(&ipEnv);
    double width;
    ipEnv->get_Width(&width);
    double tolerance = width / 100.0;

    // Get the selected layer, make sure it is set to display tooltips and get the tip
    ILayerPtr ipLayer;
    m_ipMapControl->get_Layer(m_layerIndex, &ipLayer);
    ipLayer->put_ShowTips(VARIANT_TRUE);
    BSTR tipText;
    ipLayer->get_TipText(mapX, mapY, tolerance, &tipText);

    // Convert the BSTR to a char* and use the utility function to display the text
    if (tipText != NULL)
    {
      SetToolTipText(OLE2A(tipText));
      ::AoFreeBSTR(tipText); // remember to free the BSTR that was returned
    }
  }

  return S_OK;
}

// Allow the tool to be deactivated after setting the tip text to NULL
HRESULT MapTipTool::Deactivate(VARIANT_BOOL * complete)
{
  if (complete == NULL)
    return E_POINTER;

  SetToolTipText(NULL);
  *complete = VARIANT_TRUE;
  
  return S_OK;
}

HRESULT MapTipTool::OnMouseDown(LONG Button, LONG Shift, LONG X, LONG Y)
{
  return E_NOTIMPL;
}
HRESULT MapTipTool::OnMouseUp(LONG Button, LONG Shift, LONG X, LONG Y)
{
  return E_NOTIMPL;
}
HRESULT MapTipTool::OnDblClick()
{
  return E_NOTIMPL;
}
HRESULT MapTipTool::OnKeyDown(LONG keyCode, LONG Shift)
{
  return E_NOTIMPL;
}
HRESULT MapTipTool::OnKeyUp(LONG keyCode, LONG Shift)
{
  return E_NOTIMPL;
}
HRESULT MapTipTool::OnContextMenu(LONG X, LONG Y, VARIANT_BOOL * handled)
{
  if (handled == NULL)
    return E_POINTER;
    
  return E_NOTIMPL;
}
HRESULT MapTipTool::Refresh(OLE_HANDLE hDC)
{
  return E_NOTIMPL;
}

// Utility
// 
// Sets the text of the tooltip widget (called by MapTipTool)
void MapTipTool::SetToolTipText(char *inText)
{
  XmTextSetString(m_tooltipwidget, inText);
}