Extending ArcObjects  

DDE handler example

This topic is relevant for the following:
Product(s): ArcGIS Desktop: All
Version(s): 9.0, 9.1, 9.2
Language(s): VB6, VC++
Experience level(s): Intermediate to advanced



In this section:

  1. Why create a DDE command handler?
  2. Creating a DDE command handler
  3. Setting up a DDE conversation

DDE handler example

Example Code Click here

Design Coclass DDEHandler implements IDDECommandHandler.

License ArcView or above.

Libraries Carto, Framework, ArcMapUI.

Languages Visual Basic, Visual C++

Categories ESRI Mx DDE Command Handlers

Interfaces IDDECommandHandler

How to use

    1. Register the DDEHandlerVB.dll and run the DDEHandlerVB.reg registry script to register the class to the required component category.
    2. Open ArcMap and add a feature layer.
    3. Select a few features in the layer.
    4. Run the DDEVBClient.exe application and click the Send DDE Request button.

      ArcMap will now pop up a message box that informs you of the number of selected features in the map.


Why create a DDE command handler?

Within ArcMap there are numerous situations where you might want to receive communications from another non-ArcGIS application. Users wanting to communicate with the ArcView 3.x architecture in particular may have this requirement.

One method of communicating between an ArcGIS application and a second application is to make use of the AppROT coclass. AppROT can be used to access a list of all the currently running ESRI COM applications, including ArcMap, ArcCatalog, and ArcScene. A reference to AppROT can be embedded in the second application, allowing the second application to programmatically access the ESRI application.

The use of AppROT can be problematic, however, as AppROT is running out of process. It is inappropriate to share information about process-specific items, for example, window handles (generally known in code as hWnds). There may also be threading issues if attempting to hold a reference to and program against the same object from two different processes.

In cases where the use of AppROT is not feasible or appropriate, a useful alternative is a DDE command handler.

What is DDE?

Dynamic Data Exchange (DDE) is a relatively simplistic method of interapplication communication. DDE relies on a standard underlying windows protocol. Using this DDE protocol, it is possible to send messages and values between applications.

DDE is a protocol that can be used to communicate between applications. ArcView 3.x users in particular may be familiar with DDE.

Applications can use the DDE protocol for one-time data transfers, or for continuous exchanges in which applications send updates to one another when new data becomes available.

Typically, information travels from the DDE source to a destination. Some applications allow data to travel from the destination back to the source; however, ArcMap does not support the return of data.

DDE in ArcMap

ArcMap has an existing DDE command handler, GNetCommandHandler, which is used to intercept incoming DDE messages whenever a Geography Network file is opened from, for example, Windows Explorer.

The process of opening the file will start ArcMap, if it is not already running, then send a DDE string message to ArcMap, specifying the name of the file to be opened.

A custom DDE command handler can be used to execute commands in ArcMap in response to a request from another application.

You can also create your own DDE command handler, which can operate in parallel with existing handlers.

The DDE command handler mechanism

The mechanism for using DDE to communicate with ArcMap is twofold:

ArcMap can act as a DDE server, processing incoming DDE requests.

A DDE conversation may proceed as follows.

  1. DDE client starts a conversation with ArcMap by specifying an Application name (for example, ArcMap.exe) and a conversation type. For more information on conversation types, see 'Setting up a DDE conversation' later in this section.
  2. Client sends a string message to ArcMap.
  3. ArcMap receives the string message, then looks in the ESRI MX DDE Command Handlers component category to identify the registered DDE command handlers.
  4. An instance of the first registered handler is instantiated by ArcMap, and the handler's CanExecute method is called, passing in the incoming string message.
  5. The handler parses the string to check if it is able to use the information it contains. If the string can be used by the handler, it will return true as the result of the CanExecute function.
  6. Upon receiving a true value from a handler's CanExecute method, ArcMap will call Execute for that handler, again passing in the same message string.

  7. Steps 4 and 5 are repeated until a handler has returned a value of true from CanExecute.

    After calling Execute once, in response to a successful CanExecute, ArcMap will not instantiate any further DDE command handler coclasses.

Only one DDE command handler can execute each message from the client.


Creating a DDE command handler

A basic implementation of a DDE command handler coclass should be straightforward—it only needs to implement the IDDECommandHandler interface and be registered to the ESRI MX DDE Command Handlers component category. Complexity may be added by the requests your handler can parse and the functions it can perform upon request.


Implementing IDDECommandHandler

IDDECommandHandler is straightforward to implement. The CanExecute and Execute methods will be called by ArcMap when incoming DDE messages are received. Each method will be passed the string parameter Command, which originates from the DDE client.

As implied by the methods on this interface, only the Execute DDE message is supported by ArcMapthe Poke, Request, and Send DDE messages are not supported.

In this example, the incoming Command string is divided into two parts: an identifier and an action. The identifier and action are separated by a colon (:). The identifier substring determines which DDE command handler coclass the incoming Command string is intended to be used by. The action substring determines what action should be taken by the handler object upon receipt of the Command message.

A single message string identifies both a specific DDE command handler and the action the handler should execute. This message is passed to the CanExecute and Execute methods of IDDECommandHandler.

This example uses a member variable, m_strSep, to store the separator string.

[Visual Basic 6]
Private Const c_sSep As String = ":"

The CanExecute procedure first parses the Command string to retrieve the identifier substring, which is the part before the separator colon. If the identifier received matches the expected identifier for this class (in this case ARCMAPDEMO), then the CanExecute method returns true.

[Visual Basic 6]
Private Function IDDECommandHandler_CanExecute(ByVal Command As String) _
 As Boolean
  IDDECommandHandler_CanExecute = False
  
  Command = StrConv(Command, vbUnicode)
  Command = TrimNulls(Command)
  Command = Trim(Command)
  Command = UCase(Command)
  
  Dim strKey As String
  strKey = "ARCMAPDEMO"
  
  Dim iPos As Long
  iPos = InStr(Command, c_sSep)
  
  If iPos > 0 Then
    If Left(Command, iPos - 1) = strKey Then
      IDDECommandHandler_CanExecute = True
    End If
  End If
End Function

The example demonstrates a simple DDE command handler. The handler parses a DDE message and alters the current selection in ArcMap based on the information contained in the message.

Note that the function also trims any white space at the beginning or end of the string. This may help ensure that your string functions operate as expected; for example, if a user enters a DDE command string in a TextBox, it is common for an accidental keystroke to add unexpected extra white space to the beginning or end of the string, which may not be noticed by the user.

You should take care to ensure that this string is as unique as possible, to ensure a DDE message intended for your handler is not accidentally intercepted by another DDE handler. Also, this will ensure your DDE handler will not incorrectly attempt to execute DDE messages intended for other handlers. You might want to use a combination of your company name and an ID number or name, the DDE handler coclass name, or even its GUID.

Ensure your DDE message is not intercepted by another DDE handler class and that your DDE handler does not intercept messages intended for another handler.

Once the CanExecute method has returned true, then the Execute method will automatically be called by ArcMap, passing in the Command string.

The Execute method is where the real work is done. This time the action is parsed (the second part of the string, after the colon), which determines what action is to be carried out.

In the following example code, you can see that the action performed is either counting or clearing the selected features in the focus map.

[Visual Basic 6]
Private Sub IDDECommandHandler_Execute(ByVal Command As String)
  ...
  Dim iPos As Long
  iPos = InStr(Command, m_strSep)
  Dim strAction As String
  strAction = Mid(Command, iPos + 1)
  
  Dim pApp As esriFramework.IApplication
  Set pApp = esriFramework.New AppRef
  Dim pMXD As esriArcMapUI.IMxDocument
  Set pMXD = pApp.Document
  
  Dim pAV As esriCarto.IActiveView
  Select Case strAction
    Case "COUNTSELECTION"
      Dim iCnt As Long
      iCnt = pMXD.FocusMap.SelectionCount
      MsgBox Selected features in focus map: " & iCnt
    Case "CLEARSELECTION"
      pMXD.FocusMap.ClearSelection
      Set pAV = pMXD.FocusMap
      pAV.Refresh
      MsgBox "Selection Cleared"
    Case Else
      MsgBox "Unrecognized DDE Command"
  End Select
End Sub

If the action string is not recognized, then a warning is given.

Note that the code here assumes that the DDEHandler is running inside the ArcMap process and uses the AppRef object. If you adapt this example, and there is a chance that your class may be used outside ArcMap, using AppRef may cause errors. You may wish to refer to 'Developing Objects', for information on a technique to avoid the instantiation of AppRef outside of ArcGIS applications.

See 'Developing Objects' for more information about using the AppRef object.

String length

It is possible that long DDE message strings may be truncated—you may want to include a string terminator character to check that your message has not been truncated.

Check your DDE message to be sure that it is not too long.

Dealing with Unicode and ANSI strings

Depending on the type of DDE client, the Command string may be either a Unicode or ANSI string. For example, Windows API calls may return either ANSI or Unicode strings. ArcView 3.x has the ability to handle both ANSI and Unicode strings, but a DDE message sent from Avenue will be an ANSI string.

If you are creating the command handler in VB, you must be aware that VB natively deals with Unicode strings. Therefore, any incoming ANSI strings must be converted to Unicode before any parsing of the string takes place.

The type of string received by your handler class may differ depending on the type of client that creates the message string. You must take care to ensure the received string can be read correctly.

You can convert a string to Unicode in VB by using VB's StrConv function as shown.

[Visual Basic 6]
Command = StrConv(Command, vbUnicode)

Once this Unicode conversion has taken place, the command string may have null characters at the end, which may cause VB string functions to operate incorrectly. Therefore, you need to remove these null characters from the string before using it.

The following function can be used in VB to trim the extra characters from the end so that subsequent string comparisons will work correctly.

[Visual Basic 6]
Public Function TrimNulls(inputStr As String) As String
  Dim i As Long
  i = InStr(inputStr, vbNullChar)
  
  If i > 0 Then
    TrimNulls = Left$(inputStr, i - 1)
  Else
    TrimNulls = inputStr
  End If
End Function

Embedded null characters can have unexpected effects on string function operation. They may occur at the end of a string as shown in the example code, but can also occur mid-string in some cases. For further information on embedded null characters, see 'Smart Types' in ATL Internals.


Setting up a DDE conversation

Finally, when you have your ArcMap application running, you can call your DDE handler from a DDE client, passing an appropriate command string to your DDE command handler.

The client should use the following DDE settings for a conversation with ArcMap:

Conversation types

There are various types of DDE conversation possible, but ArcMap only supports the Manual type. In addition, remember that ArcMap only supports DDE Execute—this will send the specified command string to the server application.

ArcMap supports a Manual DDE conversation only.

The accompanying VB project, DDEVBClient, demonstrates a simple use of the handler. It uses a TextBox control to define the Command string and a CommandButton to initiate the DDE conversation with ArcMap via the TextBox control.

[Visual Basic 6]
Text1.LinkTopic = "ArcMap|System"
Text1.LinkMode = vbLinkManual
Dim strDDE As String
strDDE = Text1.Text
Text1.LinkExecute strDDE

Back to top

Go to the VB6 example code