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:
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
ArcMap will now pop up a message box that informs you of the number of selected features in the map.
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.
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.
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 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.
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.
A basic implementation of a DDE command handler coclass should be straightforwardit 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.
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.
Private Constc_sSepAs 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.
Private FunctionIDDECommandHandler_CanExecute(ByValCommandAs String) _As BooleanIDDECommandHandler_CanExecute =FalseCommand = StrConv(Command, vbUnicode) Command = TrimNulls(Command) Command = Trim(Command) Command = UCase(Command)DimstrKeyAs StringstrKey = "ARCMAPDEMO"DimiPosAs LongiPos = InStr(Command, c_sSep)IfiPos > 0Then IfLeft(Command, iPos - 1) = strKeyThenIDDECommandHandler_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.
Private SubIDDECommandHandler_Execute(ByValCommandAs String) ...DimiPosAs LongiPos = InStr(Command, m_strSep)DimstrActionAs StringstrAction = Mid(Command, iPos + 1)DimpAppAsesriFramework.IApplicationSetpApp = esriFramework.New AppRefDimpMXDAsesriArcMapUI.IMxDocumentSetpMXD = pApp.DocumentDimpAVAsesriCarto.IActiveViewSelect CasestrActionCase"COUNTSELECTION"DimiCntAs LongiCnt = pMXD.FocusMap.SelectionCount MsgBox Selected features in focus map: " & iCntCase"CLEARSELECTION" pMXD.FocusMap.ClearSelectionSetpAV = pMXD.FocusMap pAV.Refresh MsgBox "Selection Cleared"Case ElseMsgBox "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.
It is possible that long DDE message strings may be truncatedyou 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.
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.
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.
Public FunctionTrimNulls(inputStrAs String)As String DimiAs Longi = InStr(inputStr, vbNullChar)Ifi > 0ThenTrimNulls = Left$(inputStr, i - 1)ElseTrimNulls = inputStrEnd 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.
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:
There are various types of DDE conversation possible, but ArcMap only supports the Manual type. In addition, remember that ArcMap only supports DDE Executethis 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.
Text1.LinkTopic = "ArcMap|System" Text1.LinkMode = vbLinkManualDimstrDDEAs StringstrDDE = Text1.Text Text1.LinkExecute strDDE
Go to the VB6 example code