Click or drag to resize

Global Mapper Extensions

The Global Mapper SDK allows you to add your own functionality directly to Global Mapper by creating an extension DLL. Global Mapper takes care of loading and displaying the data. The extension only needs to implement the custom functionality. Global Mapper extensions can perform all of the functions listed above for applications, in addition to the following:

  • Add a toolbar used to invoke the custom functionality to the Global Mapper user interface.
  • Add menu items to the Digitizer context menu.
  • Access the layers and features that are currently open in Global Mapper.
  • Access a list of the features that are currently selected in the Global Mapper view.
  • Request that Global Mapper refresh the view.
Global Mapper Extension Developers Guide

Creating a Global Mapper extension requires the following tasks:

Extension DLL Requirements

Global Mapper Extension DLLs have the following requirements:

  • The DLL must have a file extension of ".gmx" instead of ".dll".
  • The DLL must implement a proxy class. The proxy class provides the "plug-in" interface for an extension DLL, and is derived from GM_ExtensionProxy.
  • The DLL must implement an extension class. The extension class performs the custom functionality, and must be derived from GM_Extension.
  • The extension DLL must have a single exported function:
    GM_ExtensionProxy* GetExtensionProxy(void)

Once you have installed the SDK, you will find two extension samples. The folder sample_tb_extension contains an extension that is primarily intended to illustrate the basics of how to implement an extension that uses both a toolbar and menus. Folder sample_tb_extension_mfc has a sample that illustrates more of the functionality such as:

  1. loading layers
  2. accessing layers that are already loaded
  3. adding menu items to the Digitizer menu
  4. working with selected features
  5. handling stock Global Mapper events
  6. etc.

The Proxy Class

The proxy class, GM_ExtensionProxy, provides the "plug-in" interface for an extension DLL. The proxy class is an abstract class, so a developer will have to create a proxy class that is derived from GM_ExtensionProxy. The extension DLL will have an entry point, called GetExtensionProxy, that returns a pointer to the proxy object.

struct GM_ExtensionProxy
{
        virtual const char* GetName(void) = 0;
        virtual const char* GetLicenseString(void) = 0;
        virtual GM_Extension* CreateExtension(void) = 0;
        virtual void Release() = 0;
};

The GM_ExtensionProxy class contains the following pure virtual methods that must be overridden when implementing a Global Mapper Extension:

  • The GetName method returns a name that identifies the extension. This name will identify the extension in cases where the extension cannot be loaded or licensed for some reason.
  • The GetLicenseString function returns the SDK license string required for the extension. This license string verifies that the DLL is a valid extension. Global Mapper will validate the returned license string when it attempts to load the extension. If the license string is not valid, the extension will not be loaded. If an extension requires a user license of some sort, then it is up to the developer to implement functionality to validate the existance of that license.
  • The CreateExtension method allocates an instance of the extension class and returns a pointer to it. When the user clicks a button on the extension's toolbar, Global Mapper will call methods on this class to perform the requested function. Global Mapper will take ownership of this pointer, and delete it when it is no longer needed.
  • The Release method frees the proxy object.

The Extension Class

The extension class, GM_Extension, performs the work of the extension. GM_Extension is an abstract class, so developers will have to use a class derived from GM_Extension to implement their extension functionality. The GM_ExtensionProxy::CreateExtension() function returns an instance of this class.

struct GM_Extension
{
        virtual const char* GetDisplayName(void) const = 0;
        virtual const char* GetDescription(void) const = 0;
        virtual const char* GetButtonTooltipText(UINT aButtonIndex) const = 0;
        virtual void HandleCustomEvent(UINT aEventID, HWND aParentWindow) = 0;
        virtual void HandleGMEvent(GM_Event_t aEvent, void* aEventData,        HWND aParentWindow) = 0;
        virtual GM_ExtensionToolbarDef_t* GetToolbarDefinition() const = 0;
        virtual GM_ExtensionMenuDef_t* GetMenuDefinition(const GM_ExtensionMenuCriteria_t& aCriteria) const = 0;
        virtual void Release() = 0;
}

The GM_Extension class contains the following pure virtual methods that must be overridden when implementing a Global Mapper Extension:

  • The GetDisplayName method returns the name that will be included in the Extension Manager's list of registered extensions.
  • The GetDescription method returns text that will be displayed on the Extension Properties dialog. This is a good place to include version and copyright information.
  • The GetToolbarDefinition returns an object derived from GM_ExtensionToolbarDef_t that defines the extension toolbar.
  • The GetMenuDefinition method returns an object derived from GM_ExtensionMenuDef_t that defines menu items to be added to the Digitizer context menu. The aCriteria parameter provides information about what types of objects are currently selected in the Global Mapper user interface. This allows the extension to implement menu items that designed to operate in a specific context with respect to selected feature geometry (areas, lines, etc.) If the extension does not add menu items to the Digitizer menu, this method should return NULL.
  • The GetButtonTooltipText method returns the text that will be used as a tooltip for the specified button. The aButtonIndex parameter contains the index of the button for which the tooltip will be displayed. If you are not using tooltips, this method should return a NULL pointer.
  • The HandleCustomEvent method will be called when the user clicks one of the buttons on the extension's toolbar. The aEventID parameter contains the index of the button clicked by the user. The aParentWindow argument contains the handle of the main Global Mapper window, which can be used as the parent window for dialogs, etc.
  • The HandleGMEvent method handles stock events generated by Global Mapper, such as notification that a new layer has been loaded or that the global projection has been changed. The aEvent parameter identifies the event being raised. The GM_Event_t enumeration is defined in GlobalMapperTypes.h. The aEventData parameter contains related data associated with the event. The comments for the enumeration members indicate the what event data is included with each event type. There are a couple of special cases that developers should be aware of:
    • When the event data is described as a Feature*, it will be passed to an extension as a GM_FoundFeature_t*.
    • When the event data is described as a GeographicOverlay*, it will be passed to an extension as a GM_LayerHandle_t32.
    In cases where no data is provided, this value will be NULL. The aParentWindow argument contains the handle of the main Global Mapper window, which can be used as the parent window for dialogs, etc.
  • The Release method frees the extension object.

The Extension Toolbar Definition

The GM_ExtensionToolbarDef_t structure defines the toolbar associated with a Global Mapper extension DLL. GM_ExtensionToolbarDef_t is an abstract definition, so developers will need to derive a class from GM_ExtensionToolbarDef_t in order to provide their toolbar definition.

struct GM_ExtensionToolbarDef_t
{
        // Data Accessors
        virtual UINT GetBitmapID(void) const = 0;
        virtual int  GetNumButtons(void) const = 0;
        virtual UINT GetButtonCommandID(int aIndex) = 0;
        virtual BOOL UsesTooltips(void) const = 0;
        virtual const char* GetTitle(void) const = 0;
        virtual void Release() = 0;
};

The GM_ExtensionToolbarDef_t structure includes the following pure virtual methods that must be implemented in your derived class:

  • GetBitmapID returns the resource ID for the toolbar button bitmap. Global Mapper will attempt to read the toolbar bitmap from the extension DLL resources using this ID. If the toolbar bitmap is not found in the extension DLL, toolbar initialization will fail and an error message will be displayed. In Global Mapper v18.0.2 and earlier, toolbar buttons are assumed be 19 pixels wide by 19 pixels high. Staring with Global Mapper v18.0.3, the toolbar buttons can be any size, but are scaled to a size of 24 pixels wide by 24 pixels high to match the built-in Global Mapper toolbars. You can continue using 19x19 buttons and allow the scaling to update them to 24x24, but for a better look you should create 24x24 toolbar buttons. If you want your extensions to work on all versions, create 2 toolbar images, one 19 pixels high for older versions and another 24 pixels high for later, then use ( GM_GetSDKVersion() >= 1803 ) in your code to decide which bitmap resource to provide.
  • GetNumButtons returns the number of buttons in the toolbar.
  • GetButtonCommandID returns the extension command ID for the specified button. The aIndex argument indicates which button ID to return. This is the value that will be passed back to the extension via the HandleCustomEvent method when the user clicks a toolbar button.
  • UsesTooltips indicates whether or not tooltips should be displayed when the user holds the mouse over a toolbar button.
  • GetTitle returns the title text to be displayed on the toolbar when it is not docked.
  • The Release method frees the toolbar definition object.

The Extension Menu Definition

The GM_ExtensionMenuDef_t structure defines the menu items to be displayed in the Digitizer menu. GM_ExtensionMenuDef_t is an abstract definition, so developers will need to derive a class from GM_ExtensionMenuDef_t in order to provide the menu definition.

struct GM_ExtensionMenuDef_t
{
        // Data Accessors
        virtual GM_MenuType_t GetMenuType(void) const = 0;
        virtual UINT GetNumMenuItems(void) const = 0;
        virtual const char* GetMenuItemText(UINT aIndex) const = 0;
        virtual UINT GetCommandID(UINT aIndex) const = 0;
        virtual void Release() = 0;
};

The GM_ExtensionMenuDef_t structure includes the following pure virtual methods that must be implemented in your derived class:

  • GetMenuType returns an enumeration that specifies which Global Mapper menu the menu items will be added to. Currently, menu items can only be added to the Digitizer context menu.
  • GetNumMenuItems returns the number of menu items contained in the definition.
  • GetMenuItemText returns the text for the specified menu item. The aIndex parameter indicates which menu item to retrieve.
  • GetCommandID returns the extension command ID for the specified menu item. The aIndex argument indicates which menu item ID to return. This is the value that will be passed back to the extension via the HandleCustomEvent method when the user clicks the menu item.
  • The Release method frees the menu definition object.

Extension Toolbar Button/Menu Options State (Disabling and Checking)

By default all toolbar buttons and menu items and enabled and unchecked. If you would like to have your command items (buttons and menu options) be disabled/checked at some times, you can do this by handling the GM_Event_GetExtensionCommandState event which passes a GM_ExtCommandState_t* to the extension. You can then set the enabled/disabled and checked/unchecked state flags for the requested command ID based on the current options that are set. Note that marking a toolbar button as checked means it is depressed. This event will only be sent by Global Mapper v16.2.4 and later. Previous versions do not support disabling or checking toolbar buttons or menu options.

The Extension DLL Entry Point

A Global Mapper Extension DLL must have one entry point:

GM_ExtensionProxy* GetExtensionProxy(void);

When attempting to load an extension, Global Mapper will verify that the extension DLL contains this entry point. If it is not there, then the load operation will fail. The following code snippet illustrates one way to implement the GetExtensionProxy function:

// TestProxy.h contains the extension proxy definition.
#include "TestProxy.h"

TestProxy theProxy;
extern "C" TestProxy* g_pProxy = &theProxy;

// This the exported function that returns the proxy instance
extern "C" __declspec(dllexport) GM_ExtensionProxy* GetExtensionProxy(void)
{
        return g_pProxy;
}

TestProxy is a class derived from GM_ExtensionProxy. Note that in this example, the instance of TestProxy (theProxy) is a static variable. Because of this, the implementation of TestProxy::Release() is empty, since the static object cannot be deleted.

Registering the Extension DLL

Before the extension can be used, it must be registered with Global Mapper. This can be accomplished in two ways:

  1. Using the Extension Manager in the Global Mapper UI
  2. In a script (e.g., an installer script) by starting Global Mapper and passing it the name of the extension DLL along with -regex parameter.

Similarly, before an extension gets removed from the computer, it must be unregistered. This can be accomplished in two ways:

  1. Using the Extension Manager in the Global Mapper UI
  2. In an uninstall script by starting Global Mapper and passing it the name of the extension DLL along with -unregex parameter.