DDE (Dynamic Data Exchange) is one Microsoft way of communicating between applications that support that (e.g. Word does, but Wordpad/Notepad don't). Messages are strings that express commands. It looks like for Word the commands have to be bracketed, so put braces around to prevent the Tcl parser from seeing them. Tcl (for Windows) of course has dde support - see the dde page in Tcl Help. http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/dde.htm ---- [tclguy] writes during March of 2002 on comp.lang.tcl: "... I wanted to get time to answer this earlier, but you eventually hit on it yourself. DDE requires an event loop to be running to service requests. DDE is based on a serial request / response mechanism, which you can hang up when a process isn't responding. A Tcl process that sees no reason to have an event loop running will also not queue into the fact that DDE requests are waiting. This is why you see the problem in Tcl apps mostly, and not Tk apps (which need the event loop for the UI)." ---- [BR] 2003-10-28 - This leads directly to the biggest problem with DDE (IMO). During connection setup, a straight-forward DDE client will send a broadcast (without a timeout) to all threads that have an event queue. (On Windows all threads that have ever processed events in the past have an event queue, all others don't have one.) The problem: Any thread that has an event queue but is currently not servicing it for any reason will block the broadcast. This will block the client, and the effect can propagate to its clients. I have had ''very'' bad experiences with this in real life. [PT] 11-Mar-2004: This issue has been resolved for Tcl 8.5 by using SendMessageTimeout to perform this step. This results in badly behaved applications not appearing in the list of available services but also not hanging the DDE client app. ---- More commentary: DDE's a funny creature. Deprecated since 199? [[document]], everyone knows it's preferable on all sorts of grounds to use a [COM] interface--but Tcl still, as of 2004, builds in the DDE package, but does not do the same for any COM facility. ---- From a posting by Bill Schongar, at http://groups.google.com/groups?oi=djq&ic=1&selm=an_490725194 , you can control '''Microsoft Word''' from the dde command. First: be sure Word is running, then try a command like the following to insert text into the current document: package require dde look at CWind:but it does the work." dde execute -async Winword System {[Insert "Text from Tcl."]} To quit Word, or close a document, use the following commands as a guide: dde execute Winword System {[FileExit 2]} dde execute Winword System {[FileClose 2]} In these examples, 2 = close without saving, 1 = save first, 0 = prompt. For documentation on accessing Word, see the "wrdbasic.hlp" file, which you can choose to install when you install Word. Adrian Davis adds that dde execute Winword System {[AppMaximize 1]} maximizes Word. - [RS] also found these to work: % dde execute Winword System {[EndOfDocument]} % dde execute Winword System {[StartOfDocument]} % dde execute Winword System {[EditFind .Find="hello" .PatternMatch=1]} See also [Word Reaper]. ---- Peter G. Baum presented this example for '''[MATLAB]''': dde execute Matlab Engine "s = ones(5);" ---- [CL]'s favorite DDE baby steps are with IE, because it's even more ubiquitous than Word or Excel. Moreover, the simplest possible IE example also illustrates a significant difficulty in working with DDE. To open a web page in '''Internet Explorer''': dde execute iexplore WWW_OpenURL "http://www.tcltk.com/" See http://support.microsoft.com/support/kb/articles/Q160/9/57.ASP?LN=EN-US&SD=gn&FR=0 for various dde commands supported by internet explorer. It would be nice to transcribe some of them into Tcl for this page. dde execute iexplore WWW_ShowFile C:/Program%20Files/.... will open a local file (note that spaces and other odd characters must be converted to valid '%' codes). dde request iexplore WWW_GetWindowInfo 1 will return information about the current window which is open, although if multiple windows are open, I'm not sure how to control this more accurately. dde request iexplore WWW_ListWindows 0 seems to do something... Vince. (any help with above? In particular, it would be useful to be able to grab the URL of the foremost window.-) All of the above experiments should "work" reliably, in that, from the user perspective, IE indeed acts as described. However, back in the Tcl process, [[dde]] typically throws a "remote server cannot handle this command" exception. That's because, in [KBK]'s analysis, DDE gives no "way to distinguish 'result expected, but the server failed to provide it' from 'no result is expected'." The only way ''not'' to receive a DMLERR_NOTPROCESSED is to invoke "dde exec -async ..." [Using dde to get browser info] - [A little Web kiosk] ------- Finally, '''Eudora''' seems to have some support: {Eudora DeleteMessageById} {Eudora PutMessageById} {Eudora GetMessageById} {Eudora GetNextMessageId} {Eudora ExpandNickname} {Eudora MAPI} {Eudora WWW_OpenURL} But I'm not sure how to make use of them... ------- Controlling '''Windows explorer''': To open a folder on the desktop: dde execute Folders AppProperties{[ViewFolder "C:\Temp","C:\Temp",5)]} you can also use 'ExploreFolder' instead. To open the Find Folder dialog: dde execute Folders AppProperties {[FindFolder("","C:\Temp")]} will open the Find Folder dialog. ---- Re '''MS Excel''', George Petasis writes in comp.lang.tcl: Finally, I manage to find an example at msdn. My only problem now is how to select the chart type of the created chart. Acoording to the example: dde execute Excel $Topic \ "\[Select(\"R1C1:R${rows}C1\;R1C5:R${rows}C$cols\")\]\[New(2,2)\]" The chart is created with New(2,2), after the correct cells are selected. This chart is the vertical bars type and is placed in a new book. How can I select the scatter graph and place it in a new sheet of the first book (referenced by $Topic)? Where can I find documentation about this New dde function? ---- Helpful procedures (Vince) [[Someone please annotate these]]: proc windowsDdeExecute {service topic name args} { set cmd "\[$name\(" set subcmds [list] foreach a $args { lappend subcmds "\"$a\"" } append cmd [join $subcmds ","] "\)\]" puts stderr "dde execute $service $topic $cmd" dde execute $service $topic $cmd } proc windowsProgmanExecute {name args} { eval [list windowsDdeExecute PROGMAN PROGMAN $name] $args } ---- A recent posting in news:comp.lang.tcl says: Message-ID: <3B0BC718.742A151D@raytheon.com> From: Bruce Hartweg Newsgroups: comp.lang.tcl Subject: Re: Q: dde and Netscape References: <9eeg4j$d8h9@kcweb01.netnews.att.com> <3B0B3012.78949DEB@home.com> <3B0B8C45.5B5E9E9D@cs.man.ac.uk> <3B0BABD9.5B83294B@cs.nott.ac.uk> Date: Wed, 23 May 2001 09:20:08 -0500 Organization: Raytheon Company Neil Madden wrote: > "Donal K. Fellows" wrote: > > > > Bruce Hartweg wrote: > > > change wrote: > > >> However, if I use > > >> dde execute -asynce netscape WWW_OpenURL http://www.yahoo.comm > > >> the netscape does nothing (no error message either). Could someone help me? > > [...] > > > It's been a while, so I am not sure (can't find my script where I used this) > > > but I think you need to use dde request instead of dde execute. > > > > > > For reference of what DDE Topics Netscape supports see > > > http://developer.netscape.com/docs/manuals/communicator/DDE/contents.htm > > > > Hmm. The following URL (hopefully not mangled by this newsreader) looks > > to be the key: > > http://developer.netscape.com/docs/manuals/communicator/DDE/ddevb.htm#www_openurl > > > > So, I *guess* that it should be something like this: > > > > dde request netscape WWW_OpenURL http://www.yahoo.com 0 0 > > Doesn't work for me on Win98, I get: > wrong # args: should be "dde request serviceName topicName value" > > Removing the "0 0" from the end and it works as expected. > Yes, (it's coming back) the value has to be a single string, if you want to pass other args to the service separate by commas & keep as single arg (add commas to skip items) so dde request netscape WWW_OpenURL "${url},,0" will open the URL in a new window, and dde request netscape WWW_OpenURL "${url},,0xFFFFFFFF" will open it in the last active window Bruce ---- How, though, does one use -ddename? How, in particular, can one Tk instance spawn and control another? [Jeffrey Hobbs] posted an example in August 2001: exec wish83.exe myfile.tcl -ddename bar -mynameis foo & dde eval bar $command Notice that the spawned interpreter can itself dde eval foo $command2 in this context. As Jeff writes, "Also, to find existing names, you just do: dde services TclEval {} and that is like 'winfo interps'." ---- Which applications are running? dde services "" "" can tell you. ---- From news:comp.lang.tcl, [Oleg Oleinick] writes: To take control over DDE, application can start DDE server in the slave interpreter. Following example prevents application to start twice: package require Tk package require dde # dde dispatcher proc ddecommand {command} { switch -- $command { "raise" { raise . focus -force . } } } # Check for running instance if { [llength [dde services TclEval MYAPP]] } { # Application already run, raise it dde eval MYAPP catch raise exit 0 } # Create slave intepreter 'ddeagent' if { [lsearch -exact [info loaded] {{} Dde}] >= 0 } { # Statically linked dde, we can use safe interpreter interp create -safe ddeagent interp invokehidden ddeagent load {} dde } else { interp create ddeagent interp eval ddeagent package require dde } # Create new command raise in slave interpreter interp alias ddeagent raise {} ddecommand raise # Create dde server in slave interpreter interp eval ddeagent dde servername MYAPP focus -force . Oleg ---- Netscape provides a list [http://developer.netscape.com/docs/manuals/communicator/DDE/ddevb.htm] of DDE things known to Navigator. ---- [Iain B. Findleton] has coded a DDE 2.0 he's currently using, although not yet released. Also, Iain has found that it's safest to connect only to active services; Win* seems to misbehave uncontrollably when one tries to connect to an absent service. ---- It is often useful to be able and use a context menu option to either launch a Tcl application on a file, or if the Tcl application is running have it handle the launched file. An example of registering the handler is shown in [regContextHandler] - TFW ---- Applications inaccessible through [DDE] often can be reached by way of [COM] and [SendKeys]. For even more power and flexibility, Stefano Porici advises, "If you're interested in sending key sequences and exchanging data through the [clipboard] (a powerful combination anyway), you can give a http://www.interq.or.jp/japan/s-imai/tcltk/cwind.html this is a loadable DLL with a very simple Tcl interface. A more powerful interaction model (allowing mouse movements) is provided by [WinTclSend] ..." ---- See [send] for a Windows emulation with DDE. ---- [[We need a comparison with [tcom], [OpTcl], ...]] ---- '''How to Restrict The List of Exposed Commands''' By default the dde package, when used as a server, exposed all of the commands and variables available in the interpreter. This is not always what is desired. One solution might be to load the package into a safe slave interpreter and use [[interp alias]] to expose the required commands. Unfortunately the package doesn't support safe interpreters. A second solution is to build a modified dde package - see [dde restriction] for more. [PT] '''Associating a Windows file type with a Tcl application''' With an implementation of TIP #120 [http://purl.org/tcl/tip/120] it is possible to have Windows Explorer launch a Tcl application for a file type. See [ddeexec] ---- How get data in and out of Excel # dde request Excel System SysItems # dde request Excel System Topics # # Create a new book # dde execute Excel System {[NEW(1)]} # dde poke Excel {[Book1]Sheet1} "R1C1" 4 # dde request Excel {[Book1]Sheet1} "R1C1" # # Select Row 1 Column1 to Row 20 Column 3 # dde execute Excel System {[select("r1c1:r20c3")]} # # Sort Row 1 Column 1 # dde execute Excel System {[sort(1,"R1C1",1)]} # # Quit # dde execute Excel System {[quit()]} # # Get a list of books and sheets # dde services Excel {} # To load an existing .xls file in the current directory set cwd [pwd] regsub "/" $cwd "\\" cwd exec {C:/Program Files/Microsoft Office/Office/Excel.exe} & catch {dde execute Excel {[Book1]Sheet1} "\[open(\"$pwd\\$fileName.xls\")\]"} package require dde # bookAndSheet like {[Book1]Sheet1} Starting at Row=1 and Column=1 and assuming data is a list of rows and each row is a list of values. proc excel_export {data bookAndSheet} { set row 1 set col 1 foreach d $data { foreach v $d { dde poke Excel $bookAndSheet "R${row}C${col}" $v incr col } incr row set col 1 } } # bookAndSheet like {[Book1]Sheet1} Imports a square of values from r1 (row 1) to r2 (row 2) and from c1 (column 1) to c2 (column 2). Returns a list of rows. Each row is a list of values. proc excel_import {r1 c1 r2 c2 bookAndSheet} { set ret {} set row $r1 set col $c1 for {} {$row <= $r2} {incr row} { for {set col $c1} {$col <= $c2} {incr col} { lappend rowData [string range [dde request Excel $bookAndSheet "R${row}C${col}"] 0 end-2] # puts "$row $col $rowData" } lappend ret $rowData set rowData {} } return $ret } Earl Johnson (earl-johnson@juno.com) (Loading an existing xls file added by [CF]) ---- A little tip from [Ro] if you want to control '''Mozilla''' via DDE: Mozilla registers the DDE application "Mozilla" and currently supports only ''(as of Sept 7th, 2002)'' the "WWW_OpenURL" topic. Use the source @ http://lxr.mozilla.org/seamonkey/source/xpfe/bootstrap/nsNativeAppSupportWin.cpp ---- package require dde puts "Currently displayed is '[lindex [dde request iexplore WWW_GetWindowInfo 0] 0]'." Back to [Tcl core extension syntax]. [Category Package] distributed in core [Tcl] ---- '''Some examples of using dde with Microsoft Access''' dde request MSAccess {c:\samples\NWIND.MDB} tablelist gives a list of available tables * Reportlist - a list of reports * Querylist - a list of queries * Formlist - a list of forms * Macrolist - a list of macros -To access data in a table dde request MSAccess {c:\samples\NWIND.MDB;TABLE tblBooks} All gives all entries in table with field names dde request MSAccess {c:\samples\NWIND.MDB;TABLE tblBooks} Data gives entries without field names dde request MSAccess {c:\samples\NWIND.MDB;TABLE tblBooks} FieldNames gives just the field names -To access data from a query dde request MSAccess {c:\samples\NWIND.MDB;QUERY qryCatagories} All gives all rows of a query ---- It is interesting to see all that you can do with DDE in other applications, but may I suggest a list of ideas of what kind of services ''a Tcl application can make available'' to other (Tcl or not) applications through dde: [Serving dde] ---- While DDE has a notion of "Advise" [[document]], Tcl's standard DDE package does ''not'' provide a correlative for Advise. ---- [ALX]: [Howto open PDF with Adobe Acrobat or Reader using DDE] ---- !!!!!! %|[Category Windows]|% !!!!!!