You are on page 1of 19


Neva Object Technology, Inc.

This bean has a single property named service that lists service names for the server to support. and an instance of that class is registered with a DdeServer using the addDdeServerConnectionEventListener method. DdeServerTransactionEventListener is the listener interface for receiving DDE server transaction events. DdeServerTransactionEvent is a custom event that is generated by DdeServer. you should set the service property and register both connection and transaction event listeners. The object that implements DdeServerTransactionEventListener interface gets a DdeServerTransactionEvent when the event occurs. This object encapsulates the DDE server side connection event data. 2 . Class DdeServerTransactionEventAdaptor provides an empty implementation of all methods defined in DdeServerTransactionEventListener. Dde Server DdeServer is an invisible bean that handles basic DDE server functionality. To stop the server. The following provides an overview of the JavaDde classes and interfaces. The start method starts the server. The object that implements DdeServerConnectionEventListener interface gets a DdeServerConnectionEvent when the event occurs. and an instance of that class is registered with a DdeServer using the addDdeServerTransactionEventListener method.JavaDde JavaDde bean enables Java applets and applications to interact with Windows applications and other applets/applications using Dynamic Data Exchange Protocol. Inc. DdeServerConnectionEvent is a custom event that is generated by DdeServer. Before you call this method. This object encapsulates the DDE server side transaction data. _____________________________________________________ © 1997 – 2004 Neva Object Technology. The class that is interested in processing DDE server connection events implements this interface. DdeServerConnectionEventListener is the listener interface for receiving DdeServerConnectionEvent. The class that is interested in processing DDE server transaction events implements this interface. The postAdvise method causes the server to trigger onAdvReq event on DdeServerTransactionEventListener interface for each client with an active advise loop on the specified topic and item. Class DdeServerConnectionEventAdaptor provides an empty implementation of all methods defined in DdeServerConnectionEventListener. JavaDde bean is written in 100% Java and uses Coroutine to interact with Windows. you call the stop method.

The object that implements DdeClientTransactionEventListener interface gets a DdeClientTransactionEvent when the event occurs. DdeClient transaction methods (request. pokeAsync) return immediately after the transaction has begun. execute. Class DdeClient offers public methods to connect to a given DDE server. The class that is interested in processing DDE client transaction events implements this interface and an instance of that class is registered with a DdeClient using the addDdeClientTransactionEventListener method. DdeClient transaction methods (requestAsync. the transaction fails. a String that specifies the name of the topic or a null (when a null is specified. In a synchronous transaction. and poke) do not return until the server processes the transaction. a DDE client can retrieve a list of all connection handlers for the connection by using the enumConnections method. During an asynchronous transaction. When a DDE client wants to establish conversations with all server applications that support the specified service name and topic name pair. 3 . terminate connection. answering a transaction identifier for further reference. Class DdeServerTransactionEventAdaptor provides an empty implementation of all methods defined in DdeServerTransactionEventListener. perform various DDE transactions. When the connectList method is used to establish original connections. a conversation on any topic supported by the server is established). DdeClientTransactionEvent is a custom event that is generated by DdeClient. the last parameter specifies the maximum length of time. Inc. As a result. a conversation is established with any available server). that the client will wait for a response from the server. executeAsync. During a synchronous transaction. To establish a DDE conversation with a server. it uses the connectList method. or the time out value expires. DdeClientTransactionEventListener is the listener interface for receiving DDE client side transaction events. the DDE sends a notification back to the client. When the DDE server finishes processing an asynchronous transaction. After a successful execution of the connectList method. the client must use the setCurrentConnection method to specify the destination for the current transaction. This object encapsulates the DDE client side transaction data.JavaDde Dde Client DdeClient is an invisible bean that handles basic DDE client functionality. JavaDde client uses the connect method that takes three parameters: a String that specifies the name of the service to connect to or a null (when a null is specified. A client can send either synchronous or asynchronous transactions. the onAsyncComplete method in DdeClientTransactionEventListener is invoked providing the client with the _____________________________________________________ © 1997 – 2004 Neva Object Technology. in milliseconds. the client specifies a time -out value that indicates the maximum amount of time it will wait for the server to process the transaction.

neva. import java.DdeRemoteClientFactory) Naming.DdeRemoteClient cl = factory.lookup("rmi://"+host+"/DdeRemoteClientFactory"). Naming.neva. if(s. JavaDde. import java. Finally. On Windows machine that runs your DDE server you need to register an instance of DdeRemoteClientFactoryImpl with RMI Registry.JavaDde opportunity to verify the results of the asynchronous transaction.LocateRegistry. String host=”tignes. When the connectList method is used to establish original connections.jar supplies the DdeRemoteClientFactoryHost class that does the following: package com. com.rmi.neva. } catch(Throwable ex) { ex. 4 . JavaDDE client uses the disconnect”). LocateRegistry. Then you call the getDdeRemoteClient method that answers an instance of DdeRemoteClient.neva.*. to close a single connection.rebind("//:"+port+"/DdeRemoteClientFactory".registry.rmi. the disconnect method closes all connections. JavaDde client must use the disconnectSingle method. a client application can choose to abandon an asynchronous transaction by calling the abandonTransaction method. To obtain an instance of DdeRemoteClient in your client application you need to acquire a reference to DdeRemoteClientFactory via RMI naming service.DdeRemoteClientImpl class .getDdeRemoteClient().length>0) port=Integer. Inc. public class DdeRemoteClientFactoryHost { public static void main(String [] s) { try { int port=1099.server.printStackTrace(). } } } _____________________________________________________ © 1997 – 2004 Neva Object Technology. The DdeRemoteClient implementer .nevaobject. import java.DdeRemoteClientFactory factory = (com.simultaneously serves as an RMI server and a DDE client. To close a connection.parseInt(s[0]). DdeRemoteClientFactoryImpl impl=new DdeRemoteClientFactoryImpl(). com.impl).rmi.*.createRegistry( port). Dde Remote Client DdeRemoteClient offers a way of extending Windows DDE protocol to non-Windows clients via Java RMI.

and type the following in a cell: =JavaDdeServer|MyTopic!MyItem The cell should obtain the value of g_cnt from the server application. private String MyTopic="MyTopic". public static void main(String [] param) { new JavaDdeServer(). } public void runServer() { try { xltablefmt=com.DdeServer ddeServer. public class JavaDdeServer implements Runnable { private int g_cnt=0. Inc. and increment rapidly as it receives updates. Then. private Thread th.ddeRegisterClipboardFormat("XlTable").neva. The thread updates a counter variable continuously.DdeServer(). Finally. ddeServer=new com. private int CF_TEXT=com. it registers connection and transaction event listeners. private com. and starts the server.DdeRemoteClientFactoryHost To receive DDE client transaction events. To test your DDE server: • • • Start JavaDdeServer Java application Start Excel. import com.neva.JavaDde So you can simply run from command prompt java com. Examples Basic DDE server written in Java to serve data to Excel The following example shows a very basic DDE server application that serves data to DDE clients such as Microsoft Excel. ddeServer.addDdeServerConnectionEventListener( _____________________________________________________ © 1997 – 2004 Neva Object Technology.neva.neva. the application creates a thread to simulate changing data.setService("JavaDdeServer"). private String MyItem="MyItem".neva. your remote application must implement DdeRemoteClientTransactionEventListener interface by extending the DdeRemoteClientTransactionEventAdaptor class and register it with a DdeRemoteClient using the addDdeClientTransactionEventListener method. The application first creates a DdeServer and initializes it with the service name. private int xltablefmt.*.DdeUtil.neva. //Register connection event listener ddeServer.DdeServer.CF_TEXT. and advises any DDE clients listening as it changes.runServer(). 5 .

JavaDde new com.DdeServerTransactionRejectedException().DdeServerTransactionRejectedException { //Data is ready. return. e. } }). 6 . } catch(Exception exc) { System.neva.setRequestedData(xldata).getBytes()). exc. Inc.DdeServerConnectionEvent e) throws com.DdeServerConnectionRejectedException { // Make sure the client is asking for the right topic if(e.getItem().equals(MyTopic)) { System. } }).DdeServerTransactionRejectedException().neva.printStackTrace().getFormat() == xltablefmt) { byte [] xldata=buildXLTable(""+g_cnt).out. // Create a thread to simulate changing data th=new Thread(this).DdeServerTransactionRejectedException { // Make sure the client is asking for the right topic and item if(!e.addDdeServerTransactionEventListener( new com. } else if(e.neva.neva.getFormat() == xltablefmt) { byte [] xldata=buildXLTable(""+g_cnt). } //Return requested data.equals(MyItem)) { throw new com.setRequestedData(xldata).out.neva.equals(MyItem)) { return. } throw new com.DdeServerTransactionEvent e) throws com.equals(MyTopic) && e. return.neva. System.getBytes()).. return.println("Waiting for transaction.setRequestedData(new String(""+g_cnt). return.println("Unable to start DDE server").length()]. } throw new com.getTopic(). } } byte [] buildXLTable(String s) { // This method answers data in xltable format byte [] arr=new byte[12+1+s.neva. //Register transaction event listener ddeServer.DdeServerConnectionRejectedException().DdeServerTransactionRejectedException().neva.start().setRequestedData(new String(""+g_cnt).neva.").DdeServerTransactionEvent e) throws com. Check whether the format is correct if(e. } throw new com.start().getFormat() == CF_TEXT) { e.out.println("Dde server started..DdeServerTransactionEvent e) throws com. th.equals(MyTopic) || !e.println("New Connection established"). } public void onRequest(com."). } public void onAdvReq(com. } throw new com.neva.out. // Start DDE server ddeServer.getTopic().DdeServerTransactionRejectedException().neva.DdeServerTransactionEventAdaptor() { public void onAdvStart(com. _____________________________________________________ © 1997 – 2004 Neva Object Technology. System.getItem().neva.DdeServerTransactionRejectedException { // Make sure the client is asking for the right topic and item if(e.neva. return. Check whether the requested //format is the one that we support if(e.exit(0).getTopic(). System. } else if(e. e.getFormat() == CF_TEXT) { e.neva.DdeServerConnectionEventAdaptor() { public void onConnect(com.neva.

length()). return arr. static String our_topic="WWW_URLEcho". Thread.neva.DdeServerConnectionRejectedException().getBytes(). Coroutine. public class EchoURL { static String our_service="EchoURL". } public void run() { //This thread updates g_cnt counter variable continuously. String topic="WWW_RegisterURLEcho". //Register transaction event listener svr. svr. Inc.setWORDAtOffset(arr. Coroutine.neva.DdeServerConnectionEvent e) throws com.length().13.JavaDde Coroutine.addDdeServerConnectionEventListener(n ew com.neva.10).toUpperCase().neva. System.length(). //and advises any DDE clients listening as it changes while(true) { try { g_cnt++.s. Coroutine.setWORDAtOffset(arr.2).neva.0.sleep(1000). String service="NETSCAPE".6). postAdvise() will trigger onAdvReq() event ddeServer.neva. } }).*.neva. Coroutine.16.DdeServerConnectionRejectedException { //Only WWW_URLEcho is allowed if(e.arraycopy(s. 7 .setWORDAtOffset(arr.2. service=service.getTopic().length>0) service=argv[0].DdeServerTransactionEventAdaptor() { _____________________________________________________ © 1997 – 2004 Neva Object Technology.postAdvise(MyTopic. //Notify server.neva.setWORDAtOffset(arr. throw new com. Coroutine.DdeServer svr=new com.1.setWORDAtOffset(arr.setWORDAtOffset(arr. //Register connection event listener svr.addDdeServerTransactionEventListener( new com. if(argv.DdeServerConnectionEventAdaptor() { public void onConnect(com.8).12).0). try { com.DdeServer(). } catch(Exception e) { } } } } Java server that receives notifications from Netscape browser client Below is Java application that runs DDE server to receive notifications when Netscape loads new URL To test your DDE server: • • Start Netscape Navigator Start EchoURL application import com.4).MyItem).1+s.equals("WWW_URLEcho")) return.1. public static void main(String [] argv) { int ret.4. Coroutine.s.setBYTEAtOffset(arr.arr.setService(our_service).

JavaDde public void onPoke(com. int i. and establishes a hot link to monitor changes.equals("NETSCAPE")) //Tell Netscape the name of the Echo server cli.neva.equals("IEXPLORE")) //Tell IE the name of the Echo server cli.CF_TEXT. //Get worksheet name byte [] data=cl.1. retu rn.neva. places some values into cells. import com. } }). } } } Java client that monitors changes in Excel sheet The following example implements DDE client that establishes a DDE link with Microsoft Excel.*.j.util.execute("[New(1)]\0".disconnect().neva. //Create new worksheet cl. com.Coroutine/com.DdeServerTransactionEvent e) throws com.neva.*. //Start echo server svr.timeout).neva.timeout).println(item).10000).neva.topic).start(). System.DdeClient().neva.neva. } catch(Exception e) { e. To test your DDE client: • • • Start Microsoft Excel Start DdeExcelLinkClient application Modify Excel worksheet and watch changes printed by Java application import java. if(service.DdeServerTransactionRejectedException { String item=e. //Connect to Browser cli.format. } try { int timeout=5000.connect("Excel".DdeClient().request(our_service.DdeClient cli=new com."System").neva.out. 8 .poke( byte[1].1000).printStackTrace(). _____________________________________________________ © 1997 – 2004 Neva Object Technology.DdeClient cl=new com.neva.connect(service. int format=com. public class DdeExcelLinkClient { public static void main(String args[]) { try { Class.println("Unable to locate com.neva.forName("com. //Establish spreadsheet link cl.Coroutine"). Inc.exit(0). } catch(Exception e) { System. //Create Dde client com.getItem().Jddeml").1. //we are done here cli. System.request("Selection\0".DdeUtil. if(service.

//Establish link with new worksheet cl=new com.DdeClientTransactionEvent e) { System.DdeClientTransactionEventAdaptor() { public void onAdviseData(com.max.addDdeClientTransactionEventListener( new com.startAdvise(hotitem. public class DdeExcelLinkClientMulti { int [] conv.DdeUtil.out.neva. 9 .util.printStackTrace().i++) cl.DdeClientTransactionEvent e) { String data=new String(e. } } } The following example implements DDE client that monitors all currently open Exc el workbooks iimport java. if(ndx>0) { worksheet=worksheet.timeout). } public void onDisconnect(com.neva.neva.neva.15) + "\n"+new String(e.timeout).getConvHandle().println("Server conv=0x"+Integer. String(""+(i*j)).println("Advise link established! "+ "Go ahead and modify Excel worksheet").DdeServer.exit(0).j++) for(i=1.j<=10.getDdeData()).neva. } void doit() { try { int timeout=5000.neva. com.ddeRegisterClipboardFormat("CSV"). System.DdeClient cl.neva.format.neva.println("onAdviseData: item="+e. //Establish hot link on range of cells int csvformat=com.neva.CF_TEXT.getItem()+" conv=0x"+ Integer. cl. }.*. public static void main(String args[]) { new DdeExcelLinkClientMulti().toString(e.addDdeClientTransactionEventListener(new com. System. System.neva.JavaDde String worksheet=new String(data).neva.getConvHandle().DdeClient().out.getItem()+" data=\n"+data).worksheet). } catch(Exception e) { e.substring(0.doit().println("onAdviseData: topic="+e. int m.ndx).neva.getTopic()+" item="+e.neva. cl. cl.i<=10. cl=new com.ddeRegisterClipboardFormat("CSV").poke("R"+j+"C"+i.csvformat.exit(0).DdeClientTransactionEvent e) { System. } public void onDisconnect(com. synchronized(conv) { _____________________________________________________ © 1997 – 2004 Neva Object Technology.connect("Excel".getDdeData())).DdeClientTransactionEvent e) { System.disconnect().out.*.out.16)+" has gone !").DdeClientTransactionEventAdaptor() { public void onAdviseData(com.DdeClient(). //Put some values into worksheet for(j=1.indexOf((int)'!'). } cl. }).toString(e. int ndx=worksheet. System.DdeServer.getBytes().out. Inc. import com. int csvformat=com. int format=com.println("Server has gone !"). String hotitem="R1C1:R10C10" .

} } } Java application that retrieves the contents of a Word document The following example implements DDE client that establishes a DDE link with Microsoft Word.neva. finds currently open document. Inc.length.startAdvise(hotitem. } catch(com. } } } catch(Exception e) { e. 10 . requests the item "\Doc" from the document to retrieve the contents of the entire document.length. //Establish a hot link on range of cells for(m=0. } } }).timeout). System.println("No connections left. } //check whether at least one connection still exists for(m=0.DdeException exx) { //sta rtAdvise failed since it wasn't a worksheet: don't count this connection anymore conv[m]=0.null).out.println("total connections: "+max).length. System. if(conv==null) max=0. String hotitem="R1C1:R10C10".out.neva. else max=conv. Will terminate").m++) { if(conv[m]!=0) return. } //No connections left System. lists of all topics available.*.exit(0). To test your DDE client: • • • Start Microsoft Word Load a document Start Dde2Word application import com.exit(0).connectList("Excel".enumConnections().m<max. for(m=0.m<conv.setCurrentConnection(m). //Connect to all topics exposed by running Excel instances cl.csvformat.getConvHandle()) conv[m]=0.m++) { if(conv[m]==e. System. try { cl.printStackTrace().m<conv.JavaDde int m.m++) { cl. _____________________________________________________ © 1997 – 2004 Neva Object Technology. conv=cl.

if(pos2==-1) { out[cnt++]=in.pos2).out. break.connect("WINWORD". String [] Topics. int j. } String [] out=new String[cnt]. if(doc==null) { System. } //disconnect from MsWord cli.connect("WINWORD".j++) { System. //Disconnect from the document cli. //request the list of topics repl=cli."System").request("\\Doc".disconnect().out.out. int cnt=1.format.DdeClient cli=new com.printStackTrace(). pos=0.pos). 11 . for(j=0. String doc=null.pos+1). } } static String [] tabparser(String in) { //parses the tab-delimited list of information int pos=0. Inc. int format=com.timeout).endsWith(".substring(pos).substring(pos..indexOf('\t'. //retrieve the contents of the entire document repl=cli..CF_TEXT.println(Topics[j]).neva.DdeClient().neva. System.neva. if(pos==-1) break.JavaDde public class Dde2Word { public static void main(String args[]) { try { int timeout=5000. } else out[cnt++]=in.exit(0). while(true) { int pos2=in. System.out.doc).exit(0).timeout).neva.disconnect(). cnt++.endsWith(". com.DdeUtil.println(text). cli. } //connect to the document cli=new com.DdeClient(). byte [] repl.indexOf('\t'. } catch(Exception e) { e.length.doc") || Topics[j]. String text=new String(repl).request("Topics". System. } _____________________________________________________ © 1997 – 2004 Neva Object Technology.println("Document is not available.println("List of topics available:").").j<Topics.DOC")) doc=Topics[j]. //connect to MsWord cli. Topics=tabparser(new String(repl)). cnt=0.format. pos=pos2+1. System. while(true) { pos=in. if(Topics[j].

} } JSP page that generates an Excel spreadsheet via DDE to Excel The following example demonstrates how to convert an HTML table to an Excel spreadsheet. see the appropriate server documentation.Copyright (c) 1996-2003 Neva Object Technology. . For information on deploying and running this JSP onto your application server. Inc. All rights reserved. Inc. --> <head> <title>Using JavaDde from within JSP</title> </head> <body bgcolor="white"> <div align="center"> <form method='GET' action='ddexl.*" %> <html> <!-.neva.*.java.jsp'> <table border="0" bgcolor="#F1F1F1"> <tr> <td ><input type="text" name="R1C1" size="10"></td> <td ><input type="text" name="R1C2" size="10"></td> <td ><input type="text" name="R1C3" size="10"></td> <td ><input type="text" name="R1C4" size="10"></td> </tr> <tr> <td ><input type="text" name="R2C1" size="10"></td> <td ><input type="text" name="R2C2" size="10"></td> <td ><input type="text" name="R2C3" size="10"></td> <td ><input type="text" name="R2C4" size="10"></td> </tr> <tr> <td ><input type="text" name="R3C1" size="10"></td> <td ><input type="text" name="R3C2" size="10"></td> <td ><input type="text" name="R3C3" size="10"></td> <td ><input type="text" name="R3C4" size="10"></td> </tr> <tr> <td ><input type="text" name="R4C1" size="10"></td> <td ><input type="text" name="R4C2" size="10"></td> <td ><input type="text" name="R4C3" size="10"></td> <td ><input type="text" name="R4C4" size="10"></td> </tr> <tr> <td ><input type="text" name="R5C1" size="10"></td> <td ><input type="text" name="R5C2" size="10"></td> <td ><input type="text" name="R5C3" size="10"></td> <td ><input type="text" name="R5C4" size="10"></td> </tr> </table> <form method="GET" action="java:void(0)"> <p><input type="radio" value="V1" checked name="download">Download <input type="radio" name="download" value="V2">Display</p> <input type='submit' value='Make Excel Workbook' name='GO'> </form> </form> </div> <% _____________________________________________________ © 1997 – 2004 Neva Object Technology.JavaDde return <%@ page language="java" import="com. 12 .

setHeader("Content-Disposition".substring(0. _____________________________________________________ © 1997 – 2004 Neva Object Technology."System").setHeader("Pragma".indexOf((int)'!'). } //Establish link with new worksheet DdeClient cl=new DdeClient(). if(value!=null && value.setDateHeader ("Expires".length()>0) { //Launch Excel String excelpath="E:\\Program Files\\Microsoft Office \\Office \\Excel.execute("[QUIT]\0".delete()."no-cache"). int timeout=5000. response.i<=5. new File(path).exe".poke(cell. } file. //Put values into worksheet for(j=1.j. FileInputStream fin=null.DdeUtil. int c=0.length()>0) cl. String value=request.CF_TEXT.ALL]\0". filename=\"result.execute("[SAVE. response.timeout).xls \"").connect("Excel". sys.timeout).flush(). //close worksheet sys. } Thread. if(download) response.delete().setContentLength((int)file. boolean download=request.request("Selection \0". while((c=fin.setHeader("Cache-Control".worksheet).close(). DdeClient sys=new DdeClient(). String r1c1=request.length()). != -1) out. //Connect to Excel sys.execute("[New(1)]\0". cl.getParameter("download")!=null &&"). //Create new worksheet sys."no-cache"). if(r1c1!=null && r1c1.neva. 13 . try { //quit Excel sys. int format=com. } finally { if(fin!=null) fin.setContentType("application/vnd.disconnect().sleep(5000).AS(\""+path+"\")]\0".JavaDde try { String path=getFilePath()+"."attachment.i++) { String cell="R"+i+"C"+j. } catch(Exception exx) {} out. } //save worksheet cl. response.getParameter(cell).j++) for(i=1.false)) { return. File file=new File(path). response.ndx). String worksheet=new String(data). try { fin=new FileInputStream(file).disconnect(). //Get worksheet name byte [] data=sys. if(ndx>0) { worksheet=worksheet.connect("Excel".getBytes(). out.timeout).getParameter("download").format.timeout). int ndx=worksheet. cl.write(c).timeout). Inc.getParameter("R1C1"). if(0!=CreateProcess(excelpath.timeout). int i.format.equals("V1").j<=4. 0).value.xls".clearBuffer().execute("[CLOSE.

0. } %> <%! public int CreateProcess(String commandLine.gridwidth=GridBagConstraints.JavaDde } } catch(Exception ex) { out. and to save document on hard disk. gbc. int saveId=0. run spell checker.awt. gbl.setConstraints(panel.} public Dimension getMinimumSize() { return new Dimension(400.weighty=1.util.BOTH. add(text). gbc.boolean showWindow) { //some code is removed for clarity } String getFilePath() { //some code is removed for clarity } %> <hr> </body> </html> Java application that uses asynchronous DDE transactions to control Word In the following example. com. class ControlPanel extends java.SOUTH. public TextArea text. import java.weightx=1.*. GridBagConstraints gbc=new GridBagConstraints(). gbc. panel=new ControlPanel(). import java.anchor=GridBagConstraints. gbc.*.gbc).anchor=GridBagConstraints.gridwidth=GridBagConstraints. 14 . Java application launches Microsoft Word and uses several asynchronous DDE transactions to create and format new Word document. import com.setLayout(null).Panel { public Dimension getPreferredSize() { return new Dimension(400.REMAINDER.neva.40). gbc=new GridBagConstraints().awt.neva.DdeClient cli=null. text=new TextArea(). panel. setLayout(gbl).*. gbl.*.gbc). int spellingId=0.setConstraints(text. } public Java2Word() { super("Build Word Document").} } public class Java2Word extends Frame { public Button build.REMAINDER.NORTH. public ControlPanel panel. Inc.0.40). gbc. public static void ma in(String [] param) { new Java2Word().fill=GridBagConstraints. gbc. _____________________________________________________ © 1997 – 2004 Neva Object Technology. gbc. GridBagLayout gbl=new GridBagLayout().awt.println("<B>Error: "+ex.getMessage()+"</B>"). import java.event.

15 .neva.add(build). cli.executeAsync("[FileNew]"). setSize(400.executeAsync("[EditSelectAll]"). show().getAsyncTransSuccess()) saveDoc(). enableEvents(java. cli. } catch(Exception ex) { ex. setLocation(10.awt.10).neva.exe".DdeException.lang.200). if(0!=CreateProcess(wordpath.getText().InterruptedException { saveId=cli. cli.'\r')+"\"]"). } void saveDoc() throws com.replace('\n'.getAsyncTransSuccess()) quitMSWord().printStackTrace().getAsyncTransId()) { //Spelling has finished if(event. build.executeAsync("[Bold 1][Insert \"Java2Word\"][EndOfLine]").neva. } boolean buildWordDocument() { try { String wordpath="E:\\Program Files\\Microsoft Office \\Office \\winword. cli.true)) { return false.addDdeClientTransactionEventListener(new com.disconnect()."System"). } } catch(Exception ex) { ex.executeAsync("[DocWindowPosTop 100][DocWindowPosLeft 100]"). Inc.40. }). java. } String getText() { return text.neva. cli.10. spellingId=cli. } }).connect("WINWORD".printStackTrace(). } } public void onDisconnect(com.executeAsync("[Bold 0][InsertPara][Insert \""+getText(). cli.event. build=new Button("Build").executeAsync("[DocWindowWidth 500][DocWindowHeight 300] ").setBounds(20.DdeClientTransactionEvent e) { try { cli.JavaDde add(panel).WindowEvent.executeAsync("[AppRestore]"). cli. build. } if(saveId==event.printStackTrace().sleep(5000).DdeException.InterruptedException { _____________________________________________________ © 1997 – 2004 Neva Object Technology. cli.20). java.lang. } catch(Exception ex) { ex.executeAsync("[Font \"Arial\"][FontSize 12]"). } return true.DdeClient(). } Thread. } void quitMSWord() throws com. cli. cli=new com. panel. } }.neva.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { buildWordDocument().WINDOW_CLOSING).executeAsync("[ToolsSpelling]").//connect to MsWord cli.executeAsync("[FileSave]").getAsyncTransId()) { //Doc was saved if(event.DdeClientTransactionEventAdaptor() { public vo id onAsyncComplete(DdeClientTransactionEvent event){ try { if(spellingId==event.

coro. } } _____________________________________________________ © 1997 – 2004 Neva Object Technology.addArg(true). if(!showWindow) { coro. if(rc != 0) { coro.addArg(new int[2]).freeArg(). coro.68. byte [] si=new byte[68]. id[0]=ids[0]. Coroutine coro=new Coroutine("KERNEL32".setWORDAtOffset(si. if(e.48).event. coro.addArg(0).intArrayFromParameterAt(9. coro.setWORDAtOffset(si. coro.addArg(0).addArg(si).WindowEvent. coro. int rc=coro. } } public int CreateProcess(String commandLine.7.boolean showWindow) { int [] id=new int[2].setDWORDAtOffset(si.executeAsync("[AppClose]"). coro.exit(0).2).44). return 0."CreateProcessA").addArg(commandLine). Inc.addArg(0). id[1]=ids[1].1. coro. } coro.invoke().awt. 16 .WINDOW_CLOSING) { System.getID()==java. } int [] ids=coro.addArg(0).JavaDde cli. coro. coro. return rc. } public void processEvent(AWTEvent e) { super. coro.addArg(0).processEvent(e).addArg(0).0).

Inc. The single parameter specifies the host that runs Excel Modify Excel worksheet and watch changes printed by Java application _____________________________________________________ © 1997 – 2004 Neva Object Technology. To test your client application: • • • • Start Microsoft Excel Start com.neva. 17 .JavaDde Non-Windows Java client that monitors changes in remote Excel sheet The following example implements DDE client that establishes a DDE link with Microsoft Excel while running on a non-Windows OS.DdeRemoteClientFactoryHost on the machine that runs Excel Start DdeRemoteExcelLinkClient application on remote machine.

println("Advise link established! Go ahead and modify Excel worksheet").wait().timeout).format.printStackTrace().*.rmi.*. cl.timeout).new String(""+(i*j)).DdeRemoteClientTransactionEventAdaptor { public EventHandler() throws RemoteException {} public void onAdviseData(com. import java.rmi. System.neva.neva.getCause().util.neva. cl.neva. we can use the following hack for that purpose. //Get DdeREmoteClient com.worksheet).getCause()!=null) ge t. System.*.DdeRemoteClientFactory)Naming. import com.disconnect().CF_TEXT. System. String hotitem="R1C1:R10C10". this application will terminate immediately hereafter.out. } catch(Throwable e) { e. synchronized(keepAlive) { try { keepAlive. //Establish hot link on range of cells cl.DdeRemoteClientFactory factory = (com. Inc. //Establish link with new worksheet EventHandler eh=new EventHandler().DdeClientTransactionEvent e) throws RemoteException { String data=new String(e.rmi.request("Selection \0". //Locate DdeRemoteClientFactory com.i<=10.i++) cl.neva.format. _____________________________________________________ © 1997 – 2004 Neva Object Technology. System. int ndx=worksheet.neva. else re.getItem()+" data=\n"+data). //We somehow need the thread to stay alive and wait for events.server.timeout).connect("Excel". } cl.timeout). 18 .exit(0).substring(0.getCause(). //Establish spreadsheet link cl.RemoteException re) { if(re.indexOf((int)'!'). if(ndx>0) { worksheet=worksheet. //Create new worksheet cl. int format=com. //Since we do not have a GUI. //Unfortunately. //Get worksheet name byte [] data=cl.DdeUtil. import java.DdeRemoteClient cl = factory. int i.printStackTrace().j<=10.println("onAdviseData: item="+e.getCause().neva.getDdeData()). } } } class EventHandler extends com. String worksheet=new String(data).exit(0).execute("[New(1)]\0". public class DdeRemoteExcelLinkClient { public static void main(String args[]) { try { String host="localhost".getDdeRemoteClient().ndx). } catch(InterruptedException e) { // do nothing it will not happen } } } catch(java.addDdeRemoteClientTransactionEventListener(eh).j.length>0) host=args[0]. //Put some values into worksheet for(j=1.printStackTrace().connect("Excel"."System").out. int timeout=5000. if(args.poke("R"+j+"C"+i.format. Object keepAlive = new Object().getBytes().JavaDde import java.lookup("rmi://"+host+"/DdeRemoteClientFactory").startAdvise(hotitem.getCause()!=null && re.*.j++) for(i=1.

out. } } _____________________________________________________ © 1997 – 2004 Neva Object Technology.exit(0). Inc.DdeClientTransactionEvent e) throws RemoteException { System.neva. System. 19 .println("Server has gone !").JavaDde } public void onDisconnect(com.