Share CommandPool
ShareCommandPool.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 "ShareCommandPool.h"

// Motif Widgets 
Widget g_usage1;
Widget g_usage2;

// Control
IMapControl3Ptr g_ipMapControl;
IToolbarControlPtr g_ipToolbar1Control;
IToolbarControlPtr g_ipToolbar2Control;

// The command pools
ICommandPoolPtr g_ipCommandPool1;
ICommandPoolPtr g_ipCommandPool2;

int main(int argc, char* argv[])
{
  LicenseApp();

  XtAppContext app_context;
  FormSetup(argc, argv, &app_context);

  // Set the initial command pools without sharing
  g_ipToolbar1Control->get_CommandPool(&g_ipCommandPool1);
  g_ipToolbar2Control->get_CommandPool(&g_ipCommandPool2);

  AddToolbarItems();

  MwCtlAppMainLoop(app_context);
}

void ToggleCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
  XmToggleButtonCallbackStruct *share = 
    (XmToggleButtonCallbackStruct *) call_data;
  
  if (share->set)
  {
    // Share the same command pool between both ToolbarControls
    g_ipToolbar2Control->putref_CommandPool(g_ipCommandPool1);
  }  
  else
  {
    // Do not share the same command pool between both ToolbarControls
    g_ipToolbar2Control->putref_CommandPool(g_ipCommandPool2);
  }

  UpdateUsageCount();
}

void UpdateUsageCount()
{
  USES_CONVERSION;

  // Clear the list boxes
  XmListDeleteAllItems(g_usage1);
  XmListDeleteAllItems(g_usage2);

  // Populate the list box for toolbar1
  XmString item = XmStringCreateLocalized("UsageCount    Name");
  XmListAddItem(g_usage1, item, 1);
  XmStringFree(item);
  long lCommandPoolCount;
  g_ipCommandPool1->get_Count(&lCommandPoolCount);
  ICommandPtr ipCommand;
  long lUsageCount;
  char cUsageCount[64];
  CComBSTR bsCommandName;
  std::string display;
  for (int i = 0; i < lCommandPoolCount; ++i)
  {
    g_ipCommandPool1->get_Command(i, &ipCommand);
    g_ipCommandPool1->get_UsageCount(ipCommand, &lUsageCount);
    ipCommand->get_Name(&bsCommandName);
    snprintf(cUsageCount, 64, "%ld    ", lUsageCount);
    display = std::string(cUsageCount) + OLE2A(bsCommandName);
    item = XmStringCreateLocalized((char*) display.c_str());
    XmListAddItem(g_usage1, item, i+2);
    XmStringFree(item);
  }
  
  // Populate the list box for toolbar2
  item = XmStringCreateLocalized("UsageCount    Name");
  XmListAddItem(g_usage2, item, 1);
  XmStringFree(item);
  g_ipCommandPool2->get_Count(&lCommandPoolCount);
  for (int i = 0; i < lCommandPoolCount; ++i)
  {
    g_ipCommandPool2->get_Command(i, &ipCommand);
    g_ipCommandPool2->get_UsageCount(ipCommand, &lUsageCount);
    ipCommand->get_Name(&bsCommandName);
    snprintf(cUsageCount, 64, "%ld    ", lUsageCount);
    display = std::string(cUsageCount) + OLE2A(bsCommandName);
    item = XmStringCreateLocalized((char*) display.c_str());
    XmListAddItem(g_usage2, item, i+2);
    XmStringFree(item);
  }
}

HRESULT AddToolbarItems()
{
  long itemIndex;
  CComVariant varTool;
  
  // 1st toolbar
  varTool = L"esriControlCommands.ControlsOpenDocCommand";
  g_ipToolbar1Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconOnly, &itemIndex);
  varTool = L"esriControlCommands.ControlsMapZoomInTool";
  g_ipToolbar1Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconAndText, &itemIndex);
  varTool = L"esriControlCommands.ControlsMapZoomOutTool";
  g_ipToolbar1Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconAndText, &itemIndex);  
  varTool = L"esriControlCommands.ControlsMapPanTool";
  g_ipToolbar1Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconAndText, &itemIndex);
  
  // 2nd toolbar
  varTool = L"esriControlCommands.ControlsMapFullExtentCommand";
  g_ipToolbar2Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconOnly, &itemIndex);
  varTool = L"esriControlCommands.ControlsMapZoomInTool";
  g_ipToolbar2Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconAndText, &itemIndex);  
  varTool = L"esriControlCommands.ControlsMapZoomOutTool";
  g_ipToolbar2Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconAndText, &itemIndex);  
  varTool = L"esriControlCommands.ControlsMapPanTool";
  g_ipToolbar2Control->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, 
                               esriCommandStyleIconAndText, &itemIndex);

  UpdateUsageCount();

  return S_OK;
}

void LicenseApp()
{
  // Initialize the Engine
  ::AoInitialize(NULL);
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    esriLicenseStatus status;
    ipInit->Initialize(esriLicenseProductCodeEngine, &status);
    if (status != esriLicenseCheckedOut)
    {
      std::cerr << "Invalid Licensing." << std::endl;
      AoExit(0);  
    }
  }
}

void FormSetup(int argc, char* argv[], XtAppContext* app_context)
{
  XtSetLanguageProc(NULL, NULL, NULL);
  
  // Initialize the Motif toolkit and create the parent widget
  Widget topLevel = XtVaAppInitialize(app_context, "XApplication", 
                                 NULL, 0, &argc, argv, NULL, NULL);
  XtVaSetValues(topLevel, 
                XmNtitle, "Share Command Pool",
                NULL);
  
  // Set the application size by resizing the created widget
  XtResizeWidget(topLevel, 600, 450, 1);
  
  Widget mainWindow = XtVaCreateWidget("mainWindow", 
                                  xmMainWindowWidgetClass, topLevel,
                                  NULL);
  
  Widget mainForm = XtVaCreateWidget("mainForm",
                                     xmFormWidgetClass,    mainWindow,
                                     XmNtopAttachment,     XmATTACH_WIDGET,
                                     XmNtopWidget,         mainWindow,
                                     XmNbottomAttachment,  XmATTACH_WIDGET,
                                     XmNbottomWidget,      mainWindow,
                                     XmNleftAttachment,    XmATTACH_WIDGET,
                                     XmNleftWidget,        mainWindow,
                                     XmNrightAttachment,   XmATTACH_WIDGET,
                                     XmNrightWidget,       mainWindow,
                                     XmNfractionBase,      100,
                                     NULL);

  // Create and place subform for command pool info display
  Widget bottomPanel = XtVaCreateWidget("bottomPanel",
                                        xmFormWidgetClass,   mainForm,
                                        XmNrightAttachment,  XmATTACH_FORM,
                                        XmNbottomAttachment, XmATTACH_FORM,
                                        XmNleftAttachment,   XmATTACH_FORM,
                                        XmNheight,           150,
                                        XmNfractionBase,     2,
                                        NULL);  

  // Create and place subform for controls, directions, and toggle.
  Widget topPanel =  XtVaCreateWidget("bottomPanel",
                                      xmFormWidgetClass,   mainForm,
                                      XmNrightAttachment,  XmATTACH_FORM,
                                      XmNbottomAttachment, XmATTACH_WIDGET,
                                      XmNbottomWidget,     bottomPanel,
                                      XmNleftAttachment,   XmATTACH_FORM,
                                      XmNtopAttachment,    XmATTACH_FORM,
                                      NULL);  

  // Create and place subform for Customize toggle and directions
  Widget rightPanel = XtVaCreateWidget("rightPanel",
                                       xmFormWidgetClass,   topPanel,
                                       XmNtopAttachment,    XmATTACH_FORM,
                                       XmNbottomAttachment, XmATTACH_FORM,
                                       XmNrightAttachment,  XmATTACH_FORM,
                                       XmNwidth,            250,
                                       XmNtopOffset,        20,
                                       NULL);
  
  // Create and place the Toolbar1Control
  Widget toolbar1Widget = XtVaCreateWidget("toolbar1Widget",
                                           mwCtlWidgetClass,   topPanel,
                                           XmNtopAttachment,   XmATTACH_FORM,
                                           XmNleftAttachment,  XmATTACH_FORM,
                                           XmNrightAttachment, XmATTACH_WIDGET,
                                           XmNrightWidget,     rightPanel,
                                           XmNtopOffset,       5,
                                           XmNleftOffset,      5,
                                           MwNprogID,          AoPROGID_ToolbarControl,
                                     NULL);
  XtVaSetValues(toolbar1Widget, XmNheight, 25, NULL);
  MwCtlGetInterface(toolbar1Widget, (IUnknown**)&g_ipToolbar1Control);
  
  // Create and place the Toolbar2Control
  Widget toolbar2Widget = XtVaCreateWidget("toolbar2Widget",
                                           mwCtlWidgetClass,   topPanel,
                                           XmNtopAttachment,   XmATTACH_WIDGET,
                                           XmNtopWidget,       toolbar1Widget,
                                           XmNleftAttachment,  XmATTACH_FORM,
                                           XmNrightAttachment, XmATTACH_WIDGET,
                                           XmNrightWidget,     rightPanel,
                                           XmNtopOffset,       5,
                                           XmNleftOffset,      5,
                                           MwNprogID,          AoPROGID_ToolbarControl,
                                           NULL);
  XtVaSetValues(toolbar2Widget, XmNheight, 25, NULL);
  MwCtlGetInterface(toolbar2Widget, (IUnknown**)&g_ipToolbar2Control);

  // Create and place MapControl
  Widget mapWidget = XtVaCreateWidget("mapWidget",
                                      mwCtlWidgetClass,    topPanel,
                                      XmNtopAttachment,    XmATTACH_WIDGET,
                                      XmNtopWidget,        toolbar2Widget,
                                      XmNbottomAttachment, XmATTACH_FORM,
                                      XmNleftAttachment,   XmATTACH_FORM,
                                      XmNrightAttachment,  XmATTACH_WIDGET,
                                      XmNrightWidget,      rightPanel,
                                      XmNtopOffset,        5,
                                      XmNleftOffset,       5,
                                      MwNprogID,           AoPROGID_MapControl,
                                      NULL);
  MwCtlGetInterface(mapWidget, (IUnknown**)&g_ipMapControl);
  
  // Create and place customize toggle
  XmString label = XmStringCreateLocalized("Share CommandPool");
  Widget shareToggle = XtVaCreateWidget("shareToggle",
                                        xmToggleButtonWidgetClass,   rightPanel,
                                        XmNlabelString,      label,
                                        XmNtopAttachment,    XmATTACH_FORM,
                                        XmNrightAttachment,  XmATTACH_FORM,
                                        XmNleftAttachment,   XmATTACH_FORM, 
                                        XmNheight,           25,
                                        XmNleftOffset,       25,
                                        XmNrightOffset,      75,
                                        NULL);
  XtAddCallback(shareToggle, XmNvalueChangedCallback, ToggleCallback, 
                NULL);
  XmStringFree(label);
  
  // Create and place howto label
  label = XmStringCreateLocalized("1) Browse to a map document to load \n   into the MapControl. \n \n2) Select a ZoomIn, ZoomOut or Pan \n   tool. Notice that only one tool is \n   depressed. \n\n3) Share the same CommandPool \n   between both ToolbarControls. \n   Notice that the UsageCount changes. \n\n4) Select a ZoomIn, ZoomOut or Pan \n   tool. Notice that the same tool on \n   both ToolbarControls becomes \n   depressed."); 
  Widget howToLabel = XtVaCreateWidget("howToLabel",
                                       xmLabelWidgetClass,    rightPanel,
                                       XmNlabelString,        label,
                                       XmNalignment,          XmALIGNMENT_BEGINNING,
                                       XmNleftAttachment,     XmATTACH_FORM,
                                       XmNrightAttachment,    XmATTACH_FORM,
                                       XmNtopAttachment,      XmATTACH_WIDGET,
                                       XmNtopWidget,          shareToggle,
                                       XmNleftOffset,         15,
                                       XmNtopOffset,          15,
                                       NULL);
  XmStringFree(label);

  // Create and place usage count labels
  label = XmStringCreateLocalized("CommandPool1"); 
  Widget usage1Label = XtVaCreateManagedWidget("g_usage1Label",
                                               xmLabelWidgetClass,    bottomPanel,
                                               XmNlabelString,        label,
                                               XmNalignment,          XmALIGNMENT_BEGINNING,
                                               XmNleftAttachment,     XmATTACH_FORM,
                                               XmNrightAttachment,    XmATTACH_POSITION,
                                               XmNrightPosition,      1,
                                               XmNtopAttachment,      XmATTACH_FORM,
                                               XmNleftOffset,         5,
                                               XmNtopOffset,          5,
                                               NULL);
  XmStringFree(label);

  label = XmStringCreateLocalized("CommandPool2"); 
  Widget usage2Label = XtVaCreateManagedWidget("g_usage2Label",
                                               xmLabelWidgetClass,    bottomPanel,
                                               XmNlabelString,        label,
                                               XmNalignment,          XmALIGNMENT_BEGINNING,
                                               XmNleftAttachment,     XmATTACH_POSITION,
                                               XmNleftPosition,       1,
                                               XmNrightAttachment,    XmATTACH_FORM,
                                               XmNrightPosition,      1,
                                               XmNtopAttachment,      XmATTACH_FORM,
                                               XmNleftOffset,         5,
                                               XmNtopOffset,          5,
                                               NULL);
  XmStringFree(label);
  
  // Create and place list for usage1 display
  g_usage1 = XtVaCreateManagedWidget("usage1",
                                     xmListWidgetClass,     bottomPanel,
                                     XmNleftAttachment,     XmATTACH_FORM,
                                     XmNrightAttachment,    XmATTACH_POSITION,
                                     XmNrightPosition,      1,
                                     XmNtopAttachment,      XmATTACH_WIDGET,
                                     XmNtopWidget,          usage1Label,
                                     XmNleftOffset,         5,
                                     XmNtopOffset,          5, 
                                     XmNvisibleItemCount,   7,
                                     NULL);

  // Create and place list for usage2 display
  g_usage2 = XtVaCreateManagedWidget("usage1",
                                     xmListWidgetClass,     bottomPanel,
                                     XmNleftAttachment,     XmATTACH_POSITION,
                                     XmNleftPosition,       1,
                                     XmNrightAttachment,    XmATTACH_FORM,
                                     XmNtopAttachment,      XmATTACH_WIDGET,
                                     XmNtopWidget,          usage2Label,
                                     XmNleftOffset,         5,
                                     XmNtopOffset,          5,  
                                     XmNvisibleItemCount,   7,
                                     NULL);

  // Manage the non-parent widgets
  XtManageChild(mainWindow);
  XtManageChild(mainForm);
  XtManageChild(bottomPanel);
  XtManageChild(topPanel);
  XtManageChild(toolbar1Widget);
  XtManageChild(toolbar2Widget);
  XtManageChild(rightPanel);
  XtManageChild(mapWidget);
  XtManageChild(shareToggle);
  XtManageChild(howToLabel);
  
  g_ipToolbar1Control->SetBuddyControl(g_ipMapControl);
  g_ipToolbar2Control->SetBuddyControl(g_ipMapControl);

  // Handle the window manager message that the window is about to be closed 
  Atom wm_delete_window = XmInternAtom(XtDisplay(topLevel), 
                                       "WM_DELETE_WINDOW", 
                                       FALSE);
  XmAddWMProtocolCallback(topLevel, wm_delete_window, 
                          CloseAppCallback, NULL);
  
  // Start the application running 
  XtRealizeWidget(topLevel);
}

void CloseAppCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
  g_ipMapControl = 0;
  g_ipToolbar1Control = 0;

  // Uninitialize the engine
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    ipInit->Shutdown();
  }
  ::AoUninitialize();
  
  AoExit(0);
}