AddFeatureLayer.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. // // AddFeatureLayer.cpp // // This sample shows how to programmatically add and delete layers // from a MapControl #include "AddFeatureLayer.h" // Global variables // // Motif Widget g_topLevel; // application Widget g_mainWindow; // main program window Widget g_mainForm; // main prog window's form Widget g_mapWidget; // map control Widget g_tocWidget; // TOC control Widget g_toolbarWidget; // toolbar control Widget g_addLayerWidget; Widget g_removeLayerWidget; Widget g_fileSelectionDialog; Widget g_selectionDialog; XtAppContext g_appContext; Atom g_wmDeleteWindow; int main(int argc, char* argv[]) { // Interfaces for the controls IMapControl3Ptr ipMapControl; IToolbarControlPtr ipToolbarControl; ITOCControlPtr ipTOCControl; // Initialize the engine ::AoInitialize(NULL); { IAoInitializePtr ipAOinit(CLSID_AoInitialize); esriLicenseStatus status; ipAOinit->Initialize(esriLicenseProductCodeEngine, &status); if (status != esriLicenseCheckedOut) { std::cerr << "License not available for Engine\n"; std::cerr << "status is " << status << std::endl; ipAOinit->Shutdown(); ipAOinit = 0; ::AoUninitialize(); AoExit(0); } } // Initialize the Motif toolkit and create the parent widget XtSetLanguageProc(NULL, NULL, NULL); g_topLevel = XtVaAppInitialize( &g_appContext, "XApplication", NULL, 0, &argc, argv, NULL, NULL); XtVaSetValues( g_topLevel, XmNtitle, "Add Feature Layer Motif Example", NULL); XtResizeWidget(g_topLevel, 999, 800, 1); // Create g_mainWindow g_mainWindow = XtVaCreateWidget( "g_mainMindow", xmMainWindowWidgetClass, g_topLevel, NULL); // Create g_mainForm - it will fill g_mainWindow g_mainForm = XtVaCreateWidget( "g_mainForm", xmFormWidgetClass, g_mainWindow, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, g_mainWindow, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, g_mainWindow, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, g_mainWindow, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, g_mainWindow, XmNfractionBase, 100, NULL); //Create add button XmString label; label = XmStringCreateLocalized(const_cast<char*>("Add Feature Layer")); g_addLayerWidget = XtVaCreateWidget( "g_addLayerWidget", xmPushButtonWidgetClass, g_mainForm, XmNlabelString, label, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNheight, 40, XmNwidth, 200, NULL); XmStringFree(label); //Create remove button label = XmStringCreateLocalized(const_cast<char*>("Remove Feature Layer")); g_removeLayerWidget = XtVaCreateWidget( "g_removeLayerWidget", xmPushButtonWidgetClass, g_mainForm, XmNlabelString, label, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, g_addLayerWidget, XmNheight, 40, XmNwidth, 200, NULL); XmStringFree(label); // Create a FileSelectionDialog with a *.lyr mask XmString mask, title; Arg args[2]; mask = XmStringCreateLocalized(const_cast<char*>("*.lyr")); title = XmStringCreateLocalized(const_cast<char*>("Select Layer")); XtSetArg(args[0], XmNdirMask, mask); XtSetArg(args[1], XmNdialogTitle, title); g_fileSelectionDialog = XmCreateFileSelectionDialog(g_mainForm, const_cast<char*>("Select"), args, 2); XmStringFree(mask); XmStringFree(title); // Remove the Help button Widget remove1 = XmFileSelectionBoxGetChild(g_fileSelectionDialog, XmDIALOG_HELP_BUTTON); XtUnmanageChild(remove1); // Create a selection dialog (used when removing layers) label = XmStringCreateLocalized(const_cast<char*>("Layers")); title = XmStringCreateLocalized(const_cast<char*>("Select Layer")); g_selectionDialog = XmCreateSelectionDialog(g_mainForm, const_cast<char*>("selection"), NULL, 0); XtVaSetValues( g_selectionDialog, XmNlistLabelString, label, XmNdialogTitle, title, XmNmustMatch, True, NULL); XmStringFree(label); XmStringFree(title); // Remove the Help and Apply buttons remove1 = XmSelectionBoxGetChild(g_selectionDialog, XmDIALOG_HELP_BUTTON); XtUnmanageChild(remove1); remove1 = XmSelectionBoxGetChild(g_selectionDialog, XmDIALOG_APPLY_BUTTON); XtUnmanageChild(remove1); // Set up callbacks which don't need widgets created XtAddCallback(g_addLayerWidget, XmNactivateCallback, processClickAdd, NULL); // Toolbar Control setup g_toolbarWidget = XtVaCreateWidget( "g_toolbarWidget", mwCtlWidgetClass, g_mainForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, g_addLayerWidget, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, MwNprogID, AoPROGID_ToolbarControl, NULL); XtVaSetValues(g_toolbarWidget, XmNheight, 25, NULL); MwCtlGetInterface(g_toolbarWidget, (IUnknown**)&ipToolbarControl); // TOC Control setup g_tocWidget = XtVaCreateWidget( "g_tocWidget", mwCtlWidgetClass, g_mainForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, g_toolbarWidget, XmNleftAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, MwNprogID, AoPROGID_TOCControl, NULL); XtVaSetValues(g_tocWidget, XmNwidth, 200, NULL); MwCtlGetInterface(g_tocWidget, (IUnknown**)&ipTOCControl); // Map Control setup g_mapWidget = XtVaCreateWidget( "g_mapWidget", mwCtlWidgetClass, g_mainForm, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, g_toolbarWidget, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, g_tocWidget, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, MwNprogID, AoPROGID_MapControl, NULL); MwCtlGetInterface(g_mapWidget, (IUnknown**)&ipMapControl); // Set up callbacks that need the widget to have been created XtAddCallback(g_removeLayerWidget, XmNactivateCallback, processClickRemove, (XtPointer) g_mapWidget); XtAddCallback(g_fileSelectionDialog, XmNokCallback, processFileSelect, (XtPointer) g_mapWidget); XtAddCallback(g_fileSelectionDialog, XmNcancelCallback, processFileSelect, (XtPointer) g_mapWidget); XtAddCallback(g_selectionDialog, XmNokCallback, processSelect, (XtPointer) g_mapWidget); XtAddCallback(g_selectionDialog, XmNcancelCallback, processSelect, (XtPointer ) g_mapWidget); // Manage the non-parent widgets XtManageChild(g_mainWindow); XtManageChild(g_mainForm); XtManageChild(g_addLayerWidget); XtManageChild(g_removeLayerWidget); XtManageChild(g_toolbarWidget); XtManageChild(g_tocWidget); XtManageChild(g_mapWidget); // Buddy the toolbar and TOC with the map ipToolbarControl->SetBuddyControl(ipMapControl); ipTOCControl->SetBuddyControl(ipMapControl); // Add tools to toolbar ::AddStandardToolbarItems(ipToolbarControl); // Structure used to pass data to callback routines CloseFormClientDataStruct cfcds; cfcds.pMapControl = ipMapControl; cfcds.pToolbarControl = ipToolbarControl; cfcds.pTOCControl = ipTOCControl; // Handle the window manager message that the window is about to be closed g_wmDeleteWindow = XmInternAtom(XtDisplay(g_topLevel), "WM_DELETE_WINDOW", FALSE); XmAddWMProtocolCallback(g_topLevel, g_wmDeleteWindow, processClickCloseForm, &cfcds); // Realize the container widget XtRealizeWidget(g_topLevel); XtResizeWidget(g_topLevel, 1000, 800, 1); // Turn application control over to the X Toolkit Intrinsics MwCtlAppMainLoop(g_appContext); } // Function called when WM_DELETE_WINDOW is received (i.e. when the // user closes the window) void processClickCloseForm(Widget w, XtPointer client_data, XtPointer call_data) { // To be on the safe side we will make sure the controls are // destroyed before uninitializing CloseFormClientDataStruct *cfcds = (CloseFormClientDataStruct *) client_data; IMapControl3Ptr ipMapControl (cfcds->pMapControl); ipMapControl = 0; IToolbarControlPtr ipToolbarControl (cfcds->pToolbarControl); ipToolbarControl = 0; ITOCControlPtr ipTOCControl (cfcds->pTOCControl); ipTOCControl = 0; // Uninitialize the engine { IAoInitializePtr ipAOinit(CLSID_AoInitialize); ipAOinit->Shutdown(); } ::AoUninitialize(); AoExit(0); } // Open a FileSelectionDialog window to allow the user to select a // .lyr file to add to the map control and TOC. The // FileSelectionDialog has already been created, so all we need to do // here is show it. void processClickAdd(Widget w, XtPointer client_data, XtPointer call_data) { XtManageChild(g_fileSelectionDialog); } // Show a SelectionDialog with the names of all layers currently in // the map. The SelectionDialog has already been created, so all we // need to do here is update the items in its internal list and show // it. This method also shows how to use the ::AoFreeBSTR() SDK call // and to this end bsLayerName is declared as a BSTR. Normally // bsLayerName would be declared as a CComBSTR (so that it's memory // managment would occur automatically). See the function // GetIndexOfLayerName for an example of using a CComBSTR. void processClickRemove(Widget w, XtPointer client_data, XtPointer call_data) { USES_CONVERSION; IMapControl3Ptr ipMapControl; MwCtlGetInterface((Widget)client_data, (IUnknown**)&ipMapControl); BSTR bsLayerName; // Ordinarily would be a CComBSTR ILayerPtr ipLayer; long numLayers; XmString *str; ipMapControl->get_LayerCount(&numLayers); str = (XmString *) XtMalloc(numLayers * sizeof(XmString)); // Add the map's layer names to a list for (long i=0; i<numLayers; i++) { ipMapControl->get_Layer(i, &ipLayer); ipLayer->get_Name(&bsLayerName); ::AoFreeBSTR(bsLayerName); // remember to free the BSTR that was returned str[i] = XmStringCreateLocalized(OLE2A(bsLayerName)); } // Set the list of the SelectionDialog XtVaSetValues(g_selectionDialog, XmNlistItems, str, XmNlistItemCount, static_cast<int>(numLayers), NULL); // Clean up for (long i=0; i<numLayers; i++) XmStringFree(str[i]); XtFree((char *)str); XtManageChild(g_selectionDialog); } // Removes the layer with the name selected in the selectiondialog // from the map void processSelect(Widget w, XtPointer client_data, XtPointer call_data) { IMapControl3Ptr ipMapControl; MwCtlGetInterface((Widget)client_data, (IUnknown**)&ipMapControl); XmSelectionBoxCallbackStruct *cbs = (XmSelectionBoxCallbackStruct *)call_data; // Kill the dialog if they canceled if (cbs->reason == XmCR_CANCEL) { XtUnmanageChild(g_selectionDialog); return; } // Get the layer name and check for errors char *layerName = 0; if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &layerName)) { XtUnmanageChild(g_selectionDialog); return; } long index = ::GetIndexOfLayerName(ipMapControl, layerName); if (index != -1) ipMapControl->DeleteLayer(index); XtFree (layerName); XtUnmanageChild(g_selectionDialog); } // Add the .lyr file that the user selected to the map control and TOC void processFileSelect(Widget w, XtPointer client_data, XtPointer call_data) { IMapControl3Ptr ipMapControl; MwCtlGetInterface((Widget)client_data, (IUnknown**)&ipMapControl); XmFileSelectionBoxCallbackStruct *cbs; cbs = (XmFileSelectionBoxCallbackStruct *)call_data; // Kill the dialog if they canceled if (cbs->reason == XmCR_CANCEL) { XtUnmanageChild(g_fileSelectionDialog); return; } // Get the file name and check for errors char *fileName = 0; if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName)) { XtUnmanageChild(g_fileSelectionDialog); return; } if (*fileName) { // Try to add the layer to the map ipMapControl->AddLayerFromFile(CComBSTR(fileName), 0); // Hide file selection dialog XtUnmanageChild(g_fileSelectionDialog); } XtFree (fileName); return; }